更紧凑的定义

23

给定 word/1

word(W) :-
   abs(ABs),
   ABs = W.

abs([]).
abs([AB|ABs]) :-
   abs(ABs),
   ab(AB).

ab(a).
ab(b).

?- word(W).
   W = []
;  W = [a]
;  W = [b]
;  W = [a,a]
;  W = [b,a]
;  W = [a,b]
;  W = [b,b]
;  W = [a,a,a]
;  W = [b,a,a]
;  W = [a,b,a]
;  W = [b,b,a]
;  W = [a,a,b]
;  W = [b,a,b]
;  W = [a,b,b]
;  W = [b,b,b]
;  W = [a,a,a,a]
;  ... .

一个更紧凑的 word/1 定义看起来像什么,与终止和解集相同,公平性,具有以下约束条件:

  1. 不使用像 (=)/2 这样的内置功能。

  2. 不使用控制结构,如 (',')/2(;)/2,或 call/1

  3. 使用一个事实、一个递归规则以及一个 word/1 规则。

也许更简单的方法是在以下术语中要求 F1 ... F4

word(W) :-
   p(F1).

p(F2).
p(F3) :-
   p(F4).

声明一下:这里利用的属性与单个二进制子句的终止不可判定性密切相关。感谢以下人员:

Philippe Devienne、Patrick Lebègue、Jean-Christophe Routier 和 Jörg Würtz。 一个二元角子句就足够了 STACS '94


2
我期望得到完全相同的答案,不一定要按照完全相同的顺序,但至少枚举应该是公平的。因此,每个解决方案最终都将被生成。 - false
1
@GuyCoder:ABs = W 只是为了防止 word/1 有更好的终止属性。实际上,word/1 永远不会终止。它可以找到解决方案,但永远不会终止。即使对于 word(non_word),它也只是循环。 - false
1
@GuyCoder: 就是这样! word/1 的规则只能包含一个目标。不允许使用连接符 (那太高级了:-))。 - false
1
@gniourf_gniourf:使用两个内置的length/2maplist/2,使用控制结构如并置和分离。然后是这些无法输入的lambda函数... - false
1
我觉得我离成功很近了,但也可能只是差那么一点点。我肯定认为睡一晚上对此有所帮助,但正如你所指出的,你还需要与之合作;基本上是清理大脑中的杂草,这样你就会少走弯路和歧途。幸运的是现在没有人可以再睡觉了。如果我还没有完成任务,一个小时前是否应该发布我的进度,以便其他人可以看到我忽略了什么? - Guy Coder
显示剩余19条评论
7个回答

11
我想出的解决方案是:
word(W) :-
        p([[]|Ls], Ls, W).

p([W|_], _, W).
p([W0|Ws], [[a|W0],[b|W0]|Ls], W) :-
        p(Ws, Ls, W).
说明:上述代码使用了差分列表来逐步实现我希望顶层报告的解决方案。

示例查询和答案:

?- word(W).
W = [] ;
W = [a] ;
W = [b] ;
W = [a, a] ;
W = [b, a] ;
W = [a, b] ;
W = [b, b] ;
W = [a, a, a] ;
W = [b, a, a] ;
W = [a, b, a] ;
W = [b, b, a] ;
W = [a, a, b] ;
W = [b, a, b] ;
W = [a, b, b] ;
W = [b, b, b] ;
W = [a, a, a, a] ;
W = [b, a, a, a] ;
等等。

1
我已经澄清这是一个解决方案。请注意,它不仅应该正确,而且还应该尽可能优雅,因此您可以找到更好的变量名。 - mat
你赢了,干得好。再次感谢你发布我要寻找的内容。我不认为我能及时想到 [[]|Ls]。我卡在 [[]] 上了。我知道要使用 p(..., W). 但不确定具体如何操作。 - Guy Coder
@false 你是指Provisional_end吧?我认为当处理(思考)懒队列时(像这个非常好!),最好称其为Production_pointp是一个奇怪的字符 - 两个谓词的交叉或总和,即member([E|T],_,E)member([_|T],_,E):- member(T,_,E)以及 gen([E|T],[[a|E],[b|E] | R],_):- gen(T,R,_),因此在2个不同点同时读写它!向用户mat的解决方案致敬!顺便说一下,就比较而言,在Haskell中,它是这样的:abs = [] : gen abs (drop 1 abs) where gen (x:t) p = (0:x):(1:x):gen t (drop 2 p) - Will Ness
@Will:我确实指的是一个常量,它在程序中没有出现过,在目标“p([[] | Ls],Ls,W)”的解决方案中清楚地表明了事物的“结尾”,让任何人都可以看到——所谓的“结尾”,而不受任何类型检查器的限制。 - false
@Will:在Haskell中是否有最小的图灵完备程序的工作知识?也就是说,它必须使用哪些构造,例如原始递归或更多等。请参见我在其他地方的评论 - false
显示剩余6条评论

