代码之家  ›  专栏  ›  技术社区  ›  Friedrich Schmidt

swi prolog中的逻辑门和

  •  0
  • Friedrich Schmidt  · 技术社区  · 6 年前

    如何获取以下Prolog程序

    and(1,1,1).
    and(1,0,0).
    and(0,1,0).
    and(0,0,0).
    

    分别给出以下答案

    ?- and(A,B,C).
    A=1, B=1, C=1;
    A=1, B=0, C=0;
    A=0, B=1, C=0;
    A=0, B=0, C=0.
    

    当我尝试运行上面的程序时,我得到以下结果

    ?- and(A,B,C).
    A = B, B = C, C = 0 ;
    A = C, C = 0,
    B = 1 ;
    A = 1,
    B = C, C = 0 ;
    A = B, B = C, C = 1.
    

    这似乎是正确的,但我不想在我的答案中包含变量,这是我预期答案的缩写。

    如果我运行GNU Prolog的例子,我只得到原子作为变量的答案,而不是变量本身的引用。这也是我想要的swi prolog:

    GNU Prolog 1.4.5 (64 bits)
    Compiled Feb  5 2017, 10:30:08 with gcc
    By Daniel Diaz
    Copyright (C) 1999-2016 Daniel Diaz
    | ?- und(A,B,C).
    
    A = 1
    B = 1
    C = 1 ? ;
    
    A = 1
    B = 0
    C = 0 ? ;
    
    A = 0
    B = 1
    C = 0 ? ;
    
    A = 0
    B = 0
    C = 0
    

    这个例子也在这里 PDF file 第10页。

    Im在Ubuntu 17.10上运行适用于amd64的SWI Prolog 7.4.2版

    谢谢

    //编辑:更正了逻辑AND的结果。 //edit2:添加了GNU Prolog中的示例,结果应该如何。

    1 回复  |  直到 6 年前
        1
  •  3
  •   tas    6 年前

    首先,正如注释中已经提到的,您的谓词 and/3 未在您引用的PDF中描述逻辑和。第10页的定义是:

    and(0,0,0).
    and(0,1,0).
    and(1,0,0).
    and(1,1,1).
    

    其次,如果只是关于最一般查询的输出,则可以编写一个arity 1的包装谓词,将两个参数和结果显示为三元组:

    and(A-B-C) :-
       and(A,B,C).
    

    如果您查询 and/1 使用单个变量,您可以得到与您帖子中的输出类似的输出:

    ?- and(X).
    X = 0-0-0 ;
    X = 0-1-0 ;
    X = 1-0-0 ;
    X = 1-1-1.
    

    如果您查询 和/1 对于三个变量,您得到的答案与对 和/3 :

    ?- and(A-B-C).
    A = B, B = C, C = 0 ;
    A = C, C = 0,
    B = 1 ;
    A = 1,
    B = C, C = 0 ;
    A = B, B = C, C = 1.
    
    ?- and(A,B,C).
    A = B, B = C, C = 0 ;
    A = C, C = 0,
    B = 1 ;
    A = 1,
    B = C, C = 0 ;
    A = B, B = C, C = 1.
    

    编辑

    在上面的示例中,您可以观察到Prolog提供的每个答案如何由查询中出现的每个变量的替换组成,从而使这些替换满足关系。这是在上面的“技巧”中查询时使用的属性 和/1 带着论点 X :只有一个变量可提供答案替换。您可以通过定义arity 0的输出谓词进一步实现这一点。那么Prolog只能回答 true 在成功的情况下,因为查询中没有提供替换的变量,您可以使用如下谓词 format/2 创建您喜欢的输出。例如:

    andoutput :-
       and(A,B,C),
       format('A = ~d, B = ~d, C = ~d~n', [A,B,C]).
    

    查询此谓词将生成所需的输出:

    ?- andoutput.
    A = 0, B = 0, C = 0    % <- output by format/2
    true ;                 % <- Prolog's answer
    A = 0, B = 1, C = 0    % <- output by format/2
    true ;                 % <- Prolog's answer
    A = 1, B = 0, C = 0    % <- output by format/2
    true ;                 % <- Prolog's answer
    A = 1, B = 1, C = 1    % <- output by format/2
    true.                  % <- Prolog's answer
    

    请注意谓词生成的输出与Prolog提供的答案之间的差异。如果您更喜欢与GNU Prolog的答案更相似的输出,您可以定义如下:

    andoutput2 :-
       and(A,B,C),
       format('~nA = ~d~nB = ~d~nC = ~d~n', [A,B,C]).
    
    ?- andoutput2.
             % <- output by format/2
    A = 0    % <- output by format/2
    B = 0    % <- output by format/2
    C = 0    % <- output by format/2
    true ;   % <- Prolog's answer
             % <- output by format/2
    A = 0    % <- output by format/2
    B = 1    % <- output by format/2
    C = 0    % <- output by format/2
    true ;   % <- Prolog's answer
             % <- output by format/2
    A = 1    % <- output by format/2
    B = 0    % <- output by format/2
    C = 0    % <- output by format/2
    true ;   % <- Prolog's answer
             % <- output by format/2
    A = 1    % <- output by format/2
    B = 1    % <- output by format/2
    C = 1    % <- output by format/2
    true.    % <- Prolog's answer
    

    然而,请记住,这只是格式化的输出,不会改变Prolog提供答案的方式。因此,对于您希望以个性化方式回答的每个谓词,您必须提供一个输出谓词。要查看生成输出的更多选项,请查看上的文档 formatted write