1

编辑:我想出了单例变量。Prolog 不喜欢数据库的大写单词。我还对代码进行了一些重大更改。

编辑:编辑:意识到我没有递归调用。德普

尽管我在使用 Haskell 进行函数式编程方面有一些经验,但我对 Prolog 还是很陌生。

尽管我在尝试使函数输出使语句为真的所有可能值时遇到了麻烦。我不认为这是一个逻辑错误,因为过去几个小时我一直在经历它,但我可能是错的。

在这个问题中,我试图创建汽车的所有权历史。

-- 我知道一个人拥有一辆车 如果 - 他/她从经销商那里买了这辆车 - 他/她从前车主那里买了这辆车。

因此,了解这些事实后,我建立了一个数据库,创建了汽车、车主和一个单独的经销商变量,这些变量将在此递归中用作基本案例。

car(prius).
car(bmw).

owner(meg).
owner(nora).
dealer(d).

boughtFrom(meg,nora).
boughtFrom(nora,d).

我确定了从从经销商那里购买的诺拉购买的梅格。当您从经销商处购买时,我计划的递归停止,因为这是基本情况的终点。所以逻辑是这样的:

ownCar(X,Y) :- boughtFrom(X,d), car(Y).
ownCar(X,Y) :- ownCar(boughtFrom(_,prevowner(X)), car(Y)).

如果您是经销商或从前任车主那里购买汽车,您可以成为汽车的车主。如果他们是从经销商或其他前任所有者那里购买的,则该前任所有者就是所有者。等等等等。所以它唯一停止的时间是这个人从经销商那里买车的时候。

4

1 回答 1

0

我认为您的数据库不完整,因为缺少一些明显的关系。

例如,这条规则ownCar(X,Y) :- boughtFrom(X,d), car(Y).适用于所有Y,即从经销商处购买的任何人都将“拥有”每辆车。

表示也是不准确的。卖车后,卖方不再是车主。

无论如何,在 Prolog 中你编写连接(它是一个关系数据模型),然后得到传递属性的闭包:

ownCar(X, Y) :- owner(O), boughtFrom(X, O), ownCar(O, Y).

注意在Prolog中我们应该避免左递归,因为它可能导致无限循环,那么连接的顺序很重要。

编辑

要获取历史记录(作为列表),您应该在谓词中添加一个参数,或者将“输出”更改为列表。你可以做类似的事情

ownCar(X, Y, [X]) :- boughtFrom(X,d), car(Y).
ownCar(X, Y, [X|L]) :- owner(O), boughtFrom(X, O), ownCar(O, Y, L).

注意:通常在 Prolog 中,我们将“输出”参数放在最后一个参数位置。

于 2013-03-17T19:19:12.177 回答