我想要一个Prolog谓词,它可以替换指定索引处的列表中的元素.
例:
% replace(+List,+Index,+Value,-NewList).
?- L=[a,b,c,d], replace(L,1,z,L2).
L2 = [a,z,c,d]
Run Code Online (Sandbox Code Playgroud)
我不知道该怎么做.谢谢你的帮助!卢瓦克.
我试图通过阅读Ulle Endriss的讲义来了解Prolog编程.当我对练习的解决方案没有达到预期的效果时,我发现很难给出一个很好的解释.我认为这与我对Prolog评估表达式的方式的不稳定理解有关.
第20页的练习2.6调用谓词的递归实现,该谓词的last1行为类似于内置谓词last.我的尝试如下:
Run Code Online (Sandbox Code Playgroud)last1([_ | Rest], Last) :- last1(Rest, Last). last1([Last], Last).
它给出了正确的答案,但对于具有多个元素的列表,我必须键入分号才能终止查询.这last1与内置的不同last.
?- last1([1], Last).
Last = 1.
?- last1([1, 2], Last).
Last = 2 ;
false.
Run Code Online (Sandbox Code Playgroud)
如果我切换我声明规则和事实的顺序,那么我需要在两种情况下键入分号.
我想我知道为什么Prolog认为last1可能还有一个解决方案(因此是分号).我想它遵循评估顺序
last1([1, 2], Last).
==> last1([2], Last).
==> last1([], Last). OR Last = 2.
==> false OR Last = 2.
Run Code Online (Sandbox Code Playgroud)
这似乎表明我应该寻找一种方法来避免匹配Rest带[].无论如何,我没有解释为什么切换声明的顺序应该有任何影响.
问题1: 对行为的正确解释是last1什么?
问题2: 如何实现last1与内置无法区分的谓词last?
有人可以帮助在此规则中找到错误吗?
concat([], List, List).
concat([Head|[]], List, [Head|List]).
concat([Head|Tail], List, Concat) :- concat(Tail, List, C), concat(Head, C, Concat).
Run Code Online (Sandbox Code Playgroud)
尝试连接2个列表失败:
| ?- concat([1,2], [4,7,0], What).
no
Run Code Online (Sandbox Code Playgroud) xMenores(_,[],[]).
xMenores(X,[H|T],[R|Z]) :-
xMenores(X,T,Z),
X > H,
R is H.
Run Code Online (Sandbox Code Playgroud)
xMenores 有三个参数:
该规则的目标xMenores是获得一个列表,其中列表的编号(第二个参数)小于第一个参数的值.例如:
?- xMenores(3,[1,2,3],X).
X = [1,2]. % expected result
Run Code Online (Sandbox Code Playgroud)
问题是xMenores返回false时X > H是假的,我的编程技巧在prolog几乎为空.所以:
?- xMenores(4,[1,2,3],X).
X = [1,2,3]. % Perfect.
?- xMenores(2,[1,2,3],X).
false. % Wrong! "X = [1]" would be perfect.
Run Code Online (Sandbox Code Playgroud)
我认为X > H, R is H.因为我需要的只要X大于H,R取值H.但我不知道像Prolog中的if或者某种控制结构来处理这个问题.
请问,任何解决方案?谢谢.
我已经阅读了很多关于Prolog的失败否定的内容,其中Prolog是为了证明\+Goal持有试图证明Goal失败.
这与CWA(近距离世界假设)高度相关,例如,如果我们查询\+P(a)(在哪里P是arity 1的谓词),并且我们没有线索导致证明P(a)Prolog假定(由于CWA)not P(a)如此\+P(a)成功.
从我所搜索的内容来看,这是一种解决经典逻辑弱点的方法,如果我们对此毫无头绪,P(a)那么我们无法回答是否\+P(a)持有.
上面描述的是在Prolog中引入非单调推理的方法.此外,有趣的部分是Clark证明Negation by Failure与经典否定相容/类似仅适用于地面条款.我明白这个例子:
X=1, \+X==1.:应该在Prolog中返回false(在经典逻辑中).
\+X==1, X=1.:应该在经典逻辑中返回false,但是在检查NF的时候它在Prolog中成功,X不受约束,这与classic-Pure Logic不同.
\+X==1.:在X绑定之前,不应该给经典逻辑中的任何答案,但在Prolog中它返回false(可能打破经典逻辑的弱点),这与纯逻辑不相同/兼容.
我的尝试是模拟经典否定,感谢评论中的@false的建议,目前的实施是:
\\+(Goal) :- when(ground(Goal), \+Goal).
Run Code Online (Sandbox Code Playgroud)
一些测试:
?- \\+(X==1).
when(ground(X), \+X==1).
?- X=1, \\+(X==1).
false.
?- \\+(X==1), X=1.
false.
Run Code Online (Sandbox Code Playgroud)
我的问题:
以上是对经典否定的正确解释吗?(是否有任何明显的极端情况,它错过了?当使用/ 2时我也关注逻辑纯度,可以安全地假设上面是纯粹的吗??).
作为Prolog新手,我尝试定义一个谓词filter_min/2,该谓词采用两个列表来确定第二个列表是否与第一个列表相同,但是删除了所有出现的最小值.
具有预期结果的示例查询:
?- filter_min([3,2,7,8], N).
N = [3,7,8].
?- filter_min([3,2,7,8], [3,7,8]).
true.
Run Code Online (Sandbox Code Playgroud)
我试过但总是得到相同的结果:false.我不知道问题是什么.我需要帮助!
这是我的代码:
filter_min(X,Y) :-
X == [],
write("ERROR: List parameter is empty!"),
!;
min_list(X,Z),
filter(X,Y,Z).
filter([],[],0).
filter([H1|T1],[H2|T2],Z) :-
\+ number(H1),
write("ERROR: List parameter contains a non-number element"),
!;
H1 \= Z -> H2 is H1, filter(T1,T2,Z);
filter(T1,T2,Z).
Run Code Online (Sandbox Code Playgroud) 我在玩prolog-cooutining谓词freeze/2和frozen/2:
?- freeze(X,a=a), frozen(X,Goal).
?- freeze(X,a=a), freeze(Y,b=b), X=Y, frozen(X,Goal).
Run Code Online (Sandbox Code Playgroud)
sicstus-prolog(x86_64 的 4.5.1 版)给出了这些答案:
| ?- 冻结(X,a=a),冻结(X,目标)。 目标 = prolog:freeze(X,user:(a=a)) , 序言:冻结(X,用户:(a = a))?; 不 | ?- 冻结(X,a=a),冻结(Y,b=b),X=Y,冻结(X,目标)。 Y = X, 目标 = (user:(a=a),prolog:freeze(X,user:(b=b))) , 序言:冻结(X,用户:(a = a)), 序言:冻结(X,用户:(b = b))?; 不
现在没想到!Goal = prolog:freeze(X,user:(a=a))
我所期望的是像swi-prolog 8.0.3 版给出的答案:
?- 冻结(X,a=a),冻结(X,目标)。 目标 = 用户:(a=a) , 冻结(X,a = a)。 ?- 冻结(X,a=a),冻结(Y,b=b),X=Y,冻结(X,目标)。 X = Y, 目标 = (用户:(a=a), 用户:(b=b)) , 冻结(Y,a …
余由Prolog的谓词posAt(List1,P,List2),在测试位置是否在元件P的List1和List2是相等的:
posAt([X|Z], 1, [Y|W]) :-
X = Y.
posAt([Z|X], K, [W|Y]) :-
K > 1,
Kr is K - 1,
posAt(X, Kr, Y).
Run Code Online (Sandbox Code Playgroud)
测试时:
?- posAt([1,2,3], X, [a,2,b]).
Run Code Online (Sandbox Code Playgroud)
我期望输出,X = 2但我得到以下错误:
ERROR: >/2: Arguments are not sufficiently instantiated
为什么我收到此错误?
我正在玩permutation几个程序,并偶然发现了这个小实验:
置换方法1:
permute([], []).
permute([X|Rest], L) :-
permute(Rest, L1),
select(X, L, L1).
Run Code Online (Sandbox Code Playgroud)
置换方法2:
permute([], []).
permute(L, [P | P1]) :-
select(P, L, L1),
permute(L1, P1).
Run Code Online (Sandbox Code Playgroud)
置换方法3(使用内置):
permute(L, P) :- permutation(L, P).
Run Code Online (Sandbox Code Playgroud)
我知道使用尾递归是一种好习惯,通常使用内置函数应该是有效的.但是当我运行以下内容时:
time(findall(P, permute([1,2,3,4,5,6,7,8,9], P), L)).
Run Code Online (Sandbox Code Playgroud)
我得到了以下结果,这些结果在几次运行中相对一致:
方法1:
% 772,064 inferences, 1.112 CPU in 2.378 seconds (47% CPU, 694451 Lips)
Run Code Online (Sandbox Code Playgroud)
方法2:
% 3,322,118 inferences, 2.126 CPU in 4.660 seconds (46% CPU, 1562923 Lips)
Run Code Online (Sandbox Code Playgroud)
方法3:
% 2,959,245 inferences, 1.967 CPU in 4.217 seconds (47% CPU, 1504539 Lips)
Run Code Online (Sandbox Code Playgroud)
因此,非尾递归方法非常实时有效.
一个特定的递归类型通常更实时有效,所有其他条件相同(我知道这并不总是一个简单的前提)?这个实验告诉我的是,我可能不想总是努力进行尾递归,但我可能需要首先进行性能分析,然后权衡性能优势与尾递归确实具有的其他好处.
这不是关于Prolog代码的直接问题,而是关于安装,管理和更新Prolog实现的问题......
理想情况下,我想在我的机器上拥有的是:
我想在我启动机器后选择今天使用的Prolog实现.
我能做什么?有什么你在这方面的尝试?我运行Linux.先感谢您!
prolog ×10
list ×7
clpfd ×1
installation ×1
negation ×1
performance ×1
permutation ×1
updates ×1