所以我对prolog相对较新,我在互联网上遇到了一些可用于表示And / Or节点的代码。
% a is an or node with successors b,c,d.
or(a,[b,c,d]).
% c is an and node with successor d,e,f.
and(c,[d,e,f]).
% d is a terminal (solvable) node.
goal(d).
我很困惑这个谓词如何用于查找可解决的节点。 并指出我指向正确的方向将是奇妙的
答案 0 :(得分:2)
您似乎已经从东英吉利大学计算机科学系主要系列UG考试2013/14中找到问题2(c)(在Google上使用引用的文字搜索找到),询问:
给定由一组Prolog子句指定的AND / OR树
% a is an or node with successors b,c,d. or(a,[b,c,d]). % c is an and node with successor d,e,f. and(c,[d,e,f]). % d is a terminal (solvable) node. goal(d).
编写一个Prolog程序,其主要子句
solve(X)
仅在X
可解决的情况下成功。
作为背景:
请求的Prolog程序看起来像这样:
%not necessary - without this solve_and([]) will be false anyway
solve_and([]) :-
false.
solve_and([H]) :-
solve(H).
solve_and([H|T]) :-
solve(H),
solve_and(T).
%not necessary - without this solve_or([]) will be false anyway
solve_or([]) :-
false.
solve_or([H|T]) :-
solve(H);
solve_or(T).
solve(X) :-
goal(X),
!.
solve(X) :-
and(X, A),
solve_and(A),
!.
solve(X) :-
or(X, A),
solve_or(A),
!.
从消费者的角度来看,这很有效 - 一个用X调用解决方案来检查是否正确,但是切割(!
)使它成为可解决的X的不良生成器。从解决规则中删除剪切应该使系统成为双向的。
答案 1 :(得分:2)
此特定问题要求您编写谓词以确定给定节点是否可解。换句话说,如果您要查询solve(z)
,它会成功还是失败,具体取决于z
是否可以解决。
首先要写出规则是什么。 Jim Ashworth已经在答案中做到了这一点,但我会在这里重申一下:
让我们先简单地在Prolog中写一下。
% Rule 1
solve(X) :- goal(X).
% Rule 2
solve(X) :-
and(X, Subgoals),
all_solvable(Subgoals).
% Rule 3
solve(X) :-
or(X, Subgoals),
at_least_one_solvable(Subgoals).
现在我们需要编写谓词all_solvable/1
和at_least_one_solvable/1
:
% Auxiliary predicates used above
all_solvable([]).
all_solvable([Node|Nodes]) :-
solve(Node),
all_solvable(Nodes).
at_least_one_solvable([Node]) :- solve(Node).
at_least_one_solvable([Node, NextNode|Nodes]) :-
( solve(Node)
-> true
; at_least_one_solvable([NextNode|Nodes])
).
你可以看到这几乎与吉姆的答案相同,这完全是正确的方向。我只是从Prolog的角度提供了一些改进。出于这个原因,我认为Jim值得称赞答案。除了我选择的谓词名称之外,差异是:
p1 -> p2 ; p3
构造来处理"成功一次"对于析取案件all_solvable/1
也会成功在上方,p1 -> p2 ; p3
构造的行为与p1, !, p2 ; p3
相同。因此,对于某些情况,正如Jim在他的评论中指出的那样,削减是有帮助的,你只是在这个问题中寻找可解决性,而不是多种可解决方式。您还可以找到一种方法来使用once/1
谓词来实现此目的(您可以将其视为练习)。
all_solvable/1
的替代实现:
all_solvable(Goals) :- maplist(solve, Goals).
此时,maplist(solvable, Goals)
将成功,且仅当solvable
成功Goals
列表的每个元素时才会成功。
与Jim的解决方案一样,这将告诉您具体目标是否可以解决(尽管Jim的答案不会像我的解决方案那样留下选择点):
| ?- solve(a).
true? ;
no
| ?-
上述解决方案的另一个好处是,它可以使用所有正确的解决方案正确回答常规查询:
| ?- solve(X).
X = d ? ;
X = a ? ;
no
| ?-