序言关系和比较 [英] prolog relation and comparison

查看:57
本文介绍了序言关系和比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这些关系

drive(adam, van).驱动器(贝蒂,坦克).驱动器(亚当,卡车).驱动器(亚当,敞篷车).

我如何编写一个条件来找出亚当驾驶三种不同的车辆?

我试过了,但没有用.

drivethree(A):-驱动器(A,X),驱动器(A,Y),驱动器(A,Z),X = 不(Y),X = 不(Z),Y = 不(Z).

解决方案

首先,您可能想了解为什么您的程序不起作用.毕竟,这可能不是唯一导致问题的程序.

识别不正确的测试用例

问题是 drivethree(X) 在您期望它工作时没有成功.我们如何定位问题?

概括您的程序

一种可能性是通过一个接一个地移除目标来概括您的程序.如果生成的程序仍然失败,那么即使在剩余的微小部分中也一定有错误!无需一次阅读所有内容.

我会在要移除的目标前面加一个*:

<预>:- op(950,fy, *).*_.驱动器三(A):-驱动器(A,X),* 驱动器(A, Y),* 驱动器(A, Z),X = 不(Y),* X = not(Z),* Y = not(Z).

在这个新程序中 drivethree(A) 仍然失败,但只使用了两个目标.所以这两个目标肯定存在一些错误.为了更好地了解这一点,请尝试查询:

?- drive(A, X), X = not(Z).错误的.

这又失败了.现在,我们将只尝试第一个目标:

?- 驱动器(A,X).A = 亚当,X = 货车;A = 贝蒂,X = 坦克 ...

so X 必须是某个原子,但是 X = not(Z) 要求它是一个带有函子 not/1 的结构.

要表达不等式,最好使用 dif(X, Z) 查看更多信息一>.实际上使用而不是:

drivethree(A):-差异(X,Y),差异(X,Z),差异(Y,Z),驱动器(A,X),驱动器(A,Y),驱动器(A,Z).

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

单调性

现在想象一下,我们正在向您的程序中添加新的事实 drive/2.会发生什么?adam 仍然是一个解决方案吗?事实上,如果我们只添加更多的事实,他将永远是一个解决方案.这种特性被称为单调性.通过添加更多子句,您只会增加解决方案集.

假设您要描述恰好驾驶三辆车的人.稍等片刻,想想如果我们在这样的程序中添加新的事实会发生什么.现在可能发生 adam 不再是一个解决方案,因为他现在可能驾驶四辆或更多辆车.这样的程序称为非单调.刚开始学习Prolog时,远离非单调的程序,坚持单调的程序.

Let said I have these relations

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

how do I write a condition to find out adam drives three different vehicles?

I tried this, but this didn't work.

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

解决方案

At first, you might want to understand why your program does not work. After all, this might not be the only program that causes problems.

Identify incorrect test cases

The problem is that drivethree(X) does not succeed while you expect it to work. How can we localize the problem?

Generalize your program

One possibility is to generalize your program by removing one goal after the other. If the resulting program is still failing, an error must be even in the tiny remaining part! No need to read everything at once.

I will add a * in front of the goals to be removed:

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

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

In this new program drivethree(A) is still failing, but using only two goals. So there must be some bug in these two goals. To better see this, try the query:

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

which again is failing. Now, we will try only the first goal:

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

so X must be some atom, but X = not(Z) demands that it is a structure with functor not/1.

To express inequality it is best to use dif(X, Z) see this for more. In fact use rather:

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

But back to your actual problem. What you are describing here are people who drive at least three vehicles.

Monotonicity

Now imagine, we are adding new facts drive/2 into your program. What will happen? Will adam still be a solution? In fact he will always be a solution if we only add further facts. This property is known as monotonicity. By adding further clauses you will only augment the set of solutions.

Just consider that you want to describe people who drive exactly three vehicles. And just hold on for a moment and think what will happen if we add new facts in such a program. Now it might happen that adam is no longer a solution because he might now drive four or more vehicles. Such a program is called non-monotonic. When starting to learn Prolog, keep away from non-monotonic programs for the first time and stick to monotonic ones.

这篇关于序言关系和比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