在prolog中查找循环路径

在prolog中查找循环路径,prolog,path-finding,Prolog,Path Finding,关于2,4,6-三硝基甲苯的查询示例: ?- tnt(X). X = [[c1, [c2, n1, o1, o2], c3, [c4, n2, o3, o4], c5, [c6, n3, o5, o6]]] . 我的第一步是找到一个循环路径并显示为列表。但结果显示为故障。它无法将路径另存为列表 atom_elements(h1,hydrogen,[c1]). atom_elements(n1,nitrogen,[o1, o2, c2]). atom_elements(o1,oxygen,[n1

关于2,4,6-三硝基甲苯的查询示例:

?- tnt(X).
X = [[c1, [c2, n1, o1, o2], c3, [c4, n2, o3, o4], c5,
[c6, n3, o5, o6]]] .
我的第一步是找到一个循环路径并显示为列表。但结果显示为故障。它无法将路径另存为列表

atom_elements(h1,hydrogen,[c1]).
atom_elements(n1,nitrogen,[o1, o2, c2]).
atom_elements(o1,oxygen,[n1]).
atom_elements(o2,oxygen,[n1]).
atom_elements(n2,nitrogen,[o3, o4, c4]).
atom_elements(o3,oxygen,[n2]).
atom_elements(o4,oxygen,[n2]).
atom_elements(h5,hydrogen,[c5]).
atom_elements(n3,nitrogen,[o5, o6, c6]).
atom_elements(o5,oxygen,[n3]).
atom_elements(o6,oxygen,[n3]).
atom_elements(h7,hydrogen,[c7]).
atom_elements(h8,hydrogen,[c7]).
atom_elements(h9,hydrogen,[c7]).
atom_elements(c1,carbon,[c2,c6,h1]).
atom_elements(c2,carbon,[c1,c3,n1]).
atom_elements(c3,carbon,[c2,c7,c4]).
atom_elements(c4,carbon,[c3,c5,n2]).
atom_elements(c5,carbon,[c4,c6,h5]).
atom_elements(c6,carbon,[c1,c5,n3]).
atom_elements(c7,carbon,[c3,h7,h8,h9]).

removeprevious(X,Y):-
    X=Y.

filterList(A,In,Out) :-
    exclude(removeprevious(A),In,Out).

nextlist(P,C,O) :-
    atom_elements(C,_,L),
    filterList(P,L,O).

findTNT(Start,Output):-
    atom_elements(Start,_,List),
    findTNT(Start,Start,List,[],Output).
    
findTNT(_,_,[],_,[]).
findTNT(Start,_,[H|_],_,Output) :-
    H = Start,
    write('Find it'),   %For debugging%
    append([H],[],Output).

findTNT(Start,Privious,[H|T],Visited,Output) :-
    write(H+'--'), %For debugging%
    H \== Start,
    \+ member(H,Visited),
    nextlist(Privious,H,List),
    append([H],Visited,V),
    (   
    findTNT(Start,H,List,V,Output),
        Output = [],
        findTNT(Start,Privious,T,V,Output);
        append([H],Output,O),
        Output is O).
结果是:


错误消息不是很好,但它表明问题在于您使用的
is
。具体来说,代码的第65行是:

Output is O
在程序中出现问题的地方,
输出
[]
O
[c6]
,这就是为什么将此目标打印为

[] is [c6]
因此,问题是您在非算术表达式上使用的是
is
<代码>仅可用于计算算术,例如:

X is 2 + 2
它不可用于术语相等。使用
=
进行此操作。最后一行应该更像:

Output = O

但这也不起作用,因为您正试图“分配”一个新术语给一个已经绑定到不同术语的变量。您正在尝试执行“递归追加”,这在Prolog中通常是错误的。最近关于这方面的一些问题:,

你能缩小你对有机化学中NOOB的编码范围吗?哪个谓词给您带来了问题?您定义了removeprevious/2,但在filterList/3中使用了removeprevious/1。有点不对劲!感谢您的回复,主要问题发生在“write('Find it')之后,无法追加输出列表。另一个问题是我不确定,递归的工作方式是在一个循环后找到同一个节点,然后在该节点返回一个列表。上层递归检查列表是否为空,如果不是,则追加当前节点并递归返回。顺便说一句,filterList/3中使用的removeprevious/2似乎没有错误。
Output = O