7
好的,目前还没有答案。
我最接近的答案是:
s_s1([],[a]).
s_s1([b|T],[a|T]).
s_s1([a|T],[b|T2]):-
 s_s1(T,T2).

word([]).
word(W2):-
 word(W),
 s_s1(W,W2).

它既不符合条件,也没有给出正确的解决方案!

所以接下来我想我们可以尝试使用Prolog来查找答案... 已经给出了结构,我们需要搜索参数..

%First define the first 16 correct solutions.. 
correct_sols(X):-
X=[
     [],
     [a],
     [b],
     [a,a],
     [b,a],
     [a,b],
     [b,b],
     [a,a,a],
     [b,a,a],
     [a,b,a],
     [b,b,a],
     [a,a,b],
     [b,a,b],
     [a,b,b],
     [b,b,b],
     [a,a,a,a]
].

%Then a mi
provable(true, _) :- !.
provable((G1,G2), Defs) :- !,
    provable(G1, Defs),
    provable(G2, Defs).
provable(BI, _) :-
    predicate_property(BI, built_in),
    !,
    call(BI).
provable(Goal, Defs) :-
    member(Def, Defs),
    copy_term(Def, Goal-Body),
    provable(Body, Defs).

%From 4 Vars find 16 solutions to word(X)
vars_16sols(Vars,List):-
    Vars =[Args,Args0,Args1,Argsx],
    findnsols(16,X,provable(word(X),[
                            a(Args)-true,
                            a(Args0)-a(Args1),
                            word(X)-a(Argsx)]
                       ),List).
%Evaluate the score, for the solutions found how many match correct
evaluate_score(Solutions,Score):-
   correct_sols(C),
   maplist(correct_test_tf,C,Solutions,TrueFalse),
   findall(_,member(true,TrueFalse),Matches),
   length(Matches,Score).

%The main search, give a form for the starting 4 arguments, if they 
match all 16 correct stop.
startingargs_solution(Start,Sol):-
   vars_16sols(Start,SolsStart),
   evaluate_score(SolsStart,Score),
   Score =16,
   SolsStart=Sol.
%Othewise refine args, and try again.
startingargs_solution(Start,Sol):-
   vars_16sols(Start,SolsStart),
   evaluate_score(SolsStart,Score),
   Score <16,
   start_refined(Start,Refined),
   startingargs_solution(Refined,Sol).

我们仍需要定义:
  1. correct_test_tf/3
  2. 带有一些约束条件的start_refined/2,例如args的术语大小(需要合理以成为“紧凑定义”),以及需要包含哪些内容,即至少在某个地方包括a和b,可能是[]。
显然还没有完成,不确定是否可能完成,但想发表一个答案以了解人们的想法。目前搜索方式比较简单!
这只测试了前16个解决方案,但也许足以得出正确的答案。
也许这比单独解决问题更难!

3
非常有趣且值得一试的方法!它可能更加困难,但更为通用和灵活。如果您能够通过这种方式找到解决方案,我将额外支付500赏金。call_with_inference_limit/3 对此可能会有帮助。 - mat
3
好的,请提出一个新问题! - false

5

最接近我的技术。

unfold20([], []).
unfold20([H|T], [[a|H], [b|H]|L]) :-
   unfold20(T, L).

member20(X, [X|_]).
member20(X, [_|Tail]) :-
  member20(X, Tail).

swap20(R,R) :-
    write('swap20 R: '),write(R),nl.

swap20(In,L) :-
    write('swap20 In: '),write(In),nl,
    unfold20(In,L),
    swap20(L,_),
    write('swap20 L: '),write(L),nl.

word20(W) :-
    swap20([[]],L),
    write('word20 L: '),write(L),nl,
    member20(W,L),
    write('word20 W: '),write(W),nl.


