我在Ivan Bratko的书上学习Prolog DCG语法*和**解析树:“人工智能编程”
我发现以下示例存在一些困难,它提供了一个DCG语法,该语法从属于定义语言的字符串创建解析树。
定义的语言是机器人手臂的移动列表,只能是两种类型:向上和向下所以 [向上,向上,向下,up,up] 属于我的DCG语法定义的语言。
该程序还提供含义/ 2 谓词,解释与某个字符串相关联的解析树,表示机器人手臂交叉的距离(虽然它与向上移动值+1相关联,而值-1向下移动)
例如,对于列表 [向上,向上,向下,向上,向上] , mean / 2 谓词计算+3距离
这是我的例子的代码(运作良好):
move(move(Step)) --> step(Step).
move(move(Step, Move)) --> step(Step), move(Move).
step(step(up)) --> [up].
step(step(down)) --> [down].
/* Take the parse tree of a string that belong to the language defined by the DCC grammar and
calculate the total distance whereas that an up move give a +1 distance and a down move
give -1 distance
*/
meaning(move(Step, Move), Dist):-
/* Calculate the distance given by the current step node
(which can be +1 or -1) */
meaning(Step, D1),
/* Calculate the distance given by the current moove node
(which must be calculated recursively on a subtree having
a moove node as root */
meaning(Move, D2),
/* The final distance series of moves is the distance of the
current step + the distance diven from the moves in the
moove subtree */
Dist is (D1 + D2).
meaning(step(Step), Dist):- meaning(Step, Dist).
meaning(move(Step), Dist):- meaning(Step, Dist).
% step(up) means that the distance is +1
meaning(step(up), 1).
% step(down) means that the distance is -1
meaning(step(down), -1).
所以我有含义/ 2 谓词,它采用解析树并计算移动的总距离。
所以我有2个 BASE CASE ,它可以显示与单个移动相关的距离值(到一个步骤),对于向上步骤可以是+1,对于向下步骤可以是-1:< / p>
meaning(step(up), 1).
meaning(step(down), -1).
含义/ 2 采用一个解析树,根据DCG语法的定义,以root身份有一个移动节点:这个根将有一个左子节点一个步骤节点(因此它是单个移动,因此它具有与之关联的特定距离+1或-1)和一个移动节点的右子节点(所以它反映了另一个子树)
因此总距离是当前步长为+1或-1的距离(当前移动 root的左子)+右子树中的距离之和。
我认为这是正确的,这对我来说非常清楚
我不明白的是代码中的这两个谓词:
meaning(step(Step), Dist):- meaning(Step, Dist).
meaning(move(Step), Dist):- meaning(Step, Dist).
我不能坚持我的推理: - (
答案 0 :(得分:2)
我们使用这些规则,
4 ?- phrase(move(X), [up,up,down,up,up]).
X = move(step(up), move(step(up), move(step(down), move(step(up),
move(step(up)))))) ;
false.
5 ?- meaning($X,N).
N = 3 ;
false.
产生的术语是高度嵌套的:
move(step(up), % move/2: step/1 ,
move(step(up), % move/2: step/1 ,
move(step(down), % move/2: step/1 ,
move(step(up), % move/2: step/1 ,
move(step(up)))))) % move/1: step/1 .
您询问的代码,从复合词中删除functors,找到它的“肉”,即up
或down
原子arguments :
(2) meaning(step(Step), Dist):- meaning(Step, Dist).
“找到一元复合词step(X)
的''含义',与查找X
”的''含义'相同。
(3) meaning(move(Step), Dist):- meaning(Step, Dist).
“找到一元复合词move(X)
的''含义',与查找X
”的''含义'相同。
(4)基本情况:对于1
或-1
原子,'{含义''为up
或down
。< / p>
meaning(step(up), 1). % clashes with rule (2)
meaning(step(down), -1). % clashes with rule (2)
(1)主要案例使用仿函数move
处理二元化合物术语:
meaning(move(Step, Move), Dist):-
meaning(Step, D1),
meaning(Move, D2),
Dist is (D1 + D2).
move/2
是(非空)列表的自定义版本'.'/2
,实际上是:
1 ?- write_canonical([1,2,3]).
'.'(1,'.'(2,'.'(3,[])))
true.
2 ?- write_canonical([step(up),step(down),step(up)]).
'.'(step(up),'.'(step(down),'.'(step(up),[])))
true.
meaning/2
是fold。