我有谓词P1,一个接一个地返回值,如下所示:
-? P1(ARGUMENTS, RETURN).
-? RETURN = 1;
-? RETURN = 2;
-? RETURN = 3;
-? fail.
Run Code Online (Sandbox Code Playgroud)
我还有一个名为P2的谓词:
P2(ARGUMENTS, LIST) :- P1(ARGUMENTS, RETURN),... % SOMEHOW HERE I NEED TO INSERT ALL VALUES OF RETURN TO LIST.
Run Code Online (Sandbox Code Playgroud)
如何查找所有值RETURN并将其分配给LIST?
我有一个问题,试图获得一些代码,返回我的查询的唯一答案.例如,定义
stuff(A,B,C) :- A=C ; B=C.
morestuff([],[],[]).
morestuff([A|AA],[B|BB],[C|CC]) :- stuff(A,B,C), morestuff(AA,BB,CC).
Run Code Online (Sandbox Code Playgroud)
然后跑
morestuff([A,A],[A,B],[a,b]).
Run Code Online (Sandbox Code Playgroud)
给出输出:
A = a
B = b ? ;
A = a
B = b ? ;
yes.
Run Code Online (Sandbox Code Playgroud)
如您所见,这两种解决方案是相同的.有没有办法让PROLOG回归独特的解决方案,即e.给出输出:
A = a
B = b ? ;
yes.
Run Code Online (Sandbox Code Playgroud) 假设您有一个包含以下内容的数据库:
son(a, d).
son(b, d).
son(a, c).
son(b, c).
Run Code Online (Sandbox Code Playgroud)
所以a和b是d和c的儿子.现在你想知道,给定一个更大的数据库,谁是谁的兄弟.解决方案是:
brother(X, Y) :-
son(X, P),
son(Y, P),
X \= Y.
Run Code Online (Sandbox Code Playgroud)
问题是,如果你问"兄弟(X,Y)." 并开始按";" 你会得到多余的结果,如:
我能理解为什么我得到这些结果,但我正在寻找一种方法来解决这个问题.我能做什么?
什么是Prolog运算符^?
查看Prolog内置指令op,列出了内置运算符.
我看
**是取幂
/ \是或
但是^是什么?
当前三个答案中的每一个都是有价值的,我学到了一些东西:
鉴于数据库中的以下事实:
foo(a, 3).
foo(b, 2).
foo(c, 4).
foo(d, 3).
foo(e, 2).
foo(f, 6).
foo(g, 3).
foo(h, 2).
Run Code Online (Sandbox Code Playgroud)
我想收集所有具有最小第二个参数的第一个参数,加上第二个参数的值.第一次尝试:
find_min_1(Min, As) :-
setof(B-A, foo(A, B), [Min-_|_]),
findall(A, foo(A, Min), As).
?- find_min_1(Min, As).
Min = 2,
As = [b, e, h].
Run Code Online (Sandbox Code Playgroud)
而不是setof/3,我可以使用aggregate/3:
find_min_2(Min, As) :-
aggregate(min(B), A^foo(A, B), Min),
findall(A, foo(A, Min), As).
?- find_min_2(Min, As).
Min = 2,
As = [b, e, h].
Run Code Online (Sandbox Code Playgroud)
NB
如果我正在寻找最小数字,这只会给出相同的结果.如果涉及算术表达式,结果可能会有所不同.如果涉及非数字,aggregate(min(...), ...)将抛出错误!
或者,我可以使用完整的键排序列表:
find_min_3(Min, As) :-
setof(B-A, foo(A, …Run Code Online (Sandbox Code Playgroud) 我正在开发一款名为"狼山羊白菜"的益智游戏.编程语言是Prolog.
change(e,w).
change(w,e).
move([X,X,Goat,Cabbage],wolf,[Y,Y,Goat,Cabbage]) :- change(X,Y).
move([X,Wolf,X,Cabbage],goat,[Y,Wolf,Y,Cabbage]) :- change(X,Y).
move([X,Wolf,Goat,X],cabbage,[Y,Wolf,Goat,Y]) :- change(X,Y).
move([X,Wolf,Goat,Cabbage],nothing,[Y,Wolf,Goat,Cabbage]) :- change(X,Y).
oneeq(X,X,WW).
oneeq(X,WWW,X).
safe([Man,Wolf,Goat,Cabbage]) :-
oneeq(Man,Goat,Wolf),
oneeq(Man,Goat,Cabbage).
wgc([e,e,e,e],[]).
wgc(Config,[FirstMove|OtherMoves]) :-
move(Config,FirstMove,NextConfig),
safe(NextConfig),
wgc(NextConfig,OtherMoves).
Run Code Online (Sandbox Code Playgroud)
为了使它工作,我打电话 length(X,7),wgc([w,w,w,w],X).,它显示结果.问题是它显示了很多次第一个结果,然后是第二个结果:
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ; …Run Code Online (Sandbox Code Playgroud) 如何选择bagof,setof和findall?有什么重要的区别吗?哪个最常用,哪个最安全?感谢您的意见/解答.
我检查了SWI-Prolog手册页findall/3,发现它们非常相似.
我有一个快速的问题。在序言中使用 setof 的存在限定符(即 ^)。
使用 SICStus 似乎(尽管许多网站声称),S 确实似乎在下面的代码中被量化(使用沼泽标准,事实之母 / 事实之子,我没有包括在这里):
child(M,F,C) :- setof(X,(mother(S,X)),C).
Run Code Online (Sandbox Code Playgroud)
我使用以下方法检查统一:
child(M,F,C) :- setof(X-S,(mother(S,X)),C).
Run Code Online (Sandbox Code Playgroud)
所以下面的代码,与存在运算符似乎没有什么区别:
child(M,F,C) :- setof(X,S^(mother(S,X)),C).
Run Code Online (Sandbox Code Playgroud)
任何想法这是为什么?那么在什么情况下您需要统一器?
谢谢!
假设我有以下内容:
parent(alice, charlie).
parent(bob, charlie).
parent(bob, diane).
parent(alice, diane).
parent(bob, eve).
parent(alice, eve).
% people are siblings of each other if they share a parent
% and aren't the same person.
sibling(A, B) :-
parent(X, A),
parent(X, B),
B \= A.
Run Code Online (Sandbox Code Playgroud)
现在如果我问黛安的兄弟姐妹,我会得到查理和夏娃——两次,一次通过鲍勃,一次通过爱丽丝。我只想要一次。
我不认为我可以在这里使用削减,因为这会完全防止回溯。我会想,是检查的方式任何存在。
释义
sibling(A, B) :-
?(parent(X, A), parent(X, B)),
B \= A.
Run Code Online (Sandbox Code Playgroud)
我尝试了几次切割,但都没有奏效。
我试图findall/3在(parent(X, A), parent(X, B))和检查,如果结果列表是非空的,但这并不统一A或B.
setof/3按照下面的建议使用是有效的,但我真的想找到一种方法将它合并到 的定义中sibling/2,而不必在问题中使用它。我真的很想能够做到以下几点:
?- sibling(diane, X).
X = charlie ;
X …Run Code Online (Sandbox Code Playgroud) 我的代码运行但问题是它不止一次显示相同的结果.这是我的代码:
disease(hiv,[sore_throat,headache,fever,rash]).
disease(pregnancy,[fatigue,vomiting,light_headedness,increased_waistline]).
disease(flu,[fatigue,fever,tiredness,nasal_discharge]).
diagnose([], []).
diagnose(Name, [H|T]) :-
disease(The_Disease, Symptoms),
member(H, Symptoms),
write(Name), write(' has/is '), writeln(The_Disease),
diagnose(Name, T).
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
Run Code Online (Sandbox Code Playgroud)
在prolog中执行时的结果:
?- diagnose(kevin,[sore_throat,fatigue,tiredness,rash]).
kevin has/is hiv
kevin has/is pregnancy
kevin has/is flu
kevin has/is hiv
kevin has/is flu
kevin has/is flu
kevin has/is hiv
false.
Run Code Online (Sandbox Code Playgroud)
我该如何避免同样的结果?我尝试使用我在这里找到的其他方法:
filter_doubles([], []).
filter_doubles([X|L], Result) :-
(memberchk(X,L) ->
filter_doubles(L, Result)
;
filter_doubles(L, Result0),
Result = [X|Result0]
).
Run Code Online (Sandbox Code Playgroud)
但是我没能将它应用到我的代码中.请帮忙.
我使用以下失败驱动循环来列出所有内容,而无需使用分号。
happiness(fred,5).
happiness(john,3).
happiness(grace,2).
someGoal(X) :-
happiness(X,Y), write(Y), tab(4), fail.
Run Code Online (Sandbox Code Playgroud)
在查询模式下,我得到了预期的结果
?- someGoal(_).
5 3 2
Run Code Online (Sandbox Code Playgroud)
如何将这些数字插入列表中,而不是将它们写到屏幕上?someGoal由于回溯似乎是隐式的,因此我无法在内部进行处理。
我需要一个满足目标的有序对象列表.setof负责排序,但没有对象满足目标时失败.我想返回一个空列表,而不是像findall.
这有效,但有没有一种方法可以完成这一切没有削减?我正在使用SWI-Prolog.
setof(Object, Goal, List), !; List = [].
Run Code Online (Sandbox Code Playgroud) prolog ×13
prolog-setof ×13
aggregates ×1
backtracking ×1
iso-prolog ×1
lambda ×1
prolog-cut ×1
recursion ×1