Prolog程序理解

时间:2019-01-06 16:09:42

标签: prolog

这是我拥有的程序:

foo(L,[H|R1]) :-
    foo(L,R1,H).

foo([H],[],H).
foo([H|T],[H|T1],R) :-
    foo(T,T1,R).

这是查询:

foo([1,2,3,4,5,6],X).

我不了解该程序的功能,有人可以帮我解释一下它的工作原理吗?

3 个答案:

答案 0 :(得分:2)

在Prolog中,无需了解源代码。而是让Prolog为您执行此操作。只需问最普遍的查询

| ?- foo(L,R).
     L = [_A],
     R = [_A]
  ;  L = [_A,_B],
     R = [_B,_A]
  ;  L = [_A,_B,_C],
     R = [_C,_A,_B]
  ;  L = [_A,_B,_C,_D],
     R = [_D,_A,_B,_C]
  ;  L = [_A,_B,_C,_D,_E],
     R = [_E,_A,_B,_C,_D]
  ;  L = [_A,_B,_C,_D,_E,_F],
     R = [_F,_A,_B,_C,_D,_E]
  ;  L = [_A,_B,_C,_D,_E,_F,_G],
     R = [_G,_A,_B,_C,_D,_E,_F]
  ;  L = [_A,_B,_C,_D,_E,_F,_G,_H],
     R = [_H,_A,_B,_C,_D,_E,_F,_G]
  ;  ...

您在这里看到图案吗?

答案 1 :(得分:2)

您可以尝试对其进行重构。如果我以:

开头
foo(L, [H|R1]) :-
    foo(L, R1, H).

foo([H], [], H).
foo([H|T], [H|T1], R) :-
    foo(T, T1, R).

我可以将参数顺序foo(1,2,3)更改为foo(2,3,1):

foo(L,[H|R1]) :-
    foo(R1, H, L).

foo([], H, [H]).
foo([H|T1], R, [H|T]) :-
    foo(T1, R, T).

现在我可以更改foo的第二个参数,并传递[H]而不是H:

foo(L, [H|R1]) :-
    foo(R1, [H], L).

foo([], H, H).
foo([H|T1], R, [H|T]) :-
    foo(T1, R, T). 

现在,您可以重命名谓词以进行滚动和追加:

roll(L, [H|R1]) :-
    append(R1, [H], L).

append([], H, H).
append([H|T1], R, [H|T]) :-
    append(T1, R, T). 

答案 2 :(得分:0)

为便于理解,请将递归子句放在基数之上:

foo( [H | T], [H | T1], R) :- foo(          /* T = [_|_] */
          T,       T1,  R).
foo( [R],     [],       R).

因此,我们沿着两个列表(包含相同元素,H)前进,直到命中第一个列表([R])中的最后一个元素,此时第二个列表被耗尽( []),我们掌握了最后一个元素(R)。

这意味着foo( A, B, R) :- append( B, [R], A).。因此,

foo( L, [E | R1]) :- % foo( L, R1, E).
                     append( R1, [E], L).    % R1 ++ [E] = L

foo( L, M)关联两个列表LM,其中LM,其第一个元素E“翻转”到列表的末尾:< / p>

 L :     .............E
 M :    E.............
 %       ---- R1 -----