set show timing off .

fmod FOO is
  sort Foo .
  op f : Foo -> Foo .
  vars X Y Z : Foo .
endfm

unify X =? f(f(Y)) /\ Y =? X  /\ Y =? f(X) .

unify X =? f(Y) /\ Y =? f(f(X)) /\  X =? Y .


fmod FOO2 is 
  sort Foo .
  op a : -> Foo .
  op f : Foo Foo -> Foo [assoc comm] .
  op g : Foo -> Foo .
vars A X Y : Foo .
endfm

unify  f(a, A) =? f(a, X) /\ f(a, Y) =? f(a, X)
/\     f(a, g(A)) =? f(a, g(X)) /\ f(a, g(Y)) =? f(a, g(X))
.

unify  f(a, Y) =? f(a, X)
/\     f(a, g(A)) =? f(a, g(X)) /\ f(a, g(Y)) =? f(a, g(X))
.


fmod FOO3 is 
  sort Foo .
  op a : -> Foo .
  op f : Foo Foo -> Foo [assoc comm] .
  op g : Foo -> Foo .
vars A B C D X Y Z : Foo .
endfm

unify  f(a, X) =? f(a, g(X)) /\ f(a, X) =? f(a, g(g(X))) .
unify Y =? X /\ f(a, X) =? f(a, g(Y)) /\ f(a, X) =? f(a, g(g(Y))) .


fmod FOO4 is
  sort Foo .
  op f : Foo Foo -> Foo [assoc comm] .
  ops a b c d e : -> Foo .
  vars W X Y Z : Foo .
endfm

unify  f(a, Y) =? f(a, X) .
unify f(X, a) =? f(X, a) .
unify f(a, b) =? f(a, b) .
unify f(X, Y) =? f(X, Y) .

