我想知道是否有一种(可以理解的)方法来使用 prolog 谓词蛮力解决 Post 对应问题?
例如:
?- pcp(["1","11"),("10111","101")], S).
S = [2,1,1]
我想知道是否有一种(可以理解的)方法来使用 prolog 谓词蛮力解决 Post 对应问题?
例如:
?- pcp(["1","11"),("10111","101")], S).
S = [2,1,1]
好的,这是一个可能的程序,它使用广度优先搜索来找到问题的越来越大的解决方案。
1 ?- [user].
从大小为 1 的解开始搜索
|: pcp(Ts,S) :- pcp(Ts,S,1).
尝试找到当前尺寸的解决方案,如果找不到,请尝试下一个尺寸
|: pcp(Ts,S,N) :- pcp_solve(Ts,("",""),S,N).
|: pcp(Ts,S,N) :- N2 is N+1, pcp(Ts,S,N2).
如果在正确大小的解决方案结束时,字符串完全匹配,那么问题就解决了
|: pcp_solve(_,("",""),[],0).
检查解决方案的重要步骤:从字符串元组列表中获取解决方案中索引的元组元素,将此元组中的字符串附加到上一步的字符串中,匹配所有相同的内容,至少保留一个字符串为空,然后进入解决方案的下一部分。(显然,如果字符串在某些时候不匹配,matchreduce 将失败。)
|: pcp_solve(Ts,A,[I|S],N) :- N>0, N2 is N-1, nth1(I,Ts,T),
|: bothappend(A,T,AT), matchreduce(AT,ATr), pcp_solve(Ts,ATr,S,N2).
以下是其余谓词:
|: bothappend((A1,B1),(A2,B2),(A3,B3)) :- append(A1,A2,A3), append(B1,B2,B3).
|: matchreduce(([],B),([],B)) :- !.
|: matchreduce((A,[]),(A,[])).
|: matchreduce(([X|A],[X|B]),(Ao,Bo)) :- matchreduce((A,B),(Ao,Bo)).
append 和 nth1 谓词在列表库(SWI-Prolog)中,但可以轻松实现!
|: :- use_module(library(lists)).
% library(error) compiled into error 0.01 sec, 9,640 bytes
% library(lists) compiled into lists 0.03 sec, 22,996 bytes
|:
% user://1 compiled 0.12 sec, 25,600 bytes
true.
这是您的测试用例:
2 ?- pcp([("1","11"),("10111","101")], S).
S = [2, 1, 1] ;
S = [2, 1, 1, 2, 1, 1] ;
S = [2, 1, 1, 2, 1, 1, 2, 1, 1] ;
S = [2, 1, 1, 2, 1, 1, 2, 1, 1|...] .
还有来自维基百科的一对:
3 ?- pcp([("a","baa"),("ab","aa"),("bba","bb")], S).
S = [3, 2, 3, 1] ;
S = [3, 2, 3, 1, 3, 2, 3, 1] ;
S = [3, 2, 3, 1, 3, 2, 3, 1, 3|...] .
4 ?- pcp([("bb","b"),("ab","ba"),("c","bc")], S).
S = [1, 3] ;
S = [1, 2, 3] ;
S = [1, 2, 2, 3] ;
S = [1, 3, 1, 3] ;
S = [1, 2, 2, 2, 3] ;
S = [1, 2, 3, 1, 3] ;
S = [1, 3, 1, 2, 3] ;
S = [1, 2, 2, 2, 2, 3] ;
S = [1, 2, 2, 3, 1, 3] ;
S = [1, 2, 3, 1, 2, 3] ;
S = [1, 3, 1, 2, 2, 3] ;
S = [1, 3, 1, 3, 1, 3] ;
S = [1, 2, 2, 2, 2, 2, 3] ;
S = [1, 2, 2, 2, 3, 1, 3] ;
S = [1, 2, 2, 3, 1, 2, 3] ;
S = [1, 2, 3, 1, 2, 2, 3] ;
S = [1, 2, 3, 1, 3, 1, 3] ;
S = [1, 3, 1, 2, 2, 2, 3] ;
S = [1, 3, 1, 2, 3, 1, 3] ;
S = [1, 3, 1, 3, 1, 2, 3] ;
S = [1, 2, 2, 2, 2, 2, 2, 3] ;
S = [1, 2, 2, 2, 2, 3, 1, 3] ;
S = [1, 2, 2, 2, 3, 1, 2, 3] ;
S = [1, 2, 2, 3, 1, 2, 2, 3] ;
S = [1, 2, 2, 3, 1, 3, 1, 3] ;
S = [1, 2, 3, 1, 2, 2, 2, 3] ;
S = [1, 2, 3, 1, 2, 3, 1, 3] ;
S = [1, 2, 3, 1, 3, 1, 2, 3] ;
S = [1, 3, 1, 2, 2, 2, 2, 3] ;
S = [1, 3, 1, 2, 2, 3, 1, 3] ;
S = [1, 3, 1, 2, 3, 1, 2, 3] ;
S = [1, 3, 1, 3, 1, 2, 2, 3] ;
S = [1, 3, 1, 3, 1, 3, 1, 3] ;