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或者某种控制结构来处理这个问题.
请问,任何解决方案?谢谢.
如果Min是标准术语中最小的成员,则为True.如果List为空,则失败.
?- min_member(3, [1,2,X]).
X = 3.
Run Code Online (Sandbox Code Playgroud)
解释当然是变量在标准的术语顺序中位于所有其他术语之前,并且使用统一.但是,报告的解决方案感觉有些不对劲.
怎么可以说是合理的?我该如何解释这个解决方案?
编辑:
防止min_member/2成功使用此解决方案的一种方法是更改标准库(SWI-Prolog)实现,如下所示:
xmin_member(Min, [H|T]) :-
xmin_member_(T, H, Min).
xmin_member_([], Min0, Min) :-
( var(Min0), nonvar(Min)
-> fail
; Min = Min0
).
xmin_member_([H|T], Min0, Min) :-
( H @>= Min0
-> xmin_member_(T, Min0, Min)
; xmin_member_(T, H, Min)
).
Run Code Online (Sandbox Code Playgroud)
失败而不是抛出实例化错误(@mat在他的回答中建议,如果我理解正确的话)的理由是,这是一个明确的问题:
" [1,2,X]当X是自由变量时,3是最小成员吗?"
对此的答案是(至少对我来说)一个明确的"不",而不是"我无法说出来".
这与以下行为属于同一类sort/2:
?- sort([A,B,C], [3,1,2]).
A = 3,
B = 1,
C = 2.
Run Code Online (Sandbox Code Playgroud)
适用相同的技巧:
?- …Run Code Online (Sandbox Code Playgroud) 我在理解为什么我的prolog代码根据我的规则的顺序做了一些事情时遇到了一些麻烦.
这是我的数据库:
parent(tom, bob).
parent(tom, liz).
parent(mary, bob).
parent(mary, liz).
male(tom).
male(bob).
female(mary).
female(liz).
Run Code Online (Sandbox Code Playgroud)
以下是规则:
%difference(X, Y) ==> Predicate to check if two people X and Y are not the same person.
difference(X, Y) :- \==(X, Y).
father(X, Y) :- male(X), parent(X, Y), difference(X, Y).
mother(X, Y) :- female(X), parent(X, Y), difference(X, Y).
sibling(X, Y) :-
difference(X, Y),
mother(M, X), mother(M, Y),
father(F, X), father(F, Y).
Run Code Online (Sandbox Code Playgroud)
问题是,当我这样做时,
?- sibling(bob, X).
Run Code Online (Sandbox Code Playgroud)
我明白了
X = bob ;
X = liz ;
false. …Run Code Online (Sandbox Code Playgroud) 我正在查看SICStus手册的语法描述,并且有一个"浮动"的定义.但是,没有迹象表明实际上"浮动"的实现是什么.IEEE单精度还是双精度?也许甚至是BigDecimal?
在SWI Prolog(或至少SWISH)中,"浮动"似乎是IEEE双精度,可以通过以下方式确定:
planck_float(P) :-
planck_float_descent(1.0,P).
planck_float_descent(X,P) :-
Xhalf is X / 2.0, Xtest is 1.0 + Xhalf, Xtest =\= 1.0, !,
write(Xhalf),writeln(Xtest),
planck_float_descent(Xhalf,P).
planck_float_descent(P,P) :-
Xhalf is P / 2.0, Xtest is 1.0 + Xhalf, Xtest == 1.0,
writeln(P).
?- planck_float(P).
P = 2.220446049250313e-16
Run Code Online (Sandbox Code Playgroud)
2.22e-16作为最后一个值,添加到1.0仍然产生比1.0IEEE 64位浮点算法更好的声音.
其他Prolog有什么实施方案?
在最近的一个问题(如何在ISO Prolog中定义(和命名)相应的安全术语比较谓词?)@ false要求实现术语排序谓词lt/2,ISO内置的变体(@<)/2.
真值lt(T1,T2)是要T1和任意变量绑定的稳定T2.
在各种答案中,提出了不同的实现(基于隐式/显式术语遍历).在评论中提出了一些警告和提示,反例也是如此.
所以我的问题是:如何测试候选实施?有些蛮力的做法?还是更聪明的东西?
无论如何,请分享您的自动测试机器lt/2!这是为了更大的利益!