How to define (and name) the corresponding safe term comparison predicates in ISO Prolog?

后端 未结 8 2078
萌比男神i
萌比男神i 2020-12-01 17:53

Standard term order (ISO/IEC 13211-1 7.2 Term order) is defined over all terms — including variables. While there are good uses for this — think of the implement

8条回答
  •  一整个雨季
    2020-12-01 18:37

    Next! This should do better than my previous attempt:

    lt(X,Y) :-
       X \== Y,
       (  X \= Y
       -> term_variables(X,Xvars),
          term_variables(Y,Yvars),
    
          T_alpha is -(10.0^1000),  % HACK!
          functor(T_omega,z,255),   % HACK!
    
          copy_term(t(X,Y,Xvars,Yvars),t(X1,Y1,X1vars,Y1vars)),
          copy_term(t(X,Y,Xvars,Yvars),t(X2,Y2,X2vars,Y2vars)),
          copy_term(t(X,Y,Xvars,Yvars),t(X3,Y3,X3vars,Y3vars)),
          copy_term(t(X,Y,Xvars,Yvars),t(X4,Y4,X4vars,Y4vars)),
    
          maplist(=(T_alpha),X1vars), maplist(maybe_unify(T_omega),Y1vars),
          maplist(=(T_omega),X2vars), maplist(maybe_unify(T_alpha),Y2vars),
          maplist(=(T_omega),Y3vars), maplist(maybe_unify(T_alpha),X3vars), 
          maplist(=(T_alpha),Y4vars), maplist(maybe_unify(T_omega),X4vars),
    
          % do T_alpha and T_omega have an impact on the order?
          (  compare(Cmp,X1,Y1),     
             compare(Cmp,X2,Y2),
             compare(Cmp,X3,Y3),
             compare(Cmp,X4,Y4),
          -> Cmp = (<)                % no: demand that X @< Y holds
          ;  throw(error(instantiation_error,lt/2))
          )
    
       ;  throw(error(instantiation_error,lt/2))
       ).
    

    The auxiliary maybe_unify/2 deals with variables occurring in both X and Y:

    maybe_unify(K,X) :-
       (  var(X)
       -> X = K
       ;  true
       ).
    

    Checking with GNU-Prolog 1.4.4:

    ?- lt(a(X,Y,c(c),Z1), a(X,Y,b(b,b),Z2)).
    yes
    ?- lt(a(X,Y,b(b,b),Z1), a(X,Y,c(c),Z2)).
    no
    ?- lt(a(X,Y1,c(c),Z1), a(X,Y2,b(b,b),Z2)).
    uncaught exception: error(instantiation_error,lt/2)
    ?- lt(a(X,Y1,b(b,b),Z1), a(X,Y2,c(c),Z2)).
    uncaught exception: error(instantiation_error,lt/2)
    ?- lt(b(b), a(a,a)).
    yes
    ?- lt(a(X), a(Y)).
    uncaught exception: error(instantiation_error,lt/2)
    ?- lt(X, 3).
    uncaught exception: error(instantiation_error,lt/2)
    ?- lt(X+a, X+b).
    yes
    ?- lt(X+a, Y+b).
    uncaught exception: error(instantiation_error,lt/2)
    ?- lt(a(X), b(Y)).
    yes
    ?- lt(a(X), a(Y)).
    uncaught exception: error(instantiation_error,lt/2)
    ?- lt(a(X), a(X)).
    no
    ?- lt(X+1,1+2).
    uncaught exception: error(instantiation_error,lt/2)
    
    ?- lt(X+X+2,X+1+3).                                       % NEW
    uncaught exception: error(instantiation_error,lt/2)
    

提交回复
热议问题