首页 文章

如何在Prolog中实现列表连接?

提问于
浏览
1

我有以下紧凑的例子,它采用3个参数L1,L2,L3并在L3中附加L1和L2(验证L3是L1和L2的串联)

我有这个代码(运行良好):

myappend([], L, L).
myappend([X|L1], L2, [X|L]) :- myappend(L1,L2,L).

事实是基本情况,并说 when the first list is a void list, the concatenation of the first list with second list is just the second list .

好吧,这很明显......规则对我来说非常清楚(但根本不是)我可以认为这个规则是测试第1,第2和第3个参数是否具有第1和第2个连接关系的谓词是第3个争论

好吧,我试图以扩展形式表达前面的代码,其中我有这个规则的主体,代表所有必须满足的谓词(必须为TRUE),以便规则的头部本身满足 .

我在SWI Prolog中实现此代码有一些问题,这是我的代码:

concatena([],L,L).

/* REGOLA */

concatena(L1,L2,L3) :- L1 = [_|T],          /* Always true: anonymous variable: "_" unifies everything */
               concatena(T,L2,L3).     /* Recursively call on the tail of L1 */
           [X|L1],
           [X|L3].

事实是基本情况(如前面的工作示例)

在我的实验中,规则是不同的 .

为了验证规则的头部,它身体中的所有谓词都必须是真的......

我认为我的想法是好的,直到达到基本情况,事实上做:

L1 = [_|T],         /* It is always true */
concatena(T,L2,L3)  /* Call recursively on a subproblem of the original problem, this problem have one less element

好的,这样就达到了基本情况,因此L3与L2正确统一

事实上在我的追踪中:

[trace] 3 ?- concatena([a,b],[c,d],L3).
   Call: (6) concatena([a, b], [c, d], _G1514) ? creep
   Call: (7) [a, b]=[_G1592|_G1593] ? creep
   Exit: (7) [a, b]=[a, b] ? creep
   Call: (7) concatena([b], [c, d], _G1514) ? creep
   Call: (8) [b]=[_G1595|_G1596] ? creep
   Exit: (8) [b]=[b] ? creep
   Call: (8) concatena([], [c, d], _G1514) ? creep
   Exit: (8) concatena([], [c, d], [c, d]) ?

(这与我在查看原始工作示例的痕迹时发生的情况相同...所以在此之前应该更正)

问题是当程序做回溯,不工作!

实际上我有这个跟踪(这是如何结束以前不完整的跟踪):

Exit: (7) concatena([b], [c, d], [c, d]) ? creep
   Exit: (6) concatena([a, b], [c, d], [c, d]) ? creep
L3 = [c, d]

1 回答

  • 2

    我不完全清楚你在这里要做什么:重写myappend规则的第二部分,以便所有参数都是简单的变量项?在这种情况下,您可以使用=运算符重写原始myappend的参数:

    concatena(L1,L2,L3) :- L1=[X|T], L3=[X|L4], concatena(T,L2,L4).
    

    正如你在这里写的那样,你的规则的第二部分,

    [X|L1],
    [X|L3].
    

    因为它遵循 . 所以不被视为规则的一部分,所以没有回溯,并且随着递归的展开没有任何事情发生 .

相关问题