?- word20(X).
swap20 R: [[]]
word20 L: [[]]
word20 W: []
X = [] ;
swap20 In: [[]]
swap20 R: [[a],[b]]
swap20 L: [[a],[b]]
word20 L: [[a],[b]]
word20 W: [a]
X = [a] ;
word20 W: [b]
X = [b] ;
swap20 In: [[a],[b]]
swap20 R: [[a,a],[b,a],[a,b],[b,b]]
swap20 L: [[a,a],[b,a],[a,b],[b,b]]
swap20 L: [[a],[b]]
word20 L: [[a],[b]]
word20 W: [a]
X = [a] ;
word20 W: [b]
X = [b] ;
swap20 In: [[a,a],[b,a],[a,b],[b,b]]
swap20 R: [[a,a,a],[b,a,a],[a,b,a],[b,b,a],[a,a,b],[b,a,b],[a,b,b],[b,b,b]]
swap20 L: [[a,a,a],[b,a,a],[a,b,a],[b,b,a],[a,a,b],[b,a,b],[a,b,b],[b,b,b]]
swap20 L: [[a,a],[b,a],[a,b],[b,b]]
swap20 L: [[a],[b]]
word20 L: [[a],[b]]
word20 W: [a]
X = [a] ;
word20 W: [b]
X = [b] ;
swap20 In: [[a,a,a],[b,a,a],[a,b,a],[b,b,a],[a,a,b],[b,a,b],[a,b,b],[b,b,b]]
swap20 R: [[a,a,a,a],[b,a,a,a],[a,b,a,a],[b,b,a,a],[a,a,b,a],[b,a,b,a],[a,b,b,a],[b,b,b,a],[a,a,a,b],[b,a,a,b],[a,b,a,b],[b,b,a,b],[a,a,b,b],[b,a,b,b],[a,b,b,b],[b,b,b,b]]
swap20 L: [[a,a,a,a],[b,a,a,a],[a,b,a,a],[b,b,a,a],[a,a,b,a],[b,a,b,a],[a,b,b,a],[b,b,b,a],[a,a,a,b],[b,a,a,b],[a,b,a,b],[b,b,a,b],[a,a,b,b],[b,a,b,b],[a,b,b,b],[b,b,b,b]]
swap20 L: [[a,a,a],[b,a,a],[a,b,a],[b,b,a],[a,a,b],[b,a,b],[a,b,b],[b,b,b]]
swap20 L: [[a,a],[b,a],[a,b],[b,b]]
swap20 L: [[a],[b]]
word20 L: [[a],[b]]
word20 W: [a]
X = [a]

如果您仔细观察,会发现没有使用分号;,我确信有些人会遇到问题。此外,所有规则都足够简单,可以通过使用其他参数将它们整合到要求中。例如,unfold(A,B) 可以变成 unfold(A,B,C,D) 或其他变形。

这个版本的问题在于,随着评估的进行,我可以获得正确的答案,但是需要将它们返回到顶层。

例如:

swap20 L: [[a,a,a],[b,a,a],[a,b,a],[b,b,a],[a,a,b],[b,a,b],[a,b,b],[b,b,b]]
swap20 L: [[a,a],[b,a],[a,b],[b,b]]
swap20 L: [[a],[b]]

在截止日期之前,我将继续努力,但如果有人能使用我这里的内容,那么我向他们致敬,只要您在获得答案方面从任何部分得到帮助,请给予信用。

unfold谓词基于此SO答案。感谢salva

member是一个老朋友。注意它以[[]]开始而不是[]

swap我创建了这个谓词。我已经为不同的变体制定了交换工作,但是由于不同的原因,该变体无法成功。

补充

Mat的答案的调试器输出

我仔细查看了Mat的答案,因为它可能对一个类似的问题有答案,即我可以生成答案,但不能单独将其返回给Top。

Mat的答案在此处复制以供参考。

p([W|_], _, W).

p([W0|Ws], [[a|W0],[b|W0]|Ls], W) :-
    p(Ws, Ls, W).

word(W) :-
    p([[]|Ls], Ls, W).

感兴趣的部分在右侧作为注释显示。建议您复制此处内容并粘贴到可查看所有行且无换行或隐藏的应用程序中。

左侧列是使用运行trace查询时SWI-Prolog创建的,右侧的注释是使用运行gtrace查询时手动复制值并记录缩进级别创建的。

?- word(W).
   Call: (8) word(_822) ? creep                                                                                                                                      % word(W) :-
   Call: (9) p([[]|_1010], _1010, _822) ? creep                                                                                                                      %   p([[]|Ls], Ls, W).
   Exit: (9) p([[]|_1010], _1010, []) ? creep                                                                                                                        %   p([W|_], _, W).                             % W = []
   Exit: (8) word([]) ? creep                                                                                                                                        % p([[]|Ls], Ls, W).                            % W = []
