Constraint-SWI-Prolog查询

Constraint-SWI-Prolog查询,prolog,clpfd,Prolog,Clpfd,我马上就要考试了,我正在复习过去的试卷以帮助理解 我在过去的论文中遇到了以下问题: 考虑以下问题和答案。有些答案与事实相符 SWI Prolog将推断出什么,而其他人则是错误的。指明哪个 答案是真实的,哪些是假的(没有解释你的答案 是必需的)。 (i) |?- [A, B, C] ins 0 .. 2, A #= B + C. A = 0..2 B = 0..2 C = 0..2 (ii) |?- A in 0 .. 3, A * A #= A. A = 0..2 (iii) |?- [

我马上就要考试了,我正在复习过去的试卷以帮助理解

我在过去的论文中遇到了以下问题:

考虑以下问题和答案。有些答案与事实相符 SWI Prolog将推断出什么,而其他人则是错误的。指明哪个 答案是真实的,哪些是假的(没有解释你的答案 是必需的)。

(i) |?- [A, B, C] ins 0 .. 2, A #= B + C.

A = 0..2 B = 0..2 C = 0..2

(ii) |?- A in 0 .. 3, A * A #= A.

A = 0..2

(iii) |?- [A, B] ins -1 .. 1, A #= B.

A = 1 B = 1

(iv) |?- [A, B] ins 0 .. 3, A #= B + 1.

A = 1..3 B = 1..2 
我努力想知道每一个是真是假。有人能给我解释一下怎么弄清楚这些吗


谢谢,非常感谢您的帮助。

变量总是被限制为获取其域中包含的值,算术约束只会减少涉及变量的域

所以,试着“标记”所有变量——也就是说,分配来自报告域的值。当然,如果算术关系不满足,你可以说答案是伪造的。以(ii)为例。它是否适用于A=0?A=2怎么样


当然,这个“测试”不足以回答所有问题。一些报告的域较窄。例如,以三为例)。你能看到排除-1或0的任何原因吗。如果不能,则应将答案标记为伪造。

决定哪些答案是可接受的,哪些是不可接受的关键原则是查看剩余程序是否在声明上与原始查询等价。如果剩余约束允许原始查询没有的任何解决方案,或者相反,那么答案是假的(或者您在CLP(FD)解算器中发现了错误)。如果显示的答案在语法上都不正确,那么答案肯定是假的

让我们开始吧:

  • (i)
    |?-[A,B,C]在0。。2,A#=B+C.

    建议回答:
    A=0..2b=0..2c=0..2

    错了!原始查询将变量约束为整数,但此答案甚至不是语法上有效的Prolog程序

  • (ii)
    |?-A在0中。。3,A*A#=A.

    建议回答:
    A=0..2

    错了原始查询将
    A
    约束为整数,但根据这个剩余程序,
    A=0..2
    是一个有效的解决方案。术语
    (0,2)
    不是整数

  • (iii)
    ?-[A,B]ins-1。。1,A#=B.

    建议回答:
    A=1 B=1

    错了!语法上无效的

  • (iv)
    |?-[A,B]ins 0。。3,A#=B+1。

    建议回答:
    A=1..3b=1..2

    错了!语法上无效的

  • 请注意,即使所有显示的答案在语法上都是有效的,并且在(i)、(ii)和(iv)的剩余目标中,
    =/2
    被替换为
    in/2
    ,这些答案仍然是错误的,因为在每种情况下,您都可以找到原始查询或剩余目标不允许的解决方案,但不能同时找到两者。我将解决这些案例留给您作为练习,例如,假设相应的答案是:

  • A在0..2中,B在0..2中,C在0..2中。
  • 0..2中的A。
  • A=1,B=1。
  • A在1..3中,B在1..2中。
  • 并为每个案例找到一个见证人,以表明剩余目标在语义上与各自的原始查询不同


    例如,在案例(1)中,根据剩余约束,
    A=B=C=2
    将是有效的解决方案,但显然原始约束排除了该解决方案,因为
    2#=2+2
    不成立

    嗯。。。实际上,这个问题没有提到残差。对于案例i),我得到
    A=0..2b=0..2c=0..2
    和剩余
    B+C#=A
    。对于案例i,你得到剩余目标
    A在0..2,B在0..2,C在0..2
    B+C#=A
    。这在声明上等同于原始查询。如果在0..2中只得到了
    A,在0..2中得到了B,在0..2中得到了C
    ,那么剩余的程序将比原始查询更加通用。残差程序必须始终声明性地等同于原始查询,如果在其他残差中得到
    A=0..2
    ,则
    A
    甚至不是整数,而是术语
    0..2
    。如果像在
    A=0..2b=0..2
    中那样,答案甚至在语法上都是无效的,那么它肯定是假的。