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

后端 未结 8 2092
萌比男神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:18

    Third try! Developed and tested with GNU Prolog 1.4.4.


    Exhibit 'A': "as simple as it gets"

    lt(X,Y) :-
       X \== Y,
       (  X \= Y
       -> alpha_omega(Alpha,Omega),
          term_variables(X+Y,Vars),                           % A
          \+ \+ (label_vars(Vars,Alpha,Omega), X @< Y),
          (  \+ (label_vars(Vars,Alpha,Omega), X @> Y)
          -> true
          ;  throw(error(instantiation_error,lt/2))
          )
       ;  throw(error(instantiation_error,lt/2))
       ).    
    

    Exhibit 'B': "no need to label all vars"

    lt(X,Y) :-
       X \== Y,
       (  X \= Y
       -> alpha_omega(Alpha,Omega),
          term_variables(X,Xvars),                            % B
          term_variables(Y,Yvars),                            % B 
          vars_vars_needed(Xvars,Yvars,Vars),                 % B
          \+ \+ (label_vars(Vars,Alpha,Omega), X @< Y),
          (  \+ (label_vars(Vars,Alpha,Omega), X @> Y)
          -> true
          ;  throw(error(instantiation_error,lt/2))
          )
       ;  throw(error(instantiation_error,lt/2))
       ).
    
    vars_vars_needed([],    [],    []).
    vars_vars_needed([A|_], [],    [A]).
    vars_vars_needed([],    [B|_], [B]).
    vars_vars_needed([A|As],[B|Bs],[A|ABs]) :-
       (  A \== B
       -> ABs = [B]
       ;  vars_vars_needed(As,Bs,ABs)
       ).
    

    Some shared code:

    alpha_omega(Alpha,Omega) :-
        Alpha is -(10.0^1000),    % HACK!
        functor(Omega,z,255).     % HACK!
    
    label_vars([],_,_).
    label_vars([Alpha|Vs],Alpha,Omega) :- label_vars(Vs,Alpha,Omega).
    label_vars([Omega|Vs],Alpha,Omega) :- label_vars(Vs,Alpha,Omega).
    

提交回复
热议问题