List 用prolog编写上下文无关语法
假设我有以下上下文无关语法List 用prolog编写上下文无关语法,list,prolog,context-free-grammar,dcg,List,Prolog,Context Free Grammar,Dcg,假设我有以下上下文无关语法 S -> A A -> mAn A -> o 这在序言中会是什么样子?这是我试过的,但不起作用。第二行似乎是问题所在 S(Z) :- A(Z). A(Z) :- append([m],X,Z2), A(X), append(Z2,[n],Z). A([o]). 由于语法不是左递归的,我们可以使用: 然后我们可以解析或生成所有接受的序列。例如,生成: ?- length(L, _), phrase(s, L). L = [o] L = [m, o
S -> A
A -> mAn
A -> o
这在序言中会是什么样子?这是我试过的,但不起作用。第二行似乎是问题所在
S(Z) :- A(Z).
A(Z) :- append([m],X,Z2), A(X), append(Z2,[n],Z).
A([o]).
由于语法不是左递归的,我们可以使用: 然后我们可以解析或生成所有接受的序列。例如,生成:
?- length(L, _), phrase(s, L).
L = [o]
L = [m, o, n]
L = [m, m, o, n, n]
...
要检查Prolog代码,请执行以下操作:
?- listing(s).
s(A, B) :-
a(A, B).
?- listing(a).
a([m|A], C) :-
a(A, B),
B=[n|C].
a([o|A], A).
由于差异列表,无需追加/3
使用append/3进行编辑
s(Z) :- a(Z).
a(Z) :- append([m|X],[n],Z), a(X).
a([o]).
SWI Prolog有append/2(简单地基于append/3正确链接),它提供
更具可读性的替代方案
a(Z) :- append([[m],X,[n]], Z), a(X).
无论如何,我们必须在构建/拆分列表后递归调用a/1。在这个答案中,我们使用常用的谓词 s(Xs):- a(Xs)。 a([o])。 a([m|Xs]):- (Xs0,[n],Xs), a(Xs0)。 示例查询: ?- length(Xs,_), s(Xs). Xs = [o] ; Xs = [m,o,n] ; Xs = [m,m,o,n,n] ; Xs = [m,m,m,o,n,n,n] ... ?-(Xs,uz),s(Xs)。 Xs=[o] ; Xs=[m,o,n] ; Xs=[m,m,o,n,n] ; Xs=[m,m,m,o,n,n,n] ...
注意:使用
append/3
而不是,通常是一个错误的选择,可能会降低运行时性能和代码可读性。只要可能,请改用 酷。如果使用append/3会是什么样子?为什么将a([o])。
放在最后?@false:我试图使代码与原始代码保持最相似,而不是写入a(Z)
,但是a(Z)
。与所有谓词名称类似。。。
s(Xs) :-
a(Xs).
a([o]).
a([m|Xs]) :-
append(Xs0,[n],Xs),
a(Xs0).
?- length(Xs,_), s(Xs).
Xs = [o]
; Xs = [m,o,n]
; Xs = [m,m,o,n,n]
; Xs = [m,m,m,o,n,n,n]
...