2017-12-04 3 views
0

Prolog에서 재귀가 작동하는 방식을 이해하려고합니다. 다음 프로그램을 고려하십시오.다음 Prolog 프로그램에서 예기치 않은 동작이 발생했습니다.

edge(a,b). 
edge(b,c). 
edge(c,d). 
edge(a,d). 
edge(c,e). 
path(d). 
path(Vertex) :- edge(Vertex, Next), write(Next), path(Next). 

경로 (a)를 실행하십시오.

출력 : 나는 조용하지 않습니다 무엇

?- path(a). 
bcd 
true ; 
ed 
true; 
false 

이해는이 프로그램의 루프 부분이다. 그래서 우리는 a에서 시작한 다음 b, c 및 d로 이동합니다. 우리가 d를 보게되면 우리는 멈 춥니 다. 나는 네 번째 줄의 'ed'결과물을 이해할 수 없다. 왜 그것이 e, d 그리고 진실로 돌아갈 것인가. 나는 또한 어떻게 연산자 ';'이해가 안 돼요 다른 결과를 쿼리 할 때 작동합니다. 다음 결과를 얻는다는 뜻입니까?

다른 예 : 다음 프로그램은 한 노드에서 다른 노드로의 가능한 모든 경로를 작성합니다. 나는 경로의 다른 목록을 표시하는이 프로그램에서 루프가 어떻게 작동하는지 이해하지 못합니다.

link(a, b). 
    link(a, d). 
    link(b, c). 
    link(d, e). 
    link(e, c). 
    link(e, f). 
    link(f, a). 
    link(f, g). 
    link(f, j). 
    link(g, h). 
    link(h, i). 
    link(i, j). 


not(X) :- X, !, fail. 
not(_). 

writeallpaths(Node, Node) :- 
    write(Node), write(' is '), write(Node), nl. 
writeallpaths(Node, Next) :- 
    listpath(Node, Next, [Node], List), 
    write(Node), write(' to '), write(Next), write(' is '), 
    writepath(List), 
    fail. 

writepath([]) :- 
    nl. 
writepath([Head|Tail]) :- 
    write(' '), write(Head), writepath(Tail). 

listpath(Node, End, Outlist) :- 
    listpath(Node, End, [Node], Outlist). 

listpath(Node, Node, _, [Node]). 
listpath(Node, End, Tried, [Node|List]) :- 
    link(Node, Next), 
    not(member(Next, Tried)), 
    listpath(Next, End, [Next|Tried], List). 
+2

기본 교본을 받아야합니다. 프롤로그의 예술은 좋습니다. 아마 더 좋은 것들이있을 것입니다. –

+0

'경로 (d)'가 목표로 달성되면 역 추적이 중지되지 않습니다. 계속해서'ce' 경로를 찾습니다. 'd'에서 끝나지 않기 때문에 실패하지만 술어가'write'를 사용하기 때문에 궁극적 인 성공 또는 실패가 결정되기 전에 경로가 출력에 기록됩니다. @TomasBy가 암시 하듯이, 만약 당신이 무엇을''확실하지 않다면, 텍스트 북을 얻거나 온라인 Prolog 문서를 더 읽어야한다. – lurker

+0

@TomasBy이 예제는 기본 교과서에서 가져옵니다. – patzi

답변

0

또한 이해하지 않는 방법 운영자 ';' 다른 결과를 쿼리 할 때 작동합니다. 다음 결과를 얻는다는 뜻입니까?

예. 당신이 들어올 때 일어나는 일은 무엇입니까? 솔루션 "bcd"를 찾은 후 Prolog는 대체 솔루션을 찾으려고 시도합니다. 귀하의 경우, 그것은 "e"로 대체 경로가 있기 때문에 "c"로 되돌아 가고 (backtracks) "d"에이를 때까지 검색을 계속합니다. 분명히 Prolog는 처음부터 다시 돌아 가지 않으므로 "cced"이후의 노드 만 인쇄되기 때문에 "bced"전체 솔루션을 인쇄하지는 않습니다.

또한 항상 Prolog가 코드를 실행하는 방법을 자세히 볼 수있는 trace/0 조건자를 사용할 수 있습니다.

+0

이상한 것이 출력입니다. 쓰기를 사용하여 다음 노드를 인쇄했습니다. 나는 왜 그것이 진실 된 것을 인쇄하는지 이해하지 못한다; – patzi

관련 문제