Unification with STO detection

前端 未结 5 1538
野的像风
野的像风 2021-02-06 22:26

In ISO Prolog unification is defined only for those cases that are NSTO (not subject to occurs-check). The idea behind is to cover those cases of unifications that are mostly u

5条回答
  •  野的像风
    2021-02-06 22:43

    Here is my version which I used to test against @gusbro's versions. The idea is to use Martelli-Montanari rather literally. By rewriting a list of equations [X1=Y1,X2=Y2|Etc], certain rewrite rules are applied immediately - using the ! for commitment. And for certain rules I was not that sure so I left them as non-determinate as the original algorithm.

    Remark that rewrite_sto/1 will either fail or produce an error. We are not interested in the success case, which is handled without any search. Also, remark that an equation that leads to (immediate) failure, can be eliminated! That's a bit unintuitive, but we are only interested here to find STO cases.

    unify_with_sto_check(X,Y) :-
       (  \+ unify_with_occurs_check(X, Y)
       -> rewrite_sto([X=Y])  % fails or error
       ;  X = Y
       ).
    
    rewrite_sto(Xs0) :-
       select(X=Y, Xs0,Xs),
       (  X == Y
       ;  nonvar(X), nonvar(Y),
          functor(X,F,A),
          \+ functor(Y,F,A)
       ;  var(X), var(Y),
          X = Y
       ),
       !,
       rewrite_sto(Xs).
    rewrite_sto(Xs0) :-
       select(X=Y, Xs0, Xs1),
       nonvar(X), nonvar(Y),
       functor(X,F,A),
       functor(Y,F,A),
       !,
       X =.. [_|XArgs],
       Y =.. [_|YArgs],
       maplist(\Xi^Yi^(Xi=Yi)^true, XArgs, YArgs, XYs),
       append(XYs,Xs1,Xs),
       rewrite_sto(Xs).
    rewrite_sto(Xs0) :-
       select(X=Y, Xs0,Xs),
       (  var(X), nonvar(Y) -> unify_var_term(X, Y)
       ;  nonvar(X), var(Y) -> unify_var_term(Y, X)
       ;  throw(impossible)
       ),
       rewrite_sto(Xs).
    
    unify_var_term(V, Term) :-
       (  unify_with_occurs_check(V, Term) -> true
       ;  throw(error(type_error(acyclic_term, Term), _))
       ).
    

提交回复
热议问题