代码之家  ›  专栏  ›  技术社区  ›  Xiaoyong Guo

如何定义prolog规则来实现双重查询?

  •  0
  • Xiaoyong Guo  · 技术社区  · 4 年前

    我已经定义

    double(X,Y) :- Y is X*2.
    

    当我查询 double(3,Y) ,我明白 Y=6

    但当我询问 double(X,6), 我不能得到 X=3

    是否可以定义一个双向工作的规则?

    0 回复  |  直到 4 年前
        1
  •  1
  •   Will Ness Derri Leahy    4 年前

    是的,您需要检查哪些变量尚未设置,并采取相应的行动。一个没有错误检查的框架代码:

    double(X,Y) :-  % Y = 2*X
      (  var(X) ->
          (  var(Y) -> freeze(X, double(X,Y)),
                       freeze(Y, double(X,Y))
          ;  X is Y/2
          )
      ;  Y is 2*X
      ).
    

    在SWI Prolog中,

    33 ?- double(3,6).
    true.
    
    34 ?- double(3,Y).
    Y = 6.
    
    35 ?- double(X,6).
    X = 3.
    
    36 ?- double(X,Y).
    freeze(X, double(X, Y)),
    freeze(Y, double(X, Y)).
    
    37 ?- double(X,Y),Y=6.
    X = 3,
    Y = 6.
    
    38 ?- double(X,Y),X=3.
    X = 3,
    Y = 6.
    
    39 ?- double(X,Y),X=3,Y=41.
    false.
    

    或者,你可以

    41 ?- use_module( library(clpfd)).
    true.
    
    42 ?- [user].
    double(X,Y):- Y #= X * 2.
    

    以实现同样的效果。

        2
  •  0
  •   Nicholas Carey    4 年前

    我可能会这样做:

    double(X,Y) :- nonvar(X),            Y is X * 2 .
    double(X,Y) :-            nonvar(Y), X is Y / 2 .
    

    尽管当两个参数都被实例化时,您可能会得到两个解决方案( double(3,1.5). 将成功两次)。

    你可以通过多种方式来解决这个问题:

    • 使用切口来消除多余的选择点。

      double(X,Y) :- nonvar(X),            Y is X * 2 , ! .
      double(X,Y) :-            nonvar(Y), X is Y / 2     .
      
    • 添加额外的类型检查。

      double(X,Y) :- nonvar(X),    var(Y), Y is X * 2 .
      double(X,Y) :-            nonvar(Y), X is Y / 2 .
      
    • 或更多:

      double(X,Y) :- nonvar(X), nonvar(Y), X =:= Y .
      double(X,Y) :- nonvar(X),    var(Y), Y is X * 2 .
      double(X,Y) :-    var(X), nonvar(Y), X is Y / 2 .
      

      如果你走这条路,如果你愿意的话,可以加上第四种情况,这将产生一个无限的数字序列和它们的二重:

      double(X,Y) :- nonvar(X), nonvar(Y), X =:= Y .
      double(X,Y) :- nonvar(X),    var(Y), Y is X * 2 .
      double(X,Y) :-    var(X), nonvar(Y), X is Y / 2 .
      double(X,Y) :-    var(X),    var(Y), between(0,infinity), Y is X * 2. 
      
      
    推荐文章