Seaman.h.zhang

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

内容提要

 Prolog中如何进行整数的比较

 整数比较的实际应用

 

Prolog中如何进行整数的比较

 一些Prolog的运算谓词可以实际地进行运算(即,不需要通过“is”协助),这些运算谓词都是进行整数比较的操作符。

 

 运算实例      Prolog表达式

 x < y         X < Y.

 x ≤ y         X =< Y.

 x = y         X =:= Y.

 x /= y        X =\= Y.

 x ≥ y          X >= Y.

 x > y        X > Y.

 

 这些操作符有明确的含义,可以直接在Prolog中使用:

   ?- 2 < 4.

   true

   ?- 2 =< 4.

   true

   ?- 4 =< 4.

   true

   ?- 4 =:= 4.

   true

   ?- 4 =\= 5.

   true

   ?-  4 >= 4.

   true

   ?- 4 > 2.

   true

 

 而且,这些操作符可以促使其左右两端的参数进行计算:

  ?- 2 < 4 + 1.

   true

   ?- 2 + 1 < 4.

   true

   ?- 2 + 1 < 3 + 2.

   true

 需要注意,=:=和=是不同的操作符,比如:

   ?- 4 = 4.

   true

   ?- 2+2 = 4.

   false

   ?- 2+2 =:= 4.

   true

 即,=会尝试对参数进行合一,而不是进行运算,=:=就会进行运算然后比较。

 而且在使用这些操作符时,必须注意变量是已经被初始化的,比如,下面的所有例子都因为变量没有初始化而失败:

   ?- X < 3.

   false

   ?- 3 < Y.

   false

   ?- X =:= X.

   false

 而且,变量必须要被初始化为整数,比如:

   ?- X = 3, X < 4.

   true

   ?- X = b, X > 4.

   false

 

实际应用

 下面我们通过一个实际的例子来学习如何将Prolog的比较数字能力运用到程序中。我们将会定义一个谓词,其第一个参数是由非负整数组成的列表,最后一个参数是返回的列表中的

最大值。同样,我们将会使用累加器。当遍历列表的过程中,累加器会保持当前找到的最大值,如果找到了更大的值,累加器会更新为新的最大值。当我们调用程序时,会将累加器的

初始值设置为0。下面是代码,请注意存在两个递归子句:

   accMax([H|T], A, Max) :- H > A, accMax(T, H, Max).

   accMax([H|T], A, Max) :- H =< A, accMax(T, A, Max).

   accMax([], A, A).

 第一个子句测试如果列表的头元素大于当前找到的最大值的情况,如果是,就会设置累加器为新的最大值,然后对列表的尾部进行递归操作。第二个子句测试列表的头元素等于小于当

前找到最大值的情况,如果是,就会继续使用当前累加器对列表尾部进行递归操作。最终,基础子句将第二个参数和第三个参数合一,将遍历列表后找到的最大值传递给第三个参数作为

结果。下面是查询的例子:

   ?- accMax([1, 0, 5, 4], 0, Max).

 首先accMax的第一个子句会起作用,得到如下的新目标:

   ?- accMax([0, 5, 4], 1, Max).

 注意累加器的值已经更新为1。然后,accMax的第二个子句会起作用,因为0(列表当前的头元素)比1小。这个过程会重复直到列表为空:

   ?- accMax([5, 4], 1, Max).

   ?- accMax([4], 5, Max).

   ?- accMax([], 5, Max).

 最后,第三个子句会起作用,将变量Max和累加器合一:

   Max = 5.

   true

 同样的,我们可以再定义一个谓词调用之前的谓词,并给出累加器;初始化的值。但是等等,我们应该将累加器的初始值赋值为什么?如果说是0,那么意味着我们假设列表中所有的数字

都是正数。但是如果有负数的列表,比如:

   ?- accMax([-11. -2, -7, -4, -12], 0, Max).

   Max = 0

   true

 这个结果就不是我们期望的,因为列表中最大值应该是:-2。我们使用0作为累加器的初始值,但是它比列表中所有的数字都大。

 有一个简单的方式解决这个问题:由于输入的列表是要求非空的整数组成的,所以将累加器的初始值设置为列表头元素的值。通过这种方式我们可以确保累加器初始值为列表中的数字之一,

下是具体的实现:

   ?- max(List, Max) :- List = [H|_], accMax(List, H, Max).

 所以,如果我们查询:

   ?- max([1, 2, 46, 53, 0], X).

   X = 53.

   true

 如果我们查询:

   ?- max([-11, -2, -7, -4, -12], X).

   X = -2. 

   true

 能够得到期望的结果。

posted on 2015-07-17 11:16  seaman.kingfall  阅读(1214)  评论(0编辑  收藏  举报