• Learn Prolog Now 翻译


    内容提要

     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

     能够得到期望的结果。

  • 相关阅读:
    Monkey界面版测试工具
    手游兼容性测试
    周版本制度
    08 | 事务到底是隔离的还是不隔离的?
    jackson
    localDateTime和Date
    服务器被攻击后数据库密码被破解
    GC收集器
    linux安装nginx,设置代理,负载均衡
    微信(公众,商户,开放)平台的区别
  • 原文地址:https://www.cnblogs.com/seaman-h-zhang/p/4653611.html
Copyright © 2020-2023  润新知