W = [] ;                                                                                                                                                                                                                       
   Redo: (9) p([[]|_1010], _1010, _822) ? creep                                                                                                                      %   p([W0|Ws], [[a|W0],[b|W0]|Ls], W) :-        %              W0 = []    Ws = [[a],[b]|Ls]
   Call: (10) p([[a], [b]|_1028], _1028, _822) ? creep                                                                                                               %     p(Ws, Ls, W).                             %              W0 = []    Ws = [[a],[b]|Ls]
   Exit: (10) p([[a], [b]|_1028], _1028, [a]) ? creep                                                                                                                %     p([W|_], _, W).                           % W = [a]    
   Exit: (9) p([[], [a], [b]|_1028], [[a], [b]|_1028], [a]) ? creep                                                                                                  %   p(Ws, Ls, W).                               % W = [a]      W0 = []    Ws = [[a],[b]|Ls]
   Exit: (8) word([a]) ? creep                                                                                                                                       % p([[]|Ls], Ls, W).                            % W = [a]                                                                               Ls = [[a],[b]|_2312]
W = [a] ;                                                                                                                                                                                                                                                                                             
   Redo: (10) p([[a], [b]|_1028], _1028, _822) ? creep                                                                                                               %     p([W0|Ws], [[a|W0],[b|W0]|Ls], W) :-      %              W0 = [a]   Ws = [    [b],[a,a],[b,a]|Ls]                          
   Call: (11) p([[b], [a, a], [b, a]|_1052], _1052, _822) ? creep                                                                                                    %       p(Ws, Ls, W).                           %              W0 = [a]   Ws = [    [b],[a,a],[b,a]|Ls]                          
   Exit: (11) p([[b], [a, a], [b, a]|_1052], _1052, [b]) ? creep                                                                                                     %       p([W|_], _, W).                         % W = [b]                                                                    
   Exit: (10) p([[a], [b], [a, a], [b, a]|_1052], [[a, a], [b, a]|_1052], [b]) ? creep                                                                               %     p(Ws, Ls, W).                             % W = [b]      W0 = [a]   Ws = [    [b],[a,a],[b,a]|Ls]                         
   Exit: (9) p([[], [a], [b], [a, a], [b, a]|_1052], [[a], [b], [a, a], [b, a]|_1052], [b]) ? creep                                                                  %   p(Ws, Ls, W).                               % W = [b]      W0 = []    Ws = [[a],[b],[a,a],[b,a]|_2324]                              Ls = [        [a,a],[b,a]|_2324] 
   Exit: (8) word([b]) ? creep                                                                                                                                       % p([[]|Ls], Ls, W).                            % W = [b]                                                                               Ls = [[a],[b],[a,a],[b,a]|_2324]                            
W = [b] .                                                                                                                                                                                                                                                                                            
   Redo: (11) p([[b], [a, a], [b, a]|_1052], _1052, _822) ? creep                                                                                                    %       p([W0|Ws], [[a|W0],[b|W0]|Ls], W) :-    %              W0 = [b]   Ws = [        [a,a],[b,a],[a,b],[b,b]|Ls]                  
   Call: (12) p([[a, a], [b, a], [a, b], [b, b]|_1076], _1076, _822) ? creep                                                                                         %         p(Ws, Ls, W).                         %              W0 = [b]   Ws = [        [a,a],[b,a],[a,b],[b,b]|Ls]                  
   Exit: (12) p([[a, a], [b, a], [a, b], [b, b]|_1076], _1076, [a, a]) ? creep                                                                                       %         p([W|_], _, W).                       % W = [a,a]                                                                   
   Exit: (11) p([[b], [a, a], [b, a], [a, b], [b, b]|_1076], [[a, b], [b, b]|_1076], [a, a]) ? creep                                                                 %       p(Ws, Ls, W).                           % W = [a,a]    W0 = [b]   Ws = [        [a,a],[b,a],[a,b],[b,b]|Ls]                  
   Exit: (10) p([[a], [b], [a, a], [b, a], [a, b], [b, b]|_1076], [[a, a], [b, a], [a, b], [b, b]|_1076], [a, a]) ? creep                                            %     p(Ws, Ls, W).                             % W = [a,a]    W0 = [a]   Ws = [    [b],[a,a],[b,a],[a,b],[b,b]|_2348]                  Ls = [                    [a,b],[b,b]|_2348]
   Exit: (9) p([[], [a], [b], [a, a], [b, a], [a, b], [b|...]|_1076], [[a], [b], [a, a], [b, a], [a, b], [b, b]|_1076], [a, a]) ? creep                              %   p(Ws, Ls, W).                               % W = [a,a]    W0 = []    Ws = [[a],[b],[a,a],[b,a],[a,b],[b,b]|_2348]                  Ls = [        [a,a],[b,a],[a,b],[b,b]|_2348] 
   Exit: (8) word([a, a]) ? creep                                                                                                                                    % p([[]|Ls], Ls, W).                            % W = [a,a]                                                                             Ls = [[a],[b],[a,a],[b,a],[a,b],[b,b]|_2348]
