序言关系和比较

时间:2015-01-22 05:07:07

标签: prolog

我说我有这些关系

drive(adam, van).
drive(betty, tank).
drive(adam, truck).
drive(adam, convertible).

我如何写一个条件来找出adam驱动三种不同的车辆?

我试过这个,但这没有用。

drivethree(A):-    
  drive(A, X),
  drive(A, Y), 
  drive(A, Z),
  X = not(Y),
  X = not(Z),
  Y = not(Z).

2 个答案:

答案 0 :(得分:2)

首先,您可能想了解您的程序无法正常工作的原因。毕竟,这可能不是导致问题的唯一程序。

识别不正确的测试用例

问题是drivethree(X)在您期望它工作时不会成功。我们如何将问题本地化?

概括您的计划

一种可能性是通过在另一个目标之后移除一个目标来概括您的程序。如果生成的程序仍然失败,则必须在剩余的小部分中出现错误!无需一次阅读所有内容。

我会在要移除的目标前添加*

:- op(920,fy, *).
*_.

drivethree(A):-    
   drive(A, X),
   * drive(A, Y), 
   * drive(A, Z),
   X = not(Y),
   * X = not(Z),
   * Y = not(Z).

在这个新程序drivethree(A)仍然失败,但只使用两个目标。因此,在这两个目标中必须存在一些错误。要更好地看到这一点,请尝试查询:

?- drive(A, X), X = not(Z).
false.

再次失败。现在,我们将只尝试第一个目标:

?- drive(A, X).
A = adam,
X = van ;
A = betty,
X = tank ...

因此X必须是某个原子,但X = not(Z)要求它是带有仿函数not/1的结构。

要表达不平等,最好使用dif(X, Z) see this for more。事实上,请使用:

drivethree(A):-
   dif(X, Y),
   dif(X, Z),
   dif(Y, Z),    
   drive(A, X),
   drive(A, Y), 
   drive(A, Z).

但回到你的实际问题。你在这里描述的是那些驾驶至少三辆车的人。

单调性

现在想象一下,我们正在为您的计划添加新的事实drive/2。会发生什么? adam仍然是一个解决方案吗?事实上,如果我们只添加更多事实,他将永远是一个解决方案。这种属性被称为单调性。通过添加更多条款,您只会增加一组解决方案。

考虑一下你想要描述那些开车完全三辆车的人。然后坚持一下,想想如果我们在这样的程序中添加新的事实会发生什么。现在可能会发生adam不再是解决方案,因为他现在可能驾驶四辆或更多车辆。这样的程序被称为非单调。在开始学习Prolog时,首次远离非单调程序并坚持单调程序。

答案 1 :(得分:0)

如果您打算在修正后打算至少 3&#3>,您的代码应该有效:

...
X = not(Y),
X = not(Z),
...

应该是

...
X \= Y,
X \= Z,
...

否则,为了更实际的定义,'驱动完全 3',您可以使用setof / 3:

drivethree(A) :- setof(V, drive(A,V), [_,_,_]).