在prolog中编写上下文无关语法

时间:2015-11-30 19:26:32

标签: list prolog context-free-grammar dcg

假设我有以下语境免费语法。

S -> A
A -> mAn
A -> o

这怎么看prolog?这是我尝试过但它不起作用。第二行似乎是问题。

S(Z) :- A(Z).
A(Z) :- append([m],X,Z2), A(X), append(Z2,[n],Z).
A([o]).

2 个答案:

答案 0 :(得分:4)

由于语法不是递归的,我们可以使用DCG

 File.Delete(filePath.Substring(filePath.Length - 4) + ".bak");
 File.Move(filePath, filePath.Substring(0, filePath.Length - 4) + ".bak");

然后我们可以解析或生成所有接受的序列。例如,生成:

s --> a.
a --> [m], a, [n].
a --> [o].

检查Prolog代码:

?- length(L, _), phrase(s, L).
L = [o] 
L = [m, o, n] 
L = [m, m, o, n, n] 
...
由于差异列表

不需要附加/ 3 使用append / 3

编辑

?- listing(s).
s(A, B) :-
    a(A, B).

?- listing(a).
a([m|A], C) :-
    a(A, B),
    B=[n|C].
a([o|A], A).

SWI-Prolog追加/ 2(简单地基于追加/ 3正确链接),给予 更可读的替代方案

s(Z) :- a(Z).
a(Z) :- append([m|X],[n],Z), a(X).
a([o]).

无论如何,我们必须在构建/拆分列表之后递归调用

答案 1 :(得分:3)

在这个答案中,我们使用常用的谓词append/3

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] 
...

注意:通常,使用append/3代替是一个糟糕的选择,可能会降低运行时性能和代码可读性。只要有可能,请改用