W = [a, a] ;                                                                                                                                                               
   Redo: (12) p([[a, a], [b, a], [a, b], [b, b]|_1076], _1076, _822) ? creep                                                                                                                         
   Call: (13) p([[b, a], [a, b], [b, b], [a, a, a], [b, a, a]|_1100], _1100, _822) ? creep                                                                           %         p([W0|Ws], [[a|W0],[b|W0]|Ls], W) :-  %              W0 = [a,a] Ws = [              [b,a],[a,b],[b,b],[a,a,a],[b,a,a]|Ls]                                              
   Exit: (13) p([[b, a], [a, b], [b, b], [a, a, a], [b, a, a]|_1100], _1100, [b, a]) ? creep                                                                         %           p(Ws, Ls, W).                       %              W0 = [a,a] Ws = [              [b,a],[a,b],[b,b],[a,a,a],[b,a,a]|Ls]                                                  
   Exit: (12) p([[a, a], [b, a], [a, b], [b, b], [a, a, a], [b, a|...]|_1100], [[a, a, a], [b, a, a]|_1100], [b, a]) ? creep                                         %           p([W|_], _, W).                     % W = [b,a]                                                                                                                                    
   Exit: (11) p([[b], [a, a], [b, a], [a, b], [b, b], [a, a|...], [b|...]|_1100], [[a, b], [b, b], [a, a, a], [b, a, a]|_1100], [b, a]) ? creep                      %         p(Ws, Ls, W).                         % W = [b,a]    W0 = [a,a] Ws = [              [b,a],[a,b],[b,b],[a,a,a],[b,a,a]|Ls]                                                                                                                                
   Exit: (10) p([[a], [b], [a, a], [b, a], [a, b], [b, b], [a|...], [...|...]|...], [[a, a], [b, a], [a, b], [b, b], [a, a, a], [b, a|...]|_1100], [b, a]) ? creep   %       p(Ws, Ls, W).                           % W = [b,a]    W0 = [b]   Ws = [        [a,a],[b,a],[a,b],[b,b],[a,a,a],[b,a,a]|_2372]  Ls = [                                [a,a,a],[b,a,a]|_2372]                                                                                                                                                         
   Exit: (9) p([[], [a], [b], [a, a], [b, a], [a, b], [b|...], [...|...]|...], [[a], [b], [a, a], [b, a], [a, b], [b, b], [a|...], [...|...]|...], [b, a]) ? creep   %     p(Ws, Ls, W).                             % W = [b,a]    W0 = [a]   Ws = [    [b],[a,a],[b,a],[a,b],[b,b],[a,a,a],[b,a,a]|_2372]  Ls = [                    [a,b],[b,b],[a,a,a],[b,a,a]|_2372]                                                                                                                                                           
   Exit: (8) word([b, a]) ? creep                                                                                                                                    %   p(Ws, Ls, W).                               % W = [b,a]    W0 = []    Ws = [[a],[b],[a,a],[b,a],[a,b],[b,b],[a,a,a],[b,a,a]|_2372]  Ls = [        [a,a],[b,a],[a,b],[b,b],[a,a,a],[b,a,a]|_2372]     
W = [b, a] ;                                                                                                                                                         % p([[]|Ls], Ls, W).                            % W = [b,a]                                                                             Ls = [[a],[b],[a,a],[b,a],[a,b],[b,b],[a,a,a],[b,a,a]|_2372] 

你可以使用额外的参数,通过binding使顶层报告答案! - mat
1
我真的很喜欢 unfold20!!! 但是想一想:它也必须要“返回”一个元素。 - false
1
(只是一般的评论:真的没有理由使用write/1。顶层写得更好!) - false
1
只需以这样的方式发布您的查询,顶层就会为您生成答案 - 无需编写(如果需要,则最好使用writeq/1)。 - false
1
另外:最好单独发布解决方案。 - false
显示剩余4条评论

