从此开始
e([number(0)] , t1 , Uc0 , Uc0, Bc0 , Bc0) --> [].
e([number(1)] , t2 , Uc0 , Uc0, Bc0 , Bc0) --> [].
e([number(2)] , t3 , Uc0 , Uc0, Bc0 , Bc0) --> [].
e([op(neg),[Arg]] , u1(E) , [_|Uc0], Uc1, Bc0 , Bc1) -->
[_],
e(Arg , E , Uc0, Uc1, Bc0, Bc1).
e([op(ln),[Arg]] , u2(E) , [_|Uc0], Uc1, Bc0 , Bc1) -->
[_],
e(Arg , E , Uc0, Uc1, Bc0, Bc1).
e([op(add),[Left,Right]], b1(E0,E1) , Uc0 , Uc2, [_|Bc0], Bc2) -->
[_,_],
e(Left, E0, Uc0, Uc1, Bc0, Bc1),
e(Right, E1, Uc1, Uc2, Bc1, Bc2).
e([op(sub),[Left,Right]], b2(E0,E1) , Uc0 , Uc2, [_|Bc0], Bc2) -->
[_,_],
e(Left, E0, Uc0, Uc1, Bc0, Bc1),
e(Right, E1, Uc1, Uc2, Bc1, Bc2).
e(U,B,EL,Es) :-
length(UL, U),
length(BL, B),
phrase(e(EL,Es,UL,[],BL,[]), _).
e(N,EL,Es) :-
length([_|Ls], N),
phrase(e(EL,Es,_,[],_,[]),Ls).
e_count(E, Count) :-
length([_|Ls], E),
findall(., phrase(e(_,_,_,[],_,[]), Ls), Sols),
length(Sols, Count).
然后阅读
对于一个变量,使用一个包含仅包含该变量的单个元素的列表。如果要传递多个变量,请使用包含 f(...) 形式的单个项的列表,捕获所有要传递的变量。这也很值得提出自己的问题。
演变成这样
e( f([number(0)], t1, Uc0, Uc0, Bc0, Bc0) ) --> [].
e( f([number(1)], t2, Uc0, Uc0, Bc0, Bc0) ) --> [].
e( f([number(2)], t3, Uc0, Uc0, Bc0, Bc0) ) --> [].
e( f([op(neg), [Arg]], u1(E), [_|Uc0], Uc1, Bc0, Bc1) ) -->
[_],
e( f(Arg, E, Uc0, Uc1, Bc0, Bc1) ).
e( f([op(ln) , [Arg]], u2(E), [_|Uc0], Uc1, Bc0, Bc1) ) -->
[_],
e( f(Arg, E, Uc0, Uc1, Bc0, Bc1) ).
e( f([op(add), [Left,Right]], b1(E0,E1) ,Uc0, Uc2, [_|Bc0], Bc2) ) -->
[_,_],
e(f(Left, E0, Uc0, Uc1, Bc0, Bc1) ),
e(f(Right, E1, Uc1, Uc2, Bc1, Bc2) ).
e( f([op(sub), [Left,Right]], b2(E0,E1) ,Uc0, Uc2, [_|Bc0], Bc2) ) -->
[_,_],
e(f(Left, E0, Uc0, Uc1, Bc0, Bc1) ),
e(f(Right, E1, Uc1, Uc2, Bc1, Bc2) ).
e(U,B,EL,Es) :-
length(UL, U),
length(BL, B),
phrase(e(f(EL,Es,UL,[],BL,[])), _).
e_N(N,EL,Es) :-
length([_|Ls], N),
phrase(e(f(EL,Es,_,[],_,[])),Ls).
e_count(E, Count) :-
length([_|Ls], E),
findall(., phrase(e(f(_,_,_,[],_,[])), Ls), Sols),
length(Sols, Count).
哪个有效,但要注意use a list that contains a single term of the form f(...)
,这里f(...)
不在列表中。
我是不是哪里出错了?
补充
参考
- Markus Triska在美国思考
- Markus Triska 的Prolog DCG 入门
- 立即学习 Prolog 的额外参数!
隐式状态传递的变量名称约定
通常在使用隐式状态传递时,变量被命名
S0
→ S1
→…→S
但是对于我的一元二叉树示例,我将它们命名为
S0
→ S1
→…→Sn
以Sn
代替结尾S
。
例如
标准
e(S0,S) :-
这里
e(S0,S2) :-
原因是这个例子有一个相当罕见的属性,即每个 DCG 谓词的长度都在增加,
例如
e([number(0)] , t1 , Uc0 , Uc0, Bc0 , Bc0) -->
e([op(neg),[Arg]] , u1(E) , [_|Uc0], Uc1, Bc0 , Bc1) -->
e([op(add),[Left,Right]], b1(E0,E1) , Uc0 , Uc2, [_|Bc0], Bc2) -->
所以结尾xn
给了我对准确性的另一次检查。
参考:ISO/IEC DTR 13211–3:2006 定句语法规则
6.1.3 终端序列的变量名约定
此 TR 使用名为 S0、S1、...、S 的变量来表示在处理语法规则或将语法规则扩展为子句时用作参数的终端序列。在这种表示法中,变量 S0、S1、...、S 可以看作是一系列状态,其中 S0 代表初始状态,变量 S 代表最终状态。因此,如果变量 Si 表示给定状态下的终端序列,则变量 Si+1 将表示用语法规则解析 Si 后剩余的终端序列。