相关疑难解决方法(0)

不同/ 2 - 是否存在纯粹的,确定的定义?

different(Xs, Ys) :-
   member(X, Xs),
   non_member(X, Ys).
different(Xs, Ys) :-
   member(Y, Ys),
   non_member(Y, Xs).
Run Code Online (Sandbox Code Playgroud)

虽然这个定义使用member/2non_member/2几乎是1从声明的观点完美的,它产生于特定查询的冗余解决方案,并选择留点周围.

什么是改进的定义(以纯粹的方式可能使用if_/3(=)/3),使得完全相同的解决方案集被描述different/2但至少对于地面查询是确定的(因此不会留下任何无用的选择点)并且省略(如有可能)任何多余的答案?


1 实际上,different([a|nonlist],[]), different([],[b|nonlist])成功了.它同样可能失败.所以两者都失败的解决方案很好(甚至可能更精细).

prolog prolog-dif logical-purity

33
推荐指数
7
解决办法
791
查看次数

使Prolog目标的"确定性成功"明确

一些Prolog目标确定性成功的问题一次又一次地出现 - 至少 - 以下问题:

使用了不同的方法(例如,引发某些资源错误,或仔细查看Prolog toplevel给出的确切答案),但它们对我来说都有点不合适.

我正在寻找一种通用的,可移植的,符合ISO的方式来查明某些Prolog目标(成功)的执行是否会留下一些选择点.有些元谓词,也许?

你能否向我提示正确的方向?先感谢您!

prolog

29
推荐指数
1
解决办法
877
查看次数

AUBUC的Prolog联盟

我最近开始学习Prolog,我无法解决如何组合三个列表的问题.

我能够组合2个列表:

%element
element(X,[X|_]).
element(X,[_|Y]):-
               element(X,Y).

%union

union([],M,M).
union([X|Y],L,S) :- element(X,L),union(Y,L,S).
union([X|Y],L,[X|S]) :- (not(element(X,L))),union(Y,L,S).
Run Code Online (Sandbox Code Playgroud)

有人可以帮我吗?

list prolog

20
推荐指数
2
解决办法
2605
查看次数

memberchk/2的声明性用法

memberchk/2是一个通常定义的谓词,它是这样定义的member/2:

memberchk(X, Xs) :-
   once(member(X, Xs)).
Run Code Online (Sandbox Code Playgroud)

因此它只能成功地获得第一个答案member/2.它的完整程序意义不适合纯粹的关系.作为其非关系行为的一个例子考虑

?- memberchk(b, [X,b]), X = a.
false.

?- X = a, memberchk(b, [X,b]).
X = a.
Run Code Online (Sandbox Code Playgroud)

另一方面,在许多情况下,memberchk/2将使用充分实例化的参数调用,其中可以将其视为纯关系的有效近似.

背后的一个纯粹的关系是memberd/2(使用if_/3):

memberd(E, [X|Xs]) :-
   if_(E = X, true, memberd(E, Xs) ).
Run Code Online (Sandbox Code Playgroud)

memberchk/2对于充分实例化的案例,是否还有其他可以近似的纯关系?

换句话说:是否是memberd/2一个完整的,声明性的替代品,memberchk/2或者是否仍然存在memberchk/2无法替代的合法案例memberd/2

prolog logical-purity

17
推荐指数
1
解决办法
689
查看次数

PROLOG:如果顺序无关紧要,确定列表中的元素是否相等

我试图找出一种方法来检查两个列表是否相等,无论它们的元素顺序如何.

我的第一次尝试是:

areq([],[]).
areq([],[_|_]).
areq([H1|T1], L):- member(H1, L), areq(T1, L).
Run Code Online (Sandbox Code Playgroud)

但是,这只检查左侧列表中的所有元素是否都存在于右侧列表中; 意思areq([1,2,3],[1,2,3,4]) => true.在这一点上,我需要找到一种能够以双向意义测试事物的方法.我的第二次尝试如下:

areq([],[]).
areq([],[_|_]).
areq([H1|T1], L):- member(H1, L), areq(T1, L), append([H1], T1, U), areq(U, L).
Run Code Online (Sandbox Code Playgroud)

在哪里我会尝试重建左边的那个以及最后的交换列表; 但这次失败了.

我对递归的感觉非常差,根本不知道如何改进它,尤其是Prolog.任何提示或建议都将在此时受到赞赏.

prolog

13
推荐指数
4
解决办法
3721
查看次数

删除Prolog中列表中的前导零

我有一个列表,在它的开头有一个未知数量的零,例如[0,0,0,1,2,0,3].我需要将这个列表去掉前导零,以便它看起来像[1,2,0,3].

这就是我所拥有的:

lead([Head | _], _) :- Head =\= 0.
lead([0 | Tail], _) :- 
  lead(Tail, Tail).
Run Code Online (Sandbox Code Playgroud)

其输出只是True.读取跟踪显示它正在运行,直到它有一个没有前导零的列表,但随后答案不会传播回堆栈.我对Prolog很新,所以我无法弄清楚如何做到这一点.

