如何在prolog中为一个变量分配一个列表?

时间:2014-09-28 20:01:49

标签: prolog

我想追加([],C,C),其中C是包含一些元素的列表。可能吗?如果其他条件为真,我将在包含元素的C中追加一些列表追加(Found,C,C)。 而且我想将C中的最终值存储到变量D中。我怎么能这样做?

1 个答案:

答案 0 :(得分:2)

  

我想追加([],C,C),其中C是包含一些元素的列表。有可能吗?

append([],C,C)永远是真的。一个空列表与任何东西相结合就是一切。看看Prolog在您尝试时所说的内容:

?- append([],C,C).
true.

这个没有任何绑定的true告诉您Prolog建立了证明,但结果没有创建新的绑定。此代码具有相同的结果:

meaningless(_, _, _).

?- meaningless(everybody, X, Squant).
true.

这表明你的愿望是错位的。 append([], C, C)不符合您的想法。

  

如果其他条件为真,我会在C中追加一些包含元素append(Found,C,C)的列表。而且我还希望将C中的最终值存储到变量D.我该怎么做?

根据"存储"进行思考和其他暗示可变状态的操作是一个肯定的迹象,表明你不了解Prolog。在Prolog中,您可以建立绑定(或将事实断言到动态存储中,这对于初学者来说是一个tar坑)。通过这样的方式可以以Prolog的方式实现类似的东西:

frob(cat, List, Result) :- append([cat], List, Result).
frob(dog, List, List).

这个谓词frob/3有两个参数:一个原子和一个列表。如果原子是cat,那么它会将[cat]附加到列表的开头。您在子句头部的参数和它们在子句主体中的使用之间看到的线程是Prolog如何管理状态。基本上,Prolog中的所有状态都在调用堆栈或动态存储中。

举一个Python的例子,考虑这两种实现阶乘的方法:

def fac(n):
  result = 1
  while n > 1:
    result = result * n
    n = n - 1

此版本有一个变量result,这是一种状态。我们在循环中反复变异状态以实现计算。虽然阶乘函数可以定义为fac(n)= n * fac(n-1),但是这个实现没有明确隐藏在代码中的fac(n-1)。

递归方法是:

def fac(n):
  if n < 1: 
    return 1
  else: 
    return n * fac(n-1)

这里没有明确的状态,那么计算如何运作?状态是隐含的,它是在堆栈上进行的。程序员往往会在递归时提出一个持怀疑态度的眉毛,但在Prolog中,没有assignable这样的东西,所以第一种方法不能使用。

回到frob/3,条件隐含在第一个参数上。主体中的行为是不同的,因为在第一个主体中,第三个参数将绑定到append/3调用的第三个参数,这将与附加到第二个参数的原子cat的列表统一起来。参数List。在第二个主体中,没有任何特殊情况会发生,第三个参数将与第二个参数绑定相同的值。因此,如果您要致电frob(Animal, List, Result)Result将在前面与cat绑定,或者不会根据Animal的内容绑定。

不要混淆并认为Prolog只是将最后一个参数视为返回值!如果这是真的,那肯定不会这样:

?- frob(X, Y, [whale]).
X = dog,
Y = [whale].

这里似乎发生的事情是Prolog可以告诉我,因为列表不是以cat开头,而是能够推断出X是dog。好的Prolog程序员渴望在他们的API中维持这种错觉,但是这里真正发生的一切是Prolog进入第一条规则,扩展到append([cat], X, [whale])然后统一失败,因为Prolog无法想出一个X,如果前面有[cat],则生成[whale]。结果,它进入了第二个规则,它将X与dog统一,并将第二个两个参数相互统一。因此Y = [whale]

我希望这有帮助!