首页 > 解决方案 > 在prolog中找到一条循环路径

问题描述

在此处输入图像描述

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]).

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

?- tnt(X).
X = [[c1, [c2, n1, o1, o2], c3, [c4, n2, o3, o4], c5,
[c6, n3, o5, o6]]] .

我的第一步是找到一条自行车道并显示为一个列表。但结果显示为fault。它不能将路径保存为列表。

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).

结果是:

在此处输入图像描述

标签: prologpath-finding

解决方案


错误信息不是很好,但它表明问题出在您使用的is. 具体来说,代码的第 65 行内容如下:

Output is O

在程序的问题点,Outputis[]Ois [c6],这就是为什么这个目标被打印为

[] is [c6]

所以问题是你正在使用is不是算术表达式的东西。is仅可用于计算算术,例如:

X is 2 + 2

不适用于术语的相等性。为此使用=。所以最后一行应该更像:

Output = O

除了那也行不通,因为您正在尝试将新术语“分配”给已经绑定到不同术语的变量。而且您正在尝试执行“递归追加”,这在 Prolog 中几乎总是错误的。关于此的一些最近的问题:Prolog - Recursive append numbers to a listProlog - Recursive append to list return false


推荐阅读