在没有算术的情况下识别Prolog中的A ^ n B ^ n语言

Leg*_*gat 3 grammar automata prolog dcg

如何识别没有算术的Prolog中的A ^ n B ^ n语言以及任何A,B,其中A!= B?

有了已知的A = a和B = b,我们就可以写了

% For each 'a' save 'b' in a list, then check 
% whether constructed list is equal to the rest of input list

anbn(L) :- anbn(L, []). 

anbn(L, L). 

anbn([a|L],A) :- anbn(L, [b|A]).
Run Code Online (Sandbox Code Playgroud)

对于任何A和BI都在考虑一个解决方案

anbn(L) :- anbn(L, []).

anbn([H|L],[]) :- anbn(L,[H]). % save an element

anbn([H|L], [H|A]) :- anbn(L, [H,H|A]). % make sure front elements are the same
Run Code Online (Sandbox Code Playgroud)

所以第一个元素都是相同的,但是我没有看到一个优雅的方法来检查列表其余部分中的所有元素是否与前面的元素相同和不同.

我可以检查剩下的是否与存储的列表一样长,然后它是否只包含第二个类型的元素,但我相信我的问题过于复杂,并且存在一个简短的解决方案.

Fre*_*Foo 8

使用明确的子句语法.

s(_, _) --> [].
s(A, B) --> [A], s(A, B), [B].
Run Code Online (Sandbox Code Playgroud)

演示:

?- phrase(s(1, 2), X).
X = [] ;
X = [1, 2] ;
X = [1, 1, 2, 2] ;
X = [1, 1, 1, 2, 2, 2] .
Run Code Online (Sandbox Code Playgroud)

  • 很好,+1.与此处发布的其他解决方案相比,您的工作也适用于最常见的查询,`? - 短语(s(X,Y),Ls).`.请注意,虽然您还不满足OP的要求,即"X"和"Y"是不同的.在第一条规则中使用`dif/2`.应始终使用DCG的`phrase/2`(或`phrase/3`)接口,因为DCG到Prolog谓词的转换可能会根据Prolog实现或版本而改变. (2认同)
  • 唯一不会烧伤眼睛的解决方案.:) +1 (2认同)