list prolog prolog-dif

13
推荐指数
4
解决办法
535
查看次数

谓词选择列表中的元素两次而不是更多

我试图写一个谓词twice(El,L)将返回true.El是名单正是两次.这是我有的:

twice(El,L) :- select(El,L,L1), member(El,L1), \+ twice(El,L1).
Run Code Online (Sandbox Code Playgroud)

它的效果很好twice(2,[1,2,2,3,4]) 但是twice(X,[1,1,2,2,3,3])它为每个数字加倍X = 1 ; X = 1 ; X = 2...我怎么能避免这种情况而不使用任何累加器呢?

prolog

7
推荐指数
1
解决办法
858
查看次数

使用prolog再添加两次

我有一个列表[a, b, a, a, a, c, c] ,我需要再添加两个元素.

最终结果应如下所示:

[a, a, a, b, b, b, a, a, a, a, a, c, c, c, c]
Run Code Online (Sandbox Code Playgroud)

如果我在列表中有一个与下一个项目相同的项目,那么它会继续运行,直到有一个新项目,当它找到新项目时,它会添加前一项目的两次,然后继续.

这是我的代码到目前为止,但我无法弄清楚如何添加两个...

dbl([], []).
dbl([X], [X,X]).
dbl([H|T], [H,H|T], [H,H|R]) :- dbl(T, R).
Run Code Online (Sandbox Code Playgroud)

list prolog prolog-dif

5
推荐指数
1
解决办法
271
查看次数

Prolog仅删除独特元素

我想返回一个列表,删除所有独特的元素,例如

remUniqueVals([1,1,2,2,3,4,4,5,6,6,6],Q).   
Q = [1,1,2,2,4,4,6,6,6].  
Run Code Online (Sandbox Code Playgroud)

我的问题是,目前我有返回的代码

remUniqueVals([1,1,2,2,3,4,4,5,6,6,6],Q).  
Q = [1, 2, 4, 6, 6].
Run Code Online (Sandbox Code Playgroud)

这样只返回这些非唯一值的第一个实例.这是我的代码:

remUniqueVals([], []).  
remUniqueVals([Q1|RestQ],[Q1|Xs]) :-        
   member(Q1,RestQ),  
   remUniqueVals(RestQ,Xs).  
remUniqueVals([Q1|RestQ],Xs) :-  
   remove(Q1,[Q1|RestQ], NewQ),  
   remUniqueVals(NewQ,Xs).  
Run Code Online (Sandbox Code Playgroud)

我可以看到member(Q1,RestQ)它在第二次检查1,2,4时失败,因为它们现在不再在列表中,因此将它们删除.我想帮助解决这个问题,我的想法是检查member(Q1, PreviousQ),这是决赛中的元素Q.不知道如何实施,虽然任何帮助将不胜感激.

更新:

好的,谢谢你最终的结论:

remUniqueVals(_,[], []).  
remUniqueVals(_,[Q1|RestQ],[Q1|Xs]) :-        
   member(Q1,RestQ), 
   remUniqueVals(Q1,RestQ,Xs).  
remUniqueVals(PrevQ,[Q1|RestQ],[Q1|Xs]) :-        
   Q1 = PrevQ, 
   remUniqueVals(PrevQ,RestQ,Xs).  
remUniqueVals(PrevQ,[_|RestQ],Xs) :-  
   remUniqueVals(PrevQ,RestQ,Xs). 

remUniqueVals(0,[4,1,1,3,2,2,5,5],Q).
Q = [1, 1, 2, 2, 5, 5].

remUniqueVals(0, [A,B,C], [1,1]).
A = 1,
B = 1,
C = 1.
Run Code Online (Sandbox Code Playgroud)

list prolog

5
推荐指数
3
解决办法
2549
查看次数

如何实现not_all_equal/1谓词

如何实现not_all_equal/1谓词,如果给定列表包含至少2个不同的元素,则谓词成功,否则失败?

这是我的尝试(不是很纯粹):

not_all_equal(L) :-
    (   member(H1, L), member(H2, L), H1 \= H2 -> true
    ;   list_to_set(L, S),
        not_all_equal_(S)
    ).

not_all_equal_([H|T]) :-
    (   member(H1, T), dif(H, H1)
    ;   not_all_equal_(T)
    ).
Run Code Online (Sandbox Code Playgroud)

然而,这并不总是具有最佳行为:

?- not_all_equal([A,B,C]), A = a, B = b.
A = a,
B = b ;
A = a,
B = b,
dif(a, C) ;
A = a,
B = b,
dif(b, C) ;
false.
Run Code Online (Sandbox Code Playgroud)

在这个例子中,只有第一个答案应该出来,另外两个答案是多余的.

predicate list prolog prolog-dif logical-purity

5
推荐指数
2
解决办法
148
查看次数

标签 统计

prolog ×10

list ×5

prolog-dif ×4

logical-purity ×3

predicate ×1