我说我有这些关系
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).
答案 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), [_,_,_]).