5

通常我会将它们作为一个单独的答案发布,但@false要求我将它们分开。

如果你阅读我的评论和答案,你会发现我知道必须将一次迭代的结果传递到下一次迭代中。给我这个启示的是使用了"cross-product predicate"的谓词,在"Prolog编程艺术"(Richard A. O'Keefe著,第243页)中找到了它。

如果你认真学习Prolog,这本书必不可少。

引用前言:

有很多介绍Prolog的书籍,但这本不是其中之一。把它看作是"Prolog的第二步"。如果你已经读过一本入门书,如果你上过一门Prolog入门课程,如果你已经写过一两个Prolog程序,并且如果你想知道为什么编写好的Prolog程序仍然很难,那么这本书就是为了帮助你。本书的目的是向您展示如何编写有效、不花太多时间和足够整洁的Prolog程序。

这里是我用于一个未成功的变体的轻微变化。

combine(X,Y,[X,Y]).

product(P,Xs,Ys,PXYs) :-
    product1(Xs,Ys,PXYs,P).

product1([],_,[],_).

product1([X|Xs],Ys,PXYs0,P) :-
    product1(Ys,X,P,PXYs0,PXYs1),
    product1(Xs,Ys,PXYs1,P).

product1([],_,_) --> [].

product1([Y|Ys],X,P) -->
    {
        call(P,X,Y,PXY)
    },
    [PXY],
    product1(Ys,X,P).

?- product(combine,[a,b],[a,b],R).
R = [[a, a], [a, b], [b, a], [b, b]].

4

因此,澄清一下,预期的解决方案是以下模式的实例吗?

fact(Args).

recursive_rule(Args0) :-
    recursive_rule(Args1).

word(W) :-
    recursive_rule(Args).

每个Args变量的出现都代表零个或多个项,据推测(但不一定)factrecursive_rule实际上是相同的函数符号?


是的。只有当事实和递归规则属于相同的谓词时,您才有机会得到我们想要的结果。参数的数量是无关紧要的,因为您始终可以使用相应的函数符号将参数表示为单个参数。 - false

3

这不是一个解决方案,而是解决方案的启示。

这始于使用DCG。

abs4 --> [].
abs4 --> abs4, ([a] | [b]).


?- phrase(abs4,X).
X = [] ;
X = [a] ;
X = [b] ;
X = [a, a] ;
X = [a, b] ;
X = [b, a] ;
X = [b, b] ;
X = [a, a, a] ;
X = [a, a, b] ;
X = [a, b, a] ;
X = [a, b, b] ;
X = [b, a, a] ;
X = [b, a, b] ;
X = [b, b, a] ;
X = [b, b, b] ;
X = [a, a, a, a] ;
X = [a, a, a, b] ;

然后查看列表

?- listing(abs4).
abs4(A, A).
abs4(A, C) :-
        abs4(A, B),
        (   B=[a|C]
        ;   B=[b|C]
        ).

使用 member 去掉 ;

word5(W) :-
    abs5(W,[]).
abs5(A, A).
abs5(A, C) :-
    abs5(A, [D|C]),
    member5(D,[a,b]).
member5(X, [X|_]).
member5(X, [_|Tail]) :-
  member5(X, Tail).


?- word5(X).
X = [] ;
X = [a] ;
X = [b] ;
X = [a, a] ;
X = [a, b] ;
X = [b, a] ;
X = [b, b] ;
X = [a, a, a] ;
X = [a, a, b] ;
X = [a, b, a] ;
X = [a, b, b] ;
X = [b, a, a] 

过于分散了,原始的unfold20表明这种本地的分支是不必要的。 - false
@false 谢谢。我现在知道了,但这是变体4和5,直到后来我才发现unfold对于这个问题的威力。我在最初的研究中找到了可以使用的部分,但直到我开始使用它,就像你建议的那样,我才看到它是通向正确解决方案的路径。由于我已经做了多年的函数式编程,使用F#,我知道foldunfold有多么强大,但我在使用Prolog时并不像他们那样熟练。需要更多地与它们一起工作,特别是现在我已经看到了解决方案。 :) - Guy Coder

3
有Guy Coder的建议,这个更接近了吗?
unfold([], []).
unfold([H|T], [[a|H], [b|H]|L]) :-
 unfold(T, L).

ab([], [[]]).   
ab([_|N1],L):-
 ab(N1, L1),
 unfold(L1, L).

word(X):-
 length(List,_),
 ab(List,Values),
 member(X,Values).

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接