给定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
的更紧凑的定义怎么样,否则相同w.r.t.终止和解决方案集,公平性,具有以下约束:
不使用(=)/2
等内置插件。
不使用(',')/2
或(;)/2
或call/1
等控件构造。
使用一个事实,一个递归规则和一个word/1
规则。
也许更简单的是在{:1}}中提出F1
这两个词:
F4
记录:此处利用的属性与终止单个二进制子句的不可判定性密切相关。赞美归于:
Philippe Devienne,PatrickLebègue,Jean-Christophe Routier和JörgWürtz。 One binary horn clause is enough STACS '94。
答案 0 :(得分: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] ; etc.
我正在使用差异列表来逐步实现我想要报告的解决方案。
答案 1 :(得分: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来找到答案.. 给出了结构,因此我们需要搜索args ..
%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).
我们仍然需要定义:
a
和{ {1}}某处,可能是b
。显然没有完成,也不确定是否可以这样做,但我想我会发一个答案,看看有什么人说的。目前搜索还很天真!
这只是测试前16个解决方案,但这可能足以得到正确答案..
也许这可能比自己解决问题更难!
答案 2 :(得分: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)
或变体。
这个版本的问题在于,随着评估的进行,我得到了正确的答案,这只是让他们回到顶层。
e.g。
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]]
我会在死寂之前继续努力,但是如果有人能够使用我在这里的东西,请向他们致敬,我只要求你给予赞扬,如果这部分有助于你得到答案。< / p>
member
是一位老朋友。请注意,它以[[]]
而不是[]
开头。
swap
我创建了这个谓词。我有交换工作的不同变化,但变化失败的原因不同。
我用调试器更仔细地查看了Mat's answer,因为它可以解决类似问题,我可以生成答案,但不能将它们独立地返回到Top。
将Mat的答案复制到此处以供参考。
p([W|_], _, W).
p([W0|Ws], [[a|W0],[b|W0]|Ls], W) :-
p(Ws, Ls, W).
word(W) :-
p([[]|Ls], Ls, W).
感兴趣的部分是评论的右边。我建议您从这里复制并过去进入一个应用程序,它允许您查看所有的行而不包装或隐藏。
左侧的列是使用SWI-Prolog运行查询trace
创建的,右侧的注释是通过使用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]
答案 3 :(得分:5)
通常我会将这些作为单个答案发布,但@false要求我将它们分开。
如果您阅读我的评论和答案,您会发现我知道我必须将结果从一次迭代传递回下一次迭代。让我深入了解的是使用我在
中找到的跨产品谓词 Richard A. O&#39; Keefe pg。如果你认真学习Prolog,那么这本书是必备的。
引用前言
有许多介绍Prolog的书籍。这不是其中之一 他们。把它想象成&#34; Prolog&#34;的第二步。如果你已经 如果您已经介绍过,请阅读其中一本入门书籍 关于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 :(得分:4)
因此,澄清一下,预期的解决方案是以下架构的实例吗?
fact(Args).
recursive_rule(Args0) :-
recursive_rule(Args1).
word(W) :-
recursive_rule(Args).
每次出现Args
变量代表零个或多个术语时,可能(但不一定)fact
和recursive_rule
实际上是同一个算子?
答案 5 :(得分:3)
根据Guy编码器的建议,这更接近了吗?
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).
答案 6 :(得分: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]