Prolog 逻辑难题的软件解决方案

Prolog 逻辑难题的软件解决方案,prolog,logic,clpb,Prolog,Logic,Clpb,我发现了一个有趣但相当简单的逻辑问题: 此列表中的哪个答案是此问题的正确答案 以下所有内容 下面没有一个 所有这些 上面的一个 以上都没有 以上都没有 将这些命题重新编写为某些编程语言中的语句是相当容易的: def p1 = p2 && p3 && p4 && p5 && p6 def p2 = !p3 && !p4 && !p5 && !p6 def p3 = p1 &&am

我发现了一个有趣但相当简单的逻辑问题:

此列表中的哪个答案是此问题的正确答案

  • 以下所有内容
  • 下面没有一个
  • 所有这些
  • 上面的一个
  • 以上都没有
  • 以上都没有
  • 将这些命题重新编写为某些编程语言中的语句是相当容易的:

    def p1 = p2 && p3 && p4 && p5 && p6
    def p2 = !p3 && !p4 && !p5 && !p6
    def p3 = p1 && p2 
    
    等等。更困难的是,在不进入无限循环的情况下实际运行这样一个程序

    有没有一种语言或库(或其他东西)或多或少地解决了这个问题?我在想Prolog,因为我对Prolog的了解是它用于解决“类似这样的问题”


    代码是什么样子的?

    Prolog解决这样的逻辑难题确实很简单

    例如,一种方法是使用CLP(B),它代表布尔变量上的约束逻辑编程,并有自己的标记

    一些Prolog系统附带CLP(B)解算器。SICStus Prolog就是一个非常突出的例子

    这种方法的核心思想是将任务表述为布尔变量上的约束满足问题(CSP)

    在这个具体的例子中,我们可以使用命题变量A1、A2、…、A6来表示回答问题的不同方式。每个答案都将这些变量中的一个与几个变量相关联,反映了答案对其他答案的陈述

    使用SICStus Prolog,对每个答案的含义的声明性描述可能如下所示:

    :- use_module(library(clpb)). solution([A1,A2,A3,A4,A5,A6]) :- sat(A1 =:= A2*A3*A4*A5*A6), sat(A2 =:= ~(A2+A3+A4+A5+A6)), sat(A3 =:= A1*A2), sat(A4 =:= card([1],[A1,A2,A3])), sat(A5 =:= ~(A1+A2+A3+A4)), sat(A6 =:= ~(A1+A2+A3+A4+A5)). :-使用_模块(库(clpb))。 溶液([A1、A2、A3、A4、A5、A6]):- sat(A1=:=A2*A3*A4*A5*A6), sat(A2=:=~(A2+A3+A4+A5+A6)), sat(A3=:=A1*A2), sat(A4=:=卡片([1],[A1,A2,A3]), sat(A5=:=~(A1+A2+A3+A4)), sat(A6=:=~(A1+A2+A3+A4+A5))。 从以下查询中,我们可以看到,根据这些约束条件,只有一个答案在逻辑上是可接受的:

    ?- solution(Vs). Vs = [0, 0, 0, 0, 1, 0]. ?解决方案(Vs)。 Vs=[0,0,0,0,1,0]。 因此,回答5是唯一可以选择的回答,同时保持所有陈述的一致性

    在这样的公式中不可能出现无限循环,因为每个单独的约束总是终止,并且整个程序仅由一系列这样的约束组成


    约束求解器已经使用一个称为约束传播的过程自动推导出了单个可接受的解决方案。使用Prolog解决此类逻辑难题确实很简单

    例如,一种方法是使用CLP(B),它代表布尔变量上的约束逻辑编程,并有自己的标记

    一些Prolog系统附带CLP(B)解算器。SICStus Prolog就是一个非常突出的例子

    这种方法的核心思想是将任务表述为布尔变量上的约束满足问题(CSP)

    在这个具体的例子中,我们可以使用命题变量A1、A2、…、A6来表示回答问题的不同方式。每个答案都将这些变量中的一个与几个变量相关联,反映了答案对其他答案的陈述

    使用SICStus Prolog,对每个答案的含义的声明性描述可能如下所示:

    :- use_module(library(clpb)). solution([A1,A2,A3,A4,A5,A6]) :- sat(A1 =:= A2*A3*A4*A5*A6), sat(A2 =:= ~(A2+A3+A4+A5+A6)), sat(A3 =:= A1*A2), sat(A4 =:= card([1],[A1,A2,A3])), sat(A5 =:= ~(A1+A2+A3+A4)), sat(A6 =:= ~(A1+A2+A3+A4+A5)). :-使用_模块(库(clpb))。 溶液([A1、A2、A3、A4、A5、A6]):- sat(A1=:=A2*A3*A4*A5*A6), sat(A2=:=~(A2+A3+A4+A5+A6)), sat(A3=:=A1*A2), sat(A4=:=卡片([1],[A1,A2,A3]), sat(A5=:=~(A1+A2+A3+A4)), sat(A6=:=~(A1+A2+A3+A4+A5))。 从以下查询中,我们可以看到,根据这些约束条件,只有一个答案在逻辑上是可接受的:

    ?- solution(Vs). Vs = [0, 0, 0, 0, 1, 0]. ?解决方案(Vs)。 Vs=[0,0,0,0,1,0]。 因此,回答5是唯一可以选择的回答,同时保持所有陈述的一致性

    在这样的公式中不可能出现无限循环,因为每个单独的约束总是终止,并且整个程序仅由一系列这样的约束组成


    约束解算器已使用称为约束传播

    的过程自动推导出单个可接受的解,如果“卡片”表示基数,则您已将(4)解释为“正好是上述其中一项”。如果你将其解释为“至少上述一项”,答案不会改变。是的,这是真的,我将其解释为“正是上述一项”。若要将其解释为“至少上述一项,请在
    card/2
    表达式中将
    [1]
    更改为
    [1,2,3]
    ,它确实表示基数。更准确地说,
    card(Ls,Exprs)如果
    Exprs
    中的真表达式数是表示整数范围的整数或整数对列表
    Ls
    中的一个成员,则
    为真。因此,您可以等效使用
    [1,2,3]
    ,而不是
    [1-3]
    。解决方案保持不变。如果“card“表示基数,那么您将(4)解释为“正是上述其中一项”。如果你将其解释为“至少上述一项”,答案不会改变。是的,这是真的,我将其解释为“正是上述一项”。若要将其解释为“至少上述一项,请在
    card/2
    表达式中将
    [1]
    更改为
    [1,2,3]
    ,它确实表示基数。更准确地说,
    card(Ls,Exprs)如果
    Exprs
    中的真表达式数是表示整数范围的整数或整数对列表
    Ls
    中的一个成员,则
    为真。因此,您可以等效地使用
    [1,2,3]
    ,而不是
    [1-3]
    。解决方案保持不变。