set show timing off .
set show advisories off .

*** 7 unifiers for most trivial elementary AC problem
reduce in META-LEVEL :
  metaDisjointUnify(['NAT],
            '_+_['X:Nat, 'Y:Nat] =? '_+_['X:Nat, 'Y:Nat],
	    '#, 0) .

reduce in META-LEVEL :
  metaDisjointUnify(['NAT],
            '_+_['X:Nat, 'Y:Nat] =? '_+_['X:Nat, 'Y:Nat],
	    '#, 1) .

reduce in META-LEVEL :
  metaDisjointUnify(['NAT],
            '_+_['X:Nat, 'Y:Nat] =? '_+_['X:Nat, 'Y:Nat],
	    '#, 2) .

reduce in META-LEVEL :
  metaDisjointUnify(['NAT],
            '_+_['X:Nat, 'Y:Nat] =? '_+_['X:Nat, 'Y:Nat],
	    '#, 3) .

reduce in META-LEVEL :
  metaDisjointUnify(['NAT],
            '_+_['X:Nat, 'Y:Nat] =? '_+_['X:Nat, 'Y:Nat],
	    '#, 4) .

reduce in META-LEVEL :
  metaDisjointUnify(['NAT],
            '_+_['X:Nat, 'Y:Nat] =? '_+_['X:Nat, 'Y:Nat],
	    '#, 5) .

reduce in META-LEVEL :
  metaDisjointUnify(['NAT],
            '_+_['X:Nat, 'Y:Nat] =? '_+_['X:Nat, 'Y:Nat],
	    '#, 6) .

reduce in META-LEVEL :
  metaDisjointUnify(['NAT],
            '_+_['X:Nat, 'Y:Nat] =? '_+_['X:Nat, 'Y:Nat],
	    '#, 7) .

*** variable families '% and '@ are also supported
reduce in META-LEVEL :
  metaUnify(['NAT],
            '_+_['X:Nat, 'Y:Nat] =? '_+_['A:Nat, 'B:Nat],
	    '%, 0) .

reduce in META-LEVEL :
  metaUnify(['NAT],
            '_+_['X:Nat, 'Y:Nat] =? '_+_['A:Nat, 'B:Nat],
	    '@, 0) .

*** using variable families other than the one
*** declared by the the 3rd argument generates a warning and no
*** reduction.
reduce in META-LEVEL :
  metaUnify(['NAT],
            '_+_['X:Nat, 'Y:Nat] =? '_+_['#1:Nat, 'Y:Nat],
	    '%, 0) .

*** simultaneous unification
fmod BAZ is
   sort Foo .
   ops a b : -> Foo .
   op f : Foo -> Foo .
endfm

red in META-LEVEL :
metaDisjointUnify(['BAZ], 'f['X:Foo] =? 'f['Y:Foo] /\ 'f['X:Foo] =? 'f['Z:Foo], '#, 0) .

red in META-LEVEL :
metaDisjointUnify(['BAZ], 'f['Y:Foo] =? 'f['X:Foo] /\ 'f['Z:Foo] =? 'f['X:Foo], '#, 0) .

red in META-LEVEL :
metaDisjointUnify(['BAZ], 'f['X:Foo] =? 'f['Y:Foo] /\ 'f['Y:Foo] =? 'f['X:Foo], '#, 0) .

red in META-LEVEL :
metaDisjointUnify(['BAZ], 'f['X:Foo] =? 'f['a.Foo] /\ 'f['X:Foo] =? 'f['b.Foo], '#, 0) .

red in META-LEVEL :
metaDisjointUnify(['BAZ], 'f['a.Foo] =? 'f['X:Foo] /\ 'f['b.Foo] =? 'f['X:Foo], '#, 0) .

*** irredundant unification
fmod BAG is
  sorts Elt Bag .
  subsort Elt < Bag .
  op empty : -> Bag .
  op __ : Bag Bag -> Bag [assoc comm id: empty] .
endfm

reduce in META-LEVEL :
  metaIrredundantUnify(['BAG],
            '__['L:Bag, 'M:Bag] =? '__['P:Bag, 'Q:Bag],
	    '#, 0) .

reduce in META-LEVEL :
  metaIrredundantUnify(['BAG],
            '__['L:Bag, 'M:Bag] =? '__['P:Bag, 'Q:Bag],
	    '#, 1) .

reduce in META-LEVEL :
  metaIrredundantDisjointUnify(['BAG],
            '__['L:Bag, 'M:Bag] =? '__['P:Bag, 'Q:Bag],
	    '#, 0) .

reduce in META-LEVEL :
  metaIrredundantDisjointUnify(['BAG],
            '__['L:Bag, 'M:Bag] =? '__['P:Bag, 'Q:Bag],
	    '#, 1) .
