我一直在Learn Prolog Now!进行自学,现在正在学习确定条款语法。我对其中一个实践课程的任务有些困难。 The task读到:
形式语言a n b 2m c 2m d n 包含以下形式的所有字符串:一个完整的 a 块,然后是一个完整的 b 块,然后是一个完整的块 c ,然后是一个完整的块 d ,这样 a 和 d 块的长度完全相同, c 和 d 块也是完全相同的长度,并且还分别由偶数个
s和d组成。例如,ε, abbccd 和 aaabbbbccccddd 都属于 n b 2m C 2米 d 名词。写一个生成这种语言的DCG。
我能够编写生成 n d n ,b 2m c 2m 的规则,以及甚至 n b 2m 和c 2m d n ...但我似乎无法加入所有这些规则为 n b 2m c 2m d n 。以下是我的规则,可以生成 n d n 和b 2m c 2m 。
s1 --> [].
s1 --> a,s1,d.
a --> [a].
d --> [d].
s2 --> [].
s2 --> c,c,s2,d,d.
c --> [c].
d --> [d].
n b 2m c 2m d n 真的是CFG,是否可以写DCG仅使用课程中教授的内容(没有其他参数或代码等)?如果是这样,有人可以给我一些指导,我可以加入这些,以便我可以解决给定的任务吗?
答案 0 :(得分:5)
@Timothy,你的答案有效,但它会产生重复:
?- length(S,_), s(S,[]).
S = [] ;
S = [a, d] ;
S = [a, d] ; % XXX
S = [b, b, c, c] ;
S = [a, a, d, d] ;
S = [a, a, d, d] ; % XXX
这可以通过删除一个子句来解决,留下DCG:
s --> x.
s --> a,s,d.
x --> [].
x --> b,b,x,c,c.
% a, b, c, d the same
这会产生:
?- length(S,_), s(S,[]).
S = [] ;
S = [a, d] ;
S = [b, b, c, c] ;
S = [a, a, d, d] ;
S = [a, b, b, c, c, d] ;
S = [a, a, a, d, d, d] ;
S = [b, b, b, b, c, c, c, c] ;
S = [a, a, b, b, c, c, d, d] ;
S = [a, a, a, a, d, d, d, d] ;
答案 1 :(得分:3)
我相信我明白了......
s --> x.
s --> a,d.
s --> a,s,d.
x --> [].
x --> b,b,x,c,c.
a --> [a].
b --> [b].
c --> [c].
d --> [d].
?- s([],[]).
Yes
?- s([a,b,c,c,d],[]).
No
?- s([a,a,a,b,b,c,c,d,d,d],[]).
Yes
看着这个解决方案很有趣并且想:“我把我的大脑放在 上?”但我想这是学习新东西的一半乐趣,特别是当它来自命令式编程背景的逻辑编程时。
答案 2 :(得分:0)
如下:
n(L,N) --> n(L,N,0).
n(_,N,N) --> [], !.
n(L,N,K) --> L, {K1 is K + 1}, n(L, N, K1).
abbccd(N,M) -->
{M1 is 2*M},
n("a",N),
n("b",M1),
n("c",M1),
n("d",N).
gen :-
forall((
between(1,4,N),
between(1,4,M),
phrase(abbccd(N,M),S),
string_to_atom(S,A)
),
writeln(A)).
执行
?- gen.
abbccd
abbbbccccd
abbbbbbccccccd
abbbbbbbbccccccccd
aabbccdd
aabbbbccccdd
aabbbbbbccccccdd
aabbbbbbbbccccccccdd
aaabbccddd
aaabbbbccccddd
aaabbbbbbccccccddd
aaabbbbbbbbccccccccddd
aaaabbccdddd
aaaabbbbccccdddd
aaaabbbbbbccccccdddd
aaaabbbbbbbbccccccccdddd
true.