# TheoryBodies

body:
  sturmsquarefree: THEORY
  BEGIN

  IMPORTING reals@polynomials,reals@more_polynomial_props,reals@sign,
  	  polynomial_division,
            number_sign_changes,
            structures@more_list_props,ints@gcd,
  	  gcd_coeff,structures@sort_array	  

    a,r : VAR [nat->real]
    p : VAR [nat->[nat->real]]
    n : VAR [nat->nat]
    d,m,i,j,k : VAR nat
    x,y,c,b : VAR real

    sturm_sequence?(p,n,m): bool =
      LET P = (LAMBDA (k): polynomial(p(k),n(k))) IN
        (FORALL (i): i<m IMPLIES (n(i)>n(i+1) OR n(i+1)=0))  % Decreasing Degree
        AND (FORALL (i): i<=m IMPLIES p(i)(n(i))/=0)
        AND (FORALL (x): P(0)(x)=0 
               IMPLIES sign_ext(P(1)(x)) = 
  	       sign_ext(polynomial(poly_deriv(p(0)),max(n(0)-1,0))(x)))
        AND (FORALL (x,i): 0<i AND i<m AND P(i)(x)=0 IMPLIES
      	    sign_ext(P(i-1)(x)) = -sign_ext(P(i+1)(x)))
        AND (FORALL (x,y): sign_ext(P(m)(x)) = sign_ext(P(m)(y)))

    sturm_sequence_degree_1: LEMMA
      n(0)=1 AND n(1)=0 AND p(0)(1)/=0 AND p(1) = poly_deriv(p(0))
      IMPLIES
      sturm_sequence?(p,n,1)

    sturm_seq_repeated_root: LEMMA sturm_sequence?(p,n,m) IMPLIES
      FORALL (i:nat): i+1<=m AND
      polynomial(p(i),n(i))(x)=0 AND polynomial(p(i+1),n(i+1))(x)=0
      IMPLIES
      (FORALL (j:upto(m)): polynomial(p(j),n(j))(x) = 0)

    sturm_seq_last_nonzero: LEMMA
      m>0 AND
      sturm_sequence?(p,n,m) AND
      (FORALL (c:real): polynomial(p(0),n(0))(c)=0 IMPLIES
        polynomial(p(1),n(1))(c)/=0)
      IMPLIES
      FORALL (xyz:real): polynomial(p(m),n(m))(xyz)/=0

    sturm_sig(p,n,m)(x): nat = number_sign_changes(LAMBDA (i): polynomial(p(i),n(i))(x),m)`num

    % Part 1: Proving Sturm's Theorem when f has no multiple roots

    sturm_seq_first_signs_eq: LEMMA
      x<b AND b<y AND
      polynomial(p(0),n(0))(b)=0 AND
      (FORALL (c:real): x<=c AND c<=y AND polynomial(p(0),n(0))(c)=0 IMPLIES
        (polynomial(p(1),n(1))(c)/=0 AND c = b)) AND
      sturm_sequence?(p,n,m)
      IMPLIES
      (polynomial(p(0),n(0))(x)/=0 AND
       polynomial(p(0),n(0))(y)/=0 AND
       sign_ext(polynomial(p(0),n(0))(x)) = -sign_ext(polynomial(p(1),n(1))(b)) AND
       sign_ext(polynomial(p(0),n(0))(y)) = sign_ext(polynomial(p(1),n(1))(b)))

    sturm_lem_no_roots: LEMMA
      x<y AND
      (FORALL (c:real,i:nat): i<=m AND x<=c AND c<=y IMPLIES polynomial(p(i),n(i))(c)/=0) AND
      sturm_sequence?(p,n,m)
      IMPLIES
      sturm_sig(p,n,m)(x) = sturm_sig(p,n,m)(y)

    sturm_lem_one_root: LEMMA
      x<y AND x<b AND b<y AND
      (FORALL (c:real,i:nat): i<=m AND x<=c AND c<=y AND polynomial(p(i),n(i))(c)=0
       IMPLIES c = b) AND
      (FORALL (c:real): x<=c AND c<=y AND polynomial(p(0),n(0))(c)=0 IMPLIES
        (polynomial(p(1),n(1))(c)/=0))
      AND j<=m AND polynomial(p(j),n(j))(b)/=0 AND
      sturm_sequence?(p,n,m)
      IMPLIES
      LET nsc = LAMBDA (xyz:real,pj:nat): number_sign_changes(LAMBDA (i): polynomial(p(i),n(i))(xyz),pj) IN
        sign_ext(nsc(x,j)`lastnz) = sign_ext(nsc(y,j)`lastnz) AND
        nsc(x,j)`num = nsc(y,j)`num+(IF polynomial(p(0),n(0))(b)=0 THEN 1 ELSE 0 ENDIF)

    sturm_lem_edge_root: LEMMA
      x<y AND
      (FORALL (c:real,i:nat): i<=m AND x<=c AND c<=y AND polynomial(p(i),n(i))(c)=0
       IMPLIES c = y) AND
      (FORALL (c:real): x<=c AND c<=y AND polynomial(p(0),n(0))(c)=0 IMPLIES
        (polynomial(p(1),n(1))(c)/=0))
      AND j<=m AND polynomial(p(j),n(j))(y)/=0 AND
      sturm_sequence?(p,n,m) AND
      p(1) = poly_deriv(p(0)) AND n(1) = n(0)-1
      IMPLIES
      LET nsc = LAMBDA (xyz:real,pj:nat): number_sign_changes(LAMBDA (i): polynomial(p(i),n(i))(xyz),pj) IN
        sign_ext(nsc(x,j)`lastnz) = sign_ext(nsc(y,j)`lastnz) AND
        nsc(x,j)`num = nsc(y,j)`num+(IF polynomial(p(0),n(0))(y)=0 THEN 1 ELSE 0 ENDIF)

    roots_between_enum: LEMMA % THIS NEEDS TO BE FOR ALL P(i) NOT JUST P(0)
      x<y AND sturm_sequence?(p,n,m) IMPLIES
        EXISTS ((K:nat|K>=2),enum:[below(K)->real]):
          (FORALL (i,j:below(K)): i<j IMPLIES enum(i)<enum(j)) AND
    	enum(0)=x AND enum(K-1)=y AND
    	(FORALL (b:real,j:nat): j<=m AND x<b AND b<=y AND polynomial(p(j),n(j))(b)=0 IMPLIES
    	  EXISTS (i:below(K)): b = enum(i))

    sturm_lem_no_roots_full: LEMMA
      m>0 AND x<y AND
      (FORALL (c:real,i:nat): i<=m AND x<c AND c<=y IMPLIES polynomial(p(i),n(i))(c)/=0) AND
      sturm_sequence?(p,n,m) AND
      (FORALL (c:real): polynomial(p(0),n(0))(c)=0 IMPLIES
        polynomial(p(1),n(1))(c)/=0) AND
      p(1) = poly_deriv(p(0)) AND n(1) = n(0)-1
      IMPLIES
      sturm_sig(p,n,m)(x) = sturm_sig(p,n,m)(y)

    sturm_square_free: LEMMA
      m>0 AND x<y AND (EXISTS (i:upto(n(0))): p(0)(i)/=0) AND
      (FORALL (c:real): polynomial(p(0),n(0))(c)=0 IMPLIES
        (polynomial(p(1),n(1))(c)/=0)) AND
      sturm_sequence?(p,n,m) AND
      p(1) = poly_deriv(p(0)) AND n(1) = n(0)-1
      IMPLIES
        LET nsc = LAMBDA (xyz:real): number_sign_changes(LAMBDA (i): polynomial(p(i),n(i))(xyz),m),
        	  Nroots = nsc(x)`num-nsc(y)`num
        IN Nroots>=0 AND EXISTS (bij: [below(Nroots)->{xr:real|x<xr AND xr<=y AND polynomial(p(0),n(0))(xr)=0}]):
             bijective?(bij)

    sturm_seq_square_free: LEMMA
      (m>0 AND n(m)=0 AND (FORALL (i:below(m)): p(i)(n(i))/=0) AND
      (FORALL (i,j:upto(m)): i<j IMPLIES n(i)>n(j)) AND
      (FORALL (c:real): polynomial(p(0),n(0))(c)=0 IMPLIES
        (polynomial(p(1),n(1))(c)/=0)) AND
      p(1) = poly_deriv(p(0)) AND n(1) = n(0)-1 AND
      (FORALL (j:nat): j>1 AND j<=m IMPLIES LET pd = poly_divide(p(j-2),n(j-2))(p(j-1),n(j-1))(0) IN
      	   	    	    	 	   EXISTS (c:posreal): 
      	   	    	    	 	   polynomial(p(j),n(j)) = 
  					   polynomial(-c*pd`rem,pd`rdeg)))
      IMPLIES
        (p(m)(0)/=0 AND sturm_sequence?(p,n,m)) OR
        (p(m)(0) =0 AND sturm_sequence?(p,n,m-1))

  END sturmsquarefree

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 22, column 45) for  max(n(0) - 1, 0)
      % expected type  nat
  sturm_sequence?_TCC1: OBLIGATION
    FORALL (p: [nat -> [nat -> real]], n: [nat -> nat], m: nat,
            P: [nat -> [real -> real]]):
      ((FORALL (i): i <= m IMPLIES p(i)(n(i)) /= 0) AND
        (FORALL (i): i < m IMPLIES (n(i) > n(i + 1) OR n(i + 1) = 0)) AND
         P = (LAMBDA (k): polynomial(p(k), n(k))))
       IMPLIES (FORALL (x: real): P(0)(x) = 0 IMPLIES max(n(0) - 1, 0) >= 0);

  % Subtype TCC generated (at line 24, column 20) for  i - 1
      % expected type  nat
  sturm_sequence?_TCC2: OBLIGATION
    FORALL (p: [nat -> [nat -> real]], n: [nat -> nat], m: nat,
            P: [nat -> [real -> real]]):
      ((FORALL (x):
          P(0)(x) = 0 IMPLIES
           sign_ext(P(1)(x)) =
            sign_ext(polynomial(poly_deriv(p(0)), max(n(0) - 1, 0))(x)))
        AND
        (FORALL (i): i <= m IMPLIES p(i)(n(i)) /= 0) AND
         (FORALL (i): i < m IMPLIES (n(i) > n(i + 1) OR n(i + 1) = 0)) AND
          P = (LAMBDA (k): polynomial(p(k), n(k))))
       IMPLIES
       (FORALL (x1: real, i1: nat):
          0 < i1 AND i1 < m AND P(i1)(x1) = 0 IMPLIES i1 - 1 >= 0);

  % Subtype TCC generated (at line 100, column 8) for  0
      % expected type  below(K)
  roots_between_enum_TCC1: OBLIGATION
    FORALL (m: nat, n: [nat -> nat], p: [nat -> [nat -> real]], x, y: real):
      sturm_sequence?(p, n, m) AND x < y IMPLIES
       (FORALL ((K: nat | K >= 2), enum: [below(K) -> real]):
          (FORALL (i, j: below(K)): i < j IMPLIES enum(i) < enum(j)) IMPLIES
           0 < K);

  % Subtype TCC generated (at line 100, column 22) for  K - 1
      % expected type  below(K)
  roots_between_enum_TCC2: OBLIGATION
    FORALL (m: nat, n: [nat -> nat], p: [nat -> [nat -> real]], x, y: real):
      sturm_sequence?(p, n, m) AND x < y IMPLIES
       (FORALL ((K: nat | K >= 2), enum: [below(K) -> real]):
          enum(0) = x AND
           (FORALL (i, j: below(K)): i < j IMPLIES enum(i) < enum(j))
           IMPLIES K - 1 >= 0 AND K - 1 < K);

  % Subtype TCC generated (at line 132, column 80) for  j - 1
      % expected type  nat
  sturm_seq_square_free_TCC1: OBLIGATION
    FORALL (m: nat, n: [nat -> nat], p: [nat -> [nat -> real]]):
           m > 0 AND n(m) = 0 AND FORALL (i: below(m)): p(i)(n(i)) /= 0
       AND FORALL (i, j: upto(m)): i < j IMPLIES n(i) > n(j)
       AND FORALL (c: real):
             polynomial(p(0), n(0))(c) = 0 IMPLIES
              (polynomial(p(1), n(1))(c) /= 0)
       AND p(1) = poly_deriv(p(0)) AND n(1) = n(0) - 1
       IMPLIES (FORALL (j1: nat): j1 > 1 AND j1 <= m IMPLIES j1 - 1 >= 0);

  % Subtype TCC generated (at line 132, column 85) for  n(j - 1)
      % expected type  {m | p(j - 1)(m) /= 0}
  sturm_seq_square_free_TCC2: OBLIGATION
    FORALL (m: nat, n: [nat -> nat], p: [nat -> [nat -> real]]):
           m > 0 AND n(m) = 0 AND FORALL (i: below(m)): p(i)(n(i)) /= 0
       AND FORALL (i, j: upto(m)): i < j IMPLIES n(i) > n(j)
       AND FORALL (c: real):
             polynomial(p(0), n(0))(c) = 0 IMPLIES
              (polynomial(p(1), n(1))(c) /= 0)
       AND p(1) = poly_deriv(p(0)) AND n(1) = n(0) - 1
       IMPLIES
       (FORALL (j1: nat):
          j1 > 1 AND j1 <= m IMPLIES p(j1 - 1)(n(j1 - 1)) /= 0);

  % Subtype TCC generated (at line 132, column 65) for  j - 2
      % expected type  nat
  sturm_seq_square_free_TCC3: OBLIGATION
    FORALL (m: nat, n: [nat -> nat], p: [nat -> [nat -> real]]):
           m > 0 AND n(m) = 0 AND FORALL (i: below(m)): p(i)(n(i)) /= 0
       AND FORALL (i, j: upto(m)): i < j IMPLIES n(i) > n(j)
       AND FORALL (c: real):
             polynomial(p(0), n(0))(c) = 0 IMPLIES
              (polynomial(p(1), n(1))(c) /= 0)
       AND p(1) = poly_deriv(p(0)) AND n(1) = n(0) - 1
       IMPLIES (FORALL (j1: nat): j1 > 1 AND j1 <= m IMPLIES j1 - 2 >= 0);

  % Subtype TCC generated (at line 138, column 42) for  m - 1
      % expected type  nat
  sturm_seq_square_free_TCC4: OBLIGATION
    FORALL (m: nat, n: [nat -> nat], p: [nat -> [nat -> real]]):
           FORALL (j: nat):
             j > 1 AND j <= m IMPLIES
              LET pd = poly_divide(p(j - 2), n(j - 2))(p(j - 1), n(j - 1))(0)
                IN
                EXISTS (c: posreal):
                  polynomial(p(j), n(j)) = polynomial(-c * pd`rem, pd`rdeg)
       AND n(1) = n(0) - 1 AND p(1) = poly_deriv(p(0))
       AND FORALL (c: real):
             polynomial(p(0), n(0))(c) = 0 IMPLIES
              (polynomial(p(1), n(1))(c) /= 0)
       AND FORALL (i, j: upto(m)): i < j IMPLIES n(i) > n(j)
       AND FORALL (i: below(m)): p(i)(n(i)) /= 0 AND n(m) = 0 AND m > 0
       AND NOT (p(m)(0) /= 0 AND sturm_sequence?(p, n, m)) AND p(m)(0) = 0
       IMPLIES m - 1 >= 0;


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Ana Cristina Rocha Oliveira, Andre Galdino and Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil         
  %% Orthogonality theory formalizing confluence of orthogonal rewriting systems
  %% subtheories mem_test and mem_tes2 specify properties between finite sequences
  %% and associated sets that are necessary for dealing adequately with sequences
  %% of positions, rules and substitutions involved in parallel rewriting steps.
  %% The theory orthogonality is the main one.
  %%
  %% Last Modified On: June 28, 2013                                    
  %%                                                                          
  %%--------------------------------------------------------------------------

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %% mem_test is an auxiliary theory formalising properties related with length and
  %% cardinality and membership of elements in finite_sequences and associated sets.
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  mem_test[T: TYPE] : THEORY
  BEGIN
         IMPORTING   structures@seq_extras[T],
                     structures@seq2set[T]

                x : VAR T
   seq, seq1, seq2: VAR finseq[T]
                E : VAR set[T]
                n : VAR nat
                P : VAR [[T, T] -> bool]
               P1 : VAR [[nat, T] -> bool]
       
   member_seq(x, seq): bool =
       EXISTS(i:below[seq`length]): x = seq(i)

   subseq(seq1, seq2): bool =
       FORALL(i:below[seq1`length]): member_seq(seq1(i),seq2)

    member(seq, E): bool = FORALL(i:below[seq`length]):
                           member(seq`seq(i),E)

    power(x,n): finseq[T] =
       (# length := n,
             seq := (LAMBDA(i:below[n]): x) #)

   member_seq_in_seq2set: LEMMA
      member_seq(x, seq) IFF seq2set(seq)(x)

   subseq_rest: LEMMA
      subseq(seq1, rest(seq2)) IMPLIES subseq(seq1, seq2)

   seq2set_comp: LEMMA
      seq2set(seq1 o seq2)(x)
      IFF seq2set(seq1)(x) OR seq2set(seq2)(x)

    seq_construct: LEMMA
      seq1`length = n &
      seq2`length = n &
      (FORALL (i:below[n]):
        EXISTS x: P(seq1`seq(i), x) & 
                  P(seq2`seq(i), x))
      IMPLIES EXISTS seq: seq`length = n &
        FORALL (i:below[n]):
                P(seq1`seq(i), seq`seq(i)) & 
                P(seq2`seq(i), seq`seq(i))

    seq_construct2: LEMMA
      (FORALL (i:below[n]):
        EXISTS x: P1(i, x))
      IMPLIES EXISTS seq: seq`length = n &
        FORALL (i:below[n]):
                P1(i, seq`seq(i))

  END mem_test

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 58, column 27) for  i
      % expected type  below[seq1`length]
  seq_construct_TCC1: OBLIGATION
    FORALL (n: nat, seq1, seq2: finseq[T]):
      seq1`length = n AND seq2`length = n IMPLIES
       (FORALL (i: below[n], x): i < seq1`length);

  % Subtype TCC generated (at line 59, column 27) for  i
      % expected type  below[seq2`length]
  seq_construct_TCC2: OBLIGATION
    FORALL (P: [[T, T] -> bool], n: nat, seq1, seq2: finseq[T]):
      seq1`length = n AND seq2`length = n IMPLIES
       (FORALL (i: below[n], x): P(seq1`seq(i), x) IMPLIES i < seq2`length);

  % Subtype TCC generated (at line 62, column 25) for  i
      % expected type  below[seq1`length]
  seq_construct_TCC3: OBLIGATION
    FORALL (P: [[T, T] -> bool], n: nat, seq1, seq2: finseq[T]):
      (FORALL (i: below[n]): EXISTS x: P(seq1`seq(i), x) & P(seq2`seq(i), x))
       AND seq2`length = n AND seq1`length = n
       IMPLIES
       (FORALL (seq):
          seq`length = n IMPLIES (FORALL (i1: below[n]): i1 < seq1`length));

  % Subtype TCC generated (at line 62, column 37) for  i
      % expected type  below[seq`length]
  seq_construct_TCC4: OBLIGATION
    FORALL (P: [[T, T] -> bool], n: nat, seq1, seq2: finseq[T]):
      (FORALL (i: below[n]): EXISTS x: P(seq1`seq(i), x) & P(seq2`seq(i), x))
       AND seq2`length = n AND seq1`length = n
       IMPLIES
       (FORALL (seq):
          seq`length = n IMPLIES (FORALL (i1: below[n]): i1 < seq`length));

  % Subtype TCC generated (at line 63, column 25) for  i
      % expected type  below[seq2`length]
  seq_construct_TCC5: OBLIGATION
    FORALL (P: [[T, T] -> bool], n: nat, seq1, seq2: finseq[T]):
      (FORALL (i: below[n]): EXISTS x: P(seq1`seq(i), x) & P(seq2`seq(i), x))
       AND seq2`length = n AND seq1`length = n
       IMPLIES
       (FORALL (seq):
          seq`length = n IMPLIES
           (FORALL (i1: below[n]):
              P(seq1`seq(i1), seq`seq(i1)) IMPLIES i1 < seq2`length));

  % Subtype TCC generated (at line 70, column 28) for  i
      % expected type  below[seq`length]
  seq_construct2_TCC1: OBLIGATION
    FORALL (P1: [[nat, T] -> bool], n: nat):
      (FORALL (i: below[n]): EXISTS x: P1(i, x)) IMPLIES
       (FORALL (seq):
          seq`length = n IMPLIES (FORALL (i1: below[n]): i1 < seq`length));


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%                   
  %% Last Modified On: March 24, 2008                                      
  %%                                                                          
  %%----------------------------------------------------------------------------


  extending_rename[T:TYPE]: THEORY
   BEGIN

   
    S, R: VAR set[T]
       t: VAR T

    extend_to_identity((S),(R),(f:(bijective?[(S),(R)])))(t): T = 
          IF S(t) THEN f(t)
          ELSE 
            t 
          ENDIF

   END extending_rename


body:
  %%-------------------** Abstract Reduction System (ARS) **-------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%              
  %% Last Modified On: December 02, 2006                                      
  %%                                                                          
  %%---------------------------------------------------------------------------


  %%---------------------------------------------------------------------------
  %%
  %% We defined reflexive, symmetric, transitive, reflexive and transitive, 
  %% and equivalence closures of a binary relation in the same way that 
  %% Alfons Geser defined in .../lib/../closure_ops.pvs. We just changed
  %% the names of the definitions and we proved some additional properties.
  %%                                                                          
  %%---------------------------------------------------------------------------



  relations_closure[T : TYPE] : THEORY
  BEGIN


   IMPORTING
      orders@closure_ops[T],
      sets_lemmas[T]

     S, R: VAR pred[[T, T]]
     n: VAR nat
     p: VAR posnat


     reflexive: TYPE = (reflexive?)

     symmetric: TYPE = (symmetric?)

     transitive: TYPE = (transitive?)

     reflexive_transitive?(R): bool = reflexive?(R) & transitive?(R)

     reflexive_transitive: TYPE = (reflexive_transitive?)

     equivalence: TYPE = (equivalence?)



  % % Reflexive Closure (RC)

      RC(R): reflexive = union(R, =)


  % %% Properties

     change_to_RC : LEMMA reflexive_closure(R) = RC(R) 

     R_subset_RC : LEMMA subset?(R, RC(R))

     RC_idempotent : LEMMA  RC(RC(R)) = RC(R)

     RC_characterization : LEMMA  reflexive?(S) <=> (S = RC(S))



  % % Symmetric Closure (SC)

      SC(R): symmetric = union(R, converse(R))


  % %% Properties

     change_to_SC : LEMMA symmetric_closure(R) = SC(R)

     R_subset_SC : LEMMA subset?(R, SC(R))

     SC_idempotent : LEMMA  SC(SC(R)) = SC(R)

     SC_characterization : LEMMA  symmetric?(S) <=> (S = SC(S))

   

  % % Transitive Closure (TC)

      TC(R): transitive = IUnion(LAMBDA p: iterate(R, p))


  % %% Properties

     change_to_TC : LEMMA transitive_closure(R) = TC(R)

     R_subset_TC :LEMMA subset?(R, TC(R))

     TC_converse: LEMMA  TC(converse(R)) = converse(TC(R))

     TC_idempotent : LEMMA  TC(TC(R)) = TC(R)

     TC_characterization : LEMMA  transitive?(S) <=> (S = TC(S))

     

  % % Reflexive Transitive Closure (RTC)

     RTC(R): reflexive_transitive = IUnion(LAMBDA n: iterate(R, n)) 


  % %% Properties

     change_to_RTC : LEMMA preorder_closure(R) = RTC(R)

     R_subset_RTC: LEMMA subset?(R, RTC(R))

     iterate_RTC: LEMMA FORALL n : subset?(iterate(R, n), RTC(R))

     RTC_idempotent : LEMMA  RTC(RTC(R)) = RTC(R)

     RTC_characterization : LEMMA reflexive_transitive?(S) <=> (S = RTC(S))



  % % Equivalence Closure (EC)

      EC(R): equivalence = RTC(SC(R))


  % %% Properties

      change_to_EC : LEMMA equivalence_closure(R) = EC(R)  

      R_subset_EC: LEMMA subset?(R, EC(R))

      RTC_subset_EC: LEMMA subset?(RTC(R), EC(R))

      EC_idempotent : LEMMA  EC(EC(R)) = EC(R)

      EC_characterization : LEMMA  equivalence?(S) <=> (S = EC(S))


  END relations_closure

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 56, column 23) for  union(R, =)
      % expected type  reflexive
  RC_TCC1: OBLIGATION
    FORALL (R: pred[[T, T]]): reflexive?[T](union[[T, T]](R, =));

  % Subtype TCC generated (at line 73, column 23) for  union(R, converse(R))
      % expected type  symmetric
  SC_TCC1: OBLIGATION
    FORALL (R: pred[[T, T]]):
      symmetric?[T](union[[T, T]](R, converse[T, T](R)));

  % Subtype TCC generated (at line 90, column 24) for
      % IUnion(LAMBDA p: iterate(R, p))
      % expected type  transitive
  TC_TCC1: OBLIGATION
    FORALL (R: pred[[T, T]]):
      transitive?[T](IUnion[posnat, [T, T]](LAMBDA p: iterate[T](R, p)));

  % Subtype TCC generated (at line 109, column 34) for
      % IUnion(LAMBDA n: iterate(R, n))
      % expected type  reflexive_transitive
  RTC_TCC1: OBLIGATION
    FORALL (R: pred[[T, T]]):
      reflexive_transitive?(IUnion[nat, [T, T]](LAMBDA n: iterate[T](R, n)));

  % Subtype TCC generated (at line 128, column 25) for  RTC(SC(R))
      % expected type  equivalence
  EC_TCC1: OBLIGATION FORALL (R: pred[[T, T]]): equivalence?[T](RTC(SC(R)));


body:
  %%-------------------** Abstract Reduction System (ARS) **-------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%              
  %% Last Modified On: December 02, 2006                                      
  %%                                                                          
  %%---------------------------------------------------------------------------


  %%----------------------------** Notations **--------------------------------
  %%
  %% These concepts can be found in the file relations_closure
  %%
  %% The binary relation R on the set T is defined as predicate
  %% PRED: TYPE = [[T,T] -> bool]
  %%
  %% RC(R) : Reflexive Closure of R            ( ->= )
  %% SC(R) : Symmetric Closure of R            ( <-> )
  %% TC(R) : Transitive Closure of R           ( ->+ )
  %% RTC(R): Reflexive Transitive Closure of R ( ->* )
  %% EC(R) : Equivalence Closure of R          ( <->*)
  %%
  %%---------------------------------------------------------------------------


  %%----------------------------** Reductions **-------------------------------
  %%
  %% An ARS is a pair (T,->), where the reduction -> is a binary relation on 
  %% the set T, noted by R. So the relation R(x,y) means x reduces to y, and
  %% y is called a reduct of x.
  %%
  %%--------------------------------------------------------------------------


  ars_terminology[T : TYPE] : THEORY
  BEGIN

    IMPORTING relations_closure[T]
    
     R, R1, R2 : VAR PRED[[T, T]]
    x, y, z, r : VAR T


  %%-----------------------** Some Terminology **------------------------------
  %%
  %% - x is reducible iff there is a y such that  x -> y
  %%
  %% - y is a reduct of x iff x -> y
  %%
  %% - x is in normal form iff it is not reducible
  %%
  %% - y is a normal form of x iff x ->* y and y is in normal form
  %%
  %% - normalizing iff every elememt has a normal form
  %%
  %% - has_unique_nf(R,x) means x has a unique normal form w.r.t. R 
  %%
  %% - unique_nf?(R)(x,y) means y is the unique normal form of x  w.r.t. R
  %%
  %% - y is a direct successor of x iff x -> y
  %%                               
  %% - y is a successor of x iff x ->+ y
  %%
  %% - x and y are joinable iff there is a z such that x ->* z *<- y
  %%
  %%---------------------------------------------------------------------------


   reducible?(R)(x): bool = EXISTS y: R(x,y)

   reduct?(R)(x): PRED[T] = {y: T | RTC(R)(x, y)}

   is_normal_form?(R)(x): bool = NOT reducible?(R)(x)

   normal_form?(R)(x,y): bool = RTC(R)(x,y) & is_normal_form?(R)(y)

   normalizing?(R): bool = FORALL x: EXISTS y: normal_form?(R)(x,y)

   has_unique_nf?(R,x): bool = EXISTS y: normal_form?(R)(x,y) 
                                   &  FORALL z: normal_form?(R)(x,z)  => y = z

   unique_nf?(R)(x,y): bool = normal_form?(R)(x,y) 
                                   &  FORALL z: normal_form?(R)(x,z)  => y = z

   direct_successor?(R)(x,y): bool = R(x,y)

   successor?(R)(x,y): bool = TC(R)(x,y)

   joinable?(R)(x,y): bool = EXISTS z: RTC(R)(x,z) & RTC(R)(y, z)






  %%-------------------------** Notions of Confluence **----------------------
  %%
  %% A reduction -> (relation R) is
  %%
  %% - Church-Rosser (CR) iff x <->* y implies x and y are joinable.
  %%
  %% - locally confluent iff  y <- x -> z implies y and z are joinable.
  %%
  %% - semi-confluent iff y <- x ->* z implies y and z are joinable.
  %%
  %% - strongly confluent iff y <- x -> z implies exists r such that
  %%   y ->* r =<- z.
  %%
  %% - has the diamond property iff y <- x -> z implies exists r such that
  %%   y -> r <- z.
  %%
  %%--------------------------------------------------------------------------


   church_rosser?(R): bool = FORALL x, y: EC(R)(x,y) => joinable?(R)(x,y)

   locally_confluent?(R): bool = FORALL x, y, z: R(x,y) & R(x,z) => 
                                                        joinable?(R)(y,z)

   semi_confluent?(R): bool = FORALL x, y, z: R(x,y) & RTC(R)(x,z) => 
                                                       joinable?(R)(y,z)

   confluent?(R): bool = FORALL x, y, z: RTC(R)(x,y) & RTC(R)(x,z) => 
                                                       joinable?(R)(y,z)
   
   strong_confluent?(R): bool = FORALL x, y, z: R(x,y) & R(x,z) => 
                                            EXISTS r: RTC(R)(y,r) & RC(R)(z,r)
   
   diamond_property?(R): bool = FORALL x, y, z: R(x,y) & R(x,z) => 
                                                     EXISTS r: R(y,r) & R(z,r)




  %%---------------------------** Commutation **-------------------------------
  %%
  %% The relations -> and -->
  %%
  %% - commute iff y *<- x -->* z implies exists r such that
  %%   y -->* r *<- z
  %%
  %% - strongly commute iff y <- x --> z implies exists r such that
  %%   y -->= r *<- z
  %%
  %% - locally commute iff  y <- x --> z implies exists r such that
  %%   y -->* r *<- z
  %%
  %% - have the commuting diamond property iff
  %%   y <- x --> z implies exists r such that y --> r <- z
  %%
  %%--------------------------------------------------------------------------


   commute?(R1,R2): bool = FORALL x, y, z: RTC(R1)(x,y) & RTC(R2)(x,z) =>
                                          EXISTS r: RTC(R2)(y,r) & RTC(R1)(z,r)

   strong_commute?(R1,R2): bool = FORALL x, y, z: R1(x,y) & R2(x,z) =>
                                            EXISTS r: RC(R2)(y,r) & RTC(R1)(z,r)


   locally_commute?(R1,R2): bool = FORALL x, y, z: R1(x,y) & R2(x,z) =>
                                            EXISTS r: RTC(R2)(y,r) & RTC(R1)(z,r)


   commute_DP?(R1,R2): bool = FORALL x, y, z: R1(x,y) & R2(x,z) =>
                                                    EXISTS r: R2(y,r) & R1(z,r)





  end ars_terminology


body:
  %%-------------------** Abstract Reduction System (ARS) **-------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%              
  %% Last Modified On: December 02, 2006                                      
  %%                                                                          
  %%---------------------------------------------------------------------------


  noetherian[T : TYPE] : THEORY
  BEGIN

    IMPORTING ars_terminology[T], 
              orders@well_foundedness[T]
    
       P : VAR PRED[T]
       R : VAR PRED[[T, T]]
    x, y : VAR T


  %%------------------------** Termination (Noetherian) **--------------------
  %%
  %% A reduction -> (relation R) is
  %%
  %% - noetherian (terminating) iff there is no infinite
  %%   descending  chain a0 -> a1 -> .... In other words, a relation -> is 
  %%   noetherian if the inverse (converse) relation of -> is well founded.
  %%
  %% - convergent if is confluent and noetherian.
  %%
  %% - R_is_Noet_iff_TC_is: ->+ is terminating iff -> is.
  %%
  %%
  %% - noetherian_induction: To prove P(x) for all x, it suffices to prove P(x)
  %%                         under the assunption that P(y) holds for all 
  %%                         successors y of x. 
  %%
  %%--------------------------------------------------------------------------

   
   noetherian?(R): bool = well_founded?(converse(R))


   noetherian: TYPE = (noetherian?)


   convergent?(R): bool = confluent?(R) & noetherian?(R)


   R_is_Noet_iff_TC_is: LEMMA noetherian?(R) <=> noetherian?(TC(R))
   

   noetherian_induction: LEMMA 
               (FORALL (R: noetherian, P):
                 (FORALL x: 
                    (FORALL y: TC(R)(x, y) IMPLIES P(y)) 
                        IMPLIES P(x))
              IMPLIES
                (FORALL x: P(x)))


  END noetherian


body:
  %%-------------------** Abstract Reduction System (ARS) **-------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%           
  %% Last Modified On: December 02, 2006                                      
  %%                                                                          
  %%---------------------------------------------------------------------------



  results_confluence[T : TYPE] : THEORY
  BEGIN

    IMPORTING ars_terminology[T]
              

    
     R, R1, R2 : VAR PRED[[T, T]]
    x, y, z, r : VAR T


  %%---------------------** Basic Results: Confluence **------------------------
  %%
  %%
  %% - reduct_transitive: If x -> y and y and z are joinable then
  %%                      x and z are joinable.
  %%
  %%
  %% - semi_and_iterate: If -> is semi-confluent and x <->* y (see definition
  %%                     of <->* in the file relations_closure) then x and y
  %%                     are joinable.
  %%
  %%
  %% - Confl_implies_Semi, Semi_implies_CR, and CR_implies_Confl: Show that 
  %%
  %%         -> is CR  iff  -> is confluent  iff  -> is semi-confluent.
  %%
  %%
  %% - strong_and_iterate: If -> is strongly confluent and y <- x ->* z then
  %%                       exists r such that y ->* r =<- z. 
  %%
  %%   In other words,
  %%
  %%  i) strongly confluent implies semi-confluent: Str_Confl_implies_Semi_Confl.
  %%
  %% ii) strongly confluent implies confluent: Strong_Confl_implies_Confl.
  %%
  %%
  %% - DP_implies_StC: If -> has the diamond property then -> is strongly 
  %%                   confluent.
  %%
  %%
  %% - R1_Confl_implies_R2_Confl: If ->* = -->* then -> is confluent iff
  %%                              --> is confluent.
  %%
  %%
  %% - R1_equal_R2: If -> contained in -->, and --> contained in ->* then
  %%                ->* = -->*.
  %%
  %%
  %% - R2_Str_Confl_implies_R1_Confl: If -> contained in -->, and --> 
  %%                                  contained in ->* and --> is strongly 
  %%                                  confluent then -> is confluent.
  %%
  %%
  %% - Confluence_Commute: If -> and --> are confluent and commute, then
  %%                       ->* o -->* has the diamond property.
  %%
  %%
  %% - R1_R2_RTC_R1_R2: For arbitrary -> and --> we have
  %%                    (-> union -->) contained in (->* o -->*) and
  %%                     (->* o -->*) contained in (-> union -->)*.
  %%
  %%
  %% - Commutative_Union_Lemma: This lemma tells us that in certain cases union
  %%                            preserves confluence. In other words,
  %%                            If -> and --> are confluent and commute, then
  %%                            -> o --> is also confluent.
  %%
  %%
  %%---------------------------------------------------------------------------


   Joinable_implies_Equiv: LEMMA joinable?(R)(x,y) =>  EC(R)(x,y)


   reduct_transitive: LEMMA R(x,y) & joinable?(R)(y,z) => joinable?(R)(x,z)


   semi_and_iterate: LEMMA FORALL (n: nat): semi_confluent?(R) & 
                                            iterate(SC(R), n)(x,y) => 
                                                             joinable?(R)(x,y)


   Confl_implies_Semi: THEOREM confluent?(R) => semi_confluent?(R)


   Semi_implies_CR: THEOREM semi_confluent?(R) => church_rosser?(R)



   CR_iff_Confluent: THEOREM church_rosser?(R) <=> confluent?(R)
   


   strong_and_iterate: LEMMA FORALL (n: nat): strong_confluent?(R) & R(x,y)
                                     &  iterate(R, n)(x, z) =>
                                          EXISTS r: RTC(R)(y,r) & RC(R)(z, r)
    

   Str_Confl_implies_Semi_Confl: THEOREM strong_confluent?(R)
                                                          => semi_confluent?(R)


   Strong_Confl_implies_Confl: COROLLARY strong_confluent?(R) => confluent?(R)


   DP_implies_StC: LEMMA diamond_property?(R) => strong_confluent?(R)


   R1_Confl_iff_R2_Confl: LEMMA RTC(R1) = RTC(R2) => 
                                          ( confluent?(R1) <=> confluent?(R2) )


   R1_equal_R2: LEMMA subset?(R1,R2) & subset?(R2,RTC(R1)) => RTC(R1) = RTC(R2)
   

   R2_Str_Confl_implies_R1_Confl: COROLLARY subset?(R1, R2) 
                                      & subset?(R2, RTC(R1))
                                      & strong_confluent?(R2) => confluent?(R1)


   Confluence_Commute: THEOREM confluent?(R1) & confluent?(R2) & commute?(R1,R2)
                                         => diamond_property?(RTC(R1) o RTC(R2))

   
   R1_R2_RTC_R1_R2: LEMMA subset?(union(R1, R2), RTC(R1) o RTC(R2)) & 
                          subset?(RTC(R1) o RTC(R2), RTC(union(R1, R2)))


   Commutative_Union_Lemma: THEOREM confluent?(R1) & confluent?(R2) &
                                 commute?(R1,R2) => confluent?(union(R1, R2))



  end results_confluence


body:
  %%-------------------** Abstract Reduction System (ARS) **-------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%            
  %% Last Modified On: December 02, 2006                                      
  %%                                                                          
  %%---------------------------------------------------------------------------


  newman_yokouchi[T : TYPE] : THEORY
  BEGIN

    IMPORTING results_confluence[T],
              noetherian[T]
    

       R, S : VAR PRED[[T, T]]
    x, y, z : VAR T


  %%----------------------** Newman and Yokouchi's Lemmas **--------------------%%


   Newman_lemma: THEOREM noetherian?(R) => (confluent?(R) <=> locally_confluent?(R))


   Yokouchi_lemma_ax1: LEMMA ( noetherian?(R) & confluent?(R) &
                  (FORALL x, y, z: ( S(x,y) & R(x,z) ) => 
                   ( EXISTS (u: T): RTC(R)(y,u) & (RTC(R) o S o RTC(R))(z,u) ))) 
                  => (FORALL x, y, z: ( S(x,y) & RTC(R)(x,z) ) => 
                     ( EXISTS (w: T): RTC(R)(y,w) & (RTC(R) o S o RTC(R))(z,w) ))

   
   Yokouchi_lemma: THEOREM (noetherian?(R) & confluent?(R) & diamond_property?(S)
                   & (FORALL x, y, z: ( S(x,y) & R(x,z) ) => 
                   ( EXISTS (u: T): RTC(R)(y,u) & (RTC(R) o S o RTC(R))(z,u) ))) 
                    => diamond_property?(RTC(R) o S o RTC(R))



  end newman_yokouchi


body:
  %%-------------------** Abstract Reduction System (ARS) **-------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%              
  %% Last Modified On: December 02, 2006                                      
  %%                                                                          
  %%---------------------------------------------------------------------------


  results_normal_form[T : TYPE] : THEORY
  BEGIN

    IMPORTING results_confluence[T],
              noetherian[T]
    
             R : VAR PRED[[T, T]]
    x, y, u, v : VAR T



  %%--------------------** Basic Results: Normal Form **------------------------
  %%
  %%
  %% - NF_doesnot_rewrite: If x is in normal form and x ->* y then x = y.
  %%
  %%
  %%%% If -> is confluent and x <->* y then
  %%
  %% - NF_implies_RTC: x ->* y if y is in normal form,
  %%
  %% - NFs_implies_Equal: x = y if both x and y are in normal form.
  %%
  %%
  %% - Norm_and_Confl_implies_UNF_NF: If -> is normalizing and confluent, 
  %%                                  every element has a unique normal form.
  %%
  %%
  %%%% If x has a unique normal form, the latter is denoted by x|
  %%
  %% - Normalizing_and_Confl: If -> is normalizing and confluent then x <->* y
  %%                          iff x| = y|.
  %%
  %%
  %% - Normal_Confl_iff_UNF:  -> is normalizing and confluent iff 
  %%                          every element has a unique normal form.
  %%
  %%
  %% - Noetherian_implies_normalizing: Any terminating relation is normalizing.
  %%
  %%
  %% - Convergent_UF: If -> is convergent, then every element has a unique 
  %%                  normal form.
  %%
  %%
  %% - Noet_and_Confl_iff_UNF: If -> is terminating, then -> is confluent iff
  %%                           every element has a unique normal form.
  %%
  %%
  %% - Convergent_iff_eqNF: If -> is convergent, then x <->* y iff x| = y|.
  %%
  %%
  %%---------------------------------------------------------------------------


   NF_doesnot_rewrite: LEMMA ( is_normal_form?(R)(x) & RTC(R)(x,y) => x = y )


   NF_implies_RTC: LEMMA ( confluent?(R) & EC(R)(x,y) ) => 
                                      (is_normal_form?(R)(y) => RTC(R)(x,y) ) 

   NFs_implies_Equal: LEMMA ( confluent?(R) & EC(R)(x,y) ) => 
                                 (is_normal_form?(R)(x) & is_normal_form?(R)(y)
                                                             => x = y )

   Norm_and_Confl_implies_UNF: LEMMA normalizing?(R) & confluent?(R) => 
                                                    FORALL x: has_unique_nf?(R,x)

   Normalizing_and_Confl: LEMMA ( normalizing?(R) & confluent?(R) ) =>
                     EXISTS u, v: unique_nf?(R)(x,u) & unique_nf?(R)(y,v)
                      & EC(R)(x,y) <=> u = v 

   Normal_Confl_iff_UNF: LEMMA normalizing?(R) & confluent?(R) <=>
                                                   FORALL x: has_unique_nf?(R,x)

   Noetherian_implies_normalizing: LEMMA noetherian?(R) => normalizing?(R)

   Convergent_UNF: LEMMA convergent?(R) => FORALL x: has_unique_nf?(R,x)

   Noet_and_Confl_iff_UNF: LEMMA noetherian?(R) => 
                                    ( confluent?(R) <=>
                                              FORALL x: has_unique_nf?(R,x) )

   Convergent_iff_eqNF: LEMMA convergent?(R) =>
                               ( EC(R)(x,y) <=> 
                                 (FORALL u,v: normal_form?(R)(x,u) 
                                              & normal_form?(R)(y,v)
                                                             => u = v) )
  end results_normal_form


body:
  %%-------------------** Abstract Reduction System (ARS) **-------------------
  %%                                                                          
  %% Authors         : Ana Cristina Rocha Oliveira 
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil
  %%
  %%                         and 
  %%  
  %%                   Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %% Last Modified On: October 15, 2008                                      
  %%                                                                          
  %%---------------------------------------------------------------------------


  %%%% This theory contains some results and exercises from the book TeReSe %%%


  confluence_commute[T: TYPE] : THEORY
    BEGIN
     IMPORTING noetherian[T],
               results_confluence[T]

      R, R1, R2, R3 : VAR PRED[[T, T]]
      x, y, z, r, s : VAR T


  % Terminology

     semi_commute?(R1,R2): bool =
  	FORALL x, y, z: R1(x,y) & RTC(R2)(x,z) =>
  	EXISTS r: RTC(R2)(y,r) & RTC(R1)(z,r)

     sub_commutative?(R): bool =
  	FORALL x, y, z: R(x,y) & R(x,z) =>
  	EXISTS r: RC(R)(y,r) & RC(R)(z,r)

     request?(R1,R2): bool =
  	FORALL x, y, z: RTC(R1)(x,y) & RTC(R2)(x,z) =>
  	EXISTS r, s: RTC(R2)(y,r) & RTC(R1)(z,s) & RTC(R2)(s,r)

     refinement?(R1,R2): bool =
  	FORALL x, y: R1(x,y) => RTC(R2)(x,y)

     ref_compatible?(R1,R2): bool =
  	refinement?(R1,R2) & (FORALL x, y: RTC(R2)(x,y) => joinable?(R1)(x,y))

     postponement?(R1,R2): bool =
  	FORALL x, y: LET R = union(R1,R2) IN RTC(R)(x,y) =>
  	EXISTS z: RTC(R1)(x,z) & RTC(R2)(z,y)

     UN_terese?(R): bool = FORALL x, y :( is_normal_form?(R)(x) & 
                                         is_normal_form?(R)(y) &
                                         EC(R)(x,y) ) =>
                                                           x = y
                                    
   UNseta_terese?(R): bool = FORALL x, y :( is_normal_form?(R)(x) & 
                                            is_normal_form?(R)(y) & 
                                           (EXISTS z : RTC(R)(z,x) & RTC(R)(z,y)) )
                                              =>
                                                x = y

  % Auxiliary Lemmas

     RC_RTC_is_RTC : LEMMA  RC(RTC(R)) = RTC(R)
     
     RTC_o_RTC_is_RTC : LEMMA RTC(R)(x,y) & RTC(R)(y,z) => RTC(R)(x,z)

     RC_o_RTC_is_RTC : LEMMA RC(R)(x,y) & RTC(R)(y,z) => RTC(R)(x,z)

     RTC_converse_RTC_R: LEMMA RTC(R)(x,y) <=> RTC(converse(R))(y,x)
    

  % Exercice: 1.3.6 [Staples 1975], terese

     semi_comm_implies_comm: LEMMA semi_commute?(R1,R2) => commute?(R1,R2)


  % Proposition: 1.1.10, terese

     sub_comm_rtc_implies_conf : LEMMA sub_commutative?(RTC(R)) => confluent?(R) 


  % Exercice: 1.3.8 (i), terese

     conf_local_request_implies_request : LEMMA
  	confluent?(R2) & (FORALL x, y, z: RTC(R1)(x,y) & R2(x,z) =>
  	EXISTS r, s: RTC(R2)(y,r) & RTC(R1)(z,s) & RTC(R2)(s,r) )
       => request?(R1,R2)
     

  % Exercice: 1.3.8 (ii), terese    

     comp_rtc_req_conf_impl_diamond: LEMMA
       LET R3 = RTC(R1) o RTC(R2) IN
       ((request?(R1,R2) & confluent?(R2) & 
       (FORALL x, y, z: RTC(R1)(x,y) & RTC(R1)(x,z) => EXISTS r: R3(y,r) & R3(z,r)))
            => 
              diamond_property?(R3) )
   
     union_req_conf_is_confluent  : LEMMA	
       request?(R1,R2) & confluent?(R2) & (LET R3 = RTC(R1) o RTC(R2) IN 
       (FORALL x, y, z: RTC(R1)(x,y) & RTC(R1)(x,z) => EXISTS r: R3(y,r) & R3(z,r)))
            => 
             (LET R = union(R1, R2) IN 
              (confluent?(R)))


  % Exercice: 1.3.8 (iii), terese

     comp_rtc_confs_req_impl_diamond: LEMMA
  	confluent?(R1) & confluent?(R2) & request?(R1,R2)
      => (LET R3 = RTC(R1) o RTC(R2) IN diamond_property?(R3))

     union_confs_req_is_confluent: LEMMA
  	confluent?(R1) & confluent?(R2) & request?(R1,R2)
      => (LET R = union(R1, R2) IN (confluent?(R)))

  % Exercice: 1.3.5 (i), terese

     CR_iff_PP: LEMMA
  	church_rosser?(R) <=> postponement?(R,converse(R))

     confluent_iff_postponement: LEMMA
  	confluent?(R) <=> postponement?(R,converse(R))

  % Exercice: 1.3.5 (ii), terese

  % 1.3.5. Exercise [Hindley 1964]

   hip_Hindley_implies_semi_comm : LEMMA 
    (FORALL x, y, z :  (R1(x, y) & R2(x, z) => EXISTS r : R2(y, r) & RC(R1)(z, r)))
        IMPLIES semi_commute?(R1, R2)

   lemma_Hindley_1964 : LEMMA 
     (FORALL x, y, z:  (R1(x, y) & R2(x, z) => EXISTS r : R2(y, r) & RC(R1)(z, r)))
        IMPLIES commute?(R1, R2)                   
                                    
    
  % Exercice: 1.3.9 (i), terese

     ref_condition_to_refcomp : LEMMA 
         refinement?(R1,R2)  => (ref_compatible?(R1,R2)
                            <=> 
    (FORALL x, y:(R2 o RTC(R1))(x,y) => joinable?(R1)(x,y)))


  % Auxiliar for Rosen 73' Lemma
     
     semi_implies_CR: LEMMA semi_confluent?(R) => church_rosser?(R)

     semi_implies_conf: LEMMA semi_confluent?(R) => confluent?(R)

     sub_comm_implies_semi_conf : LEMMA  sub_commutative?(R) => semi_confluent?(R)

     sub_comm_implies_conf : LEMMA sub_commutative?(R) => confluent?(R)


  % Exercice:  1.3.3 [Rosen 1973]

     lemma_Rosen_1973 : LEMMA	 
       RTC(R1) = RTC(R2) & sub_commutative?(R1) =>
         confluent?(R2)



  % Exercice:  1.3.2 

     lcomm_and_snunion_implies_comm : LEMMA locally_commute?(R1,R2) & 
                                            noetherian?(union(R1,R2))
                                               =>
                                                 commute?(R1,R2) 


  % Exercice:  1.3.10

     UN_implies_UNseta : LEMMA UN_terese?(R) => UNseta_terese?(R)
   


   END confluence_commute


body:
  %%-------------------** Abstract Reduction System (ARS) **-------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%              
  %% Last Modified On: October 15, 2008                                      
  %%                                                                          
  %%---------------------------------------------------------------------------


  modulo_equivalence[T : TYPE] : THEORY
  BEGIN

    IMPORTING noetherian[T]

    R, S : VAR  PRED[[T, T]]
    Eq   : VAR equivalence
    x, y,
    z, w,
    u, v : VAR T

    R_Eq(R, Eq)  : PRED[[T, T]] = Eq o R o Eq

    SC_Eq(R, Eq) : PRED[[T, T]] = union(SC(R), Eq)

    Eq_Eq(R, Eq) : equivalence = EC(SC_Eq(R, Eq))

    joinable_m?(R, Eq)(x,y) : bool = EXISTS u,v: RTC(R)(x,u) & 
                                                 Eq(u,v) & RTC(R)(y,v)

    church_rosser_m?(R, Eq) : bool = FORALL x, y: Eq_Eq(R, Eq)(x,y) => 
                                                  joinable_m?(R, Eq)(x,y)
   
    local_confluent_m?(R, Eq) : bool = FORALL x, y, z: R(x,y) & R(x,z) => 
                                                       joinable_m?(R, Eq)(y,z)

    confluent_m?(R, Eq) : bool = FORALL x, y, z, w: RTC(R)(x,z)  & 
                                                    Eq(x,y) &
                                                    RTC(R)(y,w) => 
                                                    joinable_m?(R, Eq)(z,w)

    has_unique_nf_m?(R, Eq) : bool = FORALL x, y, u, v: is_normal_form?(R)(u) &
                                                        is_normal_form?(R)(v) &
                                                        RTC(R)(x,u) &
                                                        Eq_Eq(R, Eq)(x,y)  &
                                                        RTC(R)(y,v) => Eq(u,v)

    locally_coherent?(R, Eq, S) : bool = symmetric?(S) &
                                         FORALL  x, y, z: R(x,y) & 
                                         S(x,z) => joinable_m?(R, Eq)(y,z)

    noetherian_m?(R, Eq) : bool = well_founded?(converse(R o Eq))

    

  %%--------------------------------------


  van_oostrom94 : LEMMA diamond_property?(RTC(R) o Eq) => confluent_m?(R, Eq)


  newman_lemma_general : THEOREM noetherian?(R) => 
                                (local_confluent_m?(R, Eq) & 
                                 locally_coherent?(R, Eq, Eq) <=>  
                                                             confluent_m?(R, Eq))
              

  END modulo_equivalence


body:
  %%-------------------** Abstract Reduction System (ARS) **-------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%               
  %% Last Modified On: December 02, 2006                                      
  %%                                                                          
  %%---------------------------------------------------------------------------


  results_commutation[T : TYPE] : THEORY
  BEGIN

    IMPORTING noetherian[T]
    
        R1, R2 : VAR PRED[[T, T]]
    x, y, z, r : VAR T




  %%------------------------** Commutation Lemma **---------------------------
  %%
  %%
  %% -  Local_Comu_and_Noeth: If -> and --> locally commute and (-> union -->)
  %%                          is noetherian, then -> and --> commutes.
  %%
  %%
  %% - commute_and_iterate_one: If -> and --> strongly commuting and
  %%                            y *<- x --> z then exists r such that
  %%                            y -->= r *<- z.
  %%
  %%
  %% - commute_and_iterate_two: If -> and --> strongly commuting and
  %%                            y *<- x -->* z then exists r such that
  %%                            y -->* r *<- z.
  %%
  %%
  %% - Comutation_Lemma: Two strongly commuting reductions commute.
  %%
  %%
  %%---------------------------------------------------------------------------


   Local_Comu_and_Noeth: THEOREM locally_commute?(R1,R2) 
                               & noetherian?(union(R1, R2)) => commute?(R1,R2)

   commute_and_iterate_one: LEMMA FORALL (n: nat): strong_commute?(R1,R2) &
                            iterate(R1, n)(x,y) & R2(x,z) => 
                                          EXISTS r: RTC(R1)(z,r) & RC(R2)(y,r)

   commute_and_iterate_two: LEMMA FORALL (n,m: nat): strong_commute?(R1,R2) &
                             iterate(R1, n)(x,y) & iterate(R2, m)(x,z) => 
                                          EXISTS r: RTC(R2)(y,r) & RTC(R1)(z,r)

   Comutation_Lemma: THEOREM strong_commute?(R1,R2) => commute?(R1,R2)


  END results_commutation


body:
  %%-------------------** Abstract Reduction System (ARS) **-------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%                    
  %% Last Modified On: October 15, 2008
  %%                                                                          
  %%---------------------------------------------------------------------------


  ars[T : TYPE] : THEORY
  BEGIN

    IMPORTING results_commutation[T],
              modulo_equivalence[T],
              confluence_commute[T],
              results_normal_form[T],
              newman_yokouchi[T]
             
              
  end ars


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%       
  %% Last Modified On: March 24, 2008                                      
  %%                                                                          
  %%----------------------------------------------------------------------------


  IUnion_extra[T: TYPE]: THEORY
    BEGIN


                     i, n: VAR nat
                     x, y: VAR T
                     A, B, 
                     C, D: VAR set[T]


  %%%%%%%%%%%% Defining the finite set 1 <= i <= n %%%%%%%%%%%%%%%%%%%%%%%%%%


    upto?(n: posnat): NONEMPTY_TYPE = {i: posnat | i <= n} CONTAINING n



  %%%%%%%%%%%% Auxiliar Properties %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    disjoint_subset: LEMMA subset?(A,B) & subset?(C,D) & disjoint?(B,D) 
                              => disjoint?(A,C)

    disjoint_commute: LEMMA disjoint?(A,B) => disjoint?(B,A)

    IUnion_of_finite_is_finite: LEMMA
      FORALL (n: posnat, (f:[upto?(n) -> set[T]])):
        (FORALL (i: upto?(n)): is_finite(f(i)))
         => is_finite(IUnion(LAMBDA (i: upto?(n)): f(i)))


    IUnion_of_finite_is_finite1: LEMMA
      FORALL (n: posnat, (f:[below[n] -> set[T]])):
        (FORALL (i: below[n]): is_finite(f(i)))
         => is_finite(IUnion(LAMBDA (i: below[n]): f(i)))

  END IUnion_extra

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 29, column 68) for  n
      % expected type  upto?(n)
  upto?_TCC1: OBLIGATION FORALL (n: posnat): n <= n;


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%           
  %% Last Modified On: October 15, 2008                                      
  %%                                                                          
  %%----------------------------------------------------------------------------


  %%%% Defining S-terms over V inductively, where S is a Signature and V is a %%
  %%%% set of Variables                                                       %%

  term[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]] : DATATYPE 
   BEGIN

   vars(v: variable): vars?

   app(f:symbol, args:{args:finite_sequence[term] | args`length=arity(f)}): app?

   END term


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%            
  %% Last Modified On: October 15, 2008                                      
  %%                                                                          
  %%----------------------------------------------------------------------------


  variables_term[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY
   BEGIN

       IMPORTING term[variable,symbol,arity]
               
          V: set[term] = {x: term | vars?(x)} 

  END variables_term


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%               
  %% Last Modified On: May 10, 2011
  %%                                                                          
  %%----------------------------------------------------------------------------


  positions[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY
    BEGIN
      
     position: TYPE = finseq[posnat]
    positions: TYPE = set[position]
    
    IMPORTING IUnion_extra[position],
              structures@seq_extras[position] as fspos,
              structures@seq_extras[posnat]   as fsepn,
              variables_term[variable,symbol, arity],
              structures@seq_extras[term]     as fset


  %%%%%%%%%%%% Definition: The set of positions of a term %%%%%%%%%%%%%%%%%%%


    only_empty_seq: positions = {x: position | x = empty_seq}

    catenate(i: posnat, s: positions): positions  =
          {seq: position | EXISTS (x: position): (member(x,s) AND 
                                                   seq = add_first(i,x))}


    positionsOF(t: term): RECURSIVE positions =
      (CASES t OF 
         vars(t): only_empty_seq,
         app(f, st): IF length(st) = 0
                     THEN
                      only_empty_seq
                     ELSE
                      union(only_empty_seq, 
                            IUnion((LAMBDA (i: upto?(length(st))):
                                 catenate(i, positionsOF(st(i-1)) ))))
                     ENDIF
       ENDCASES)
    MEASURE t BY << 

    positions?(t: term): TYPE = {p: position | positionsOF(t)(p)}
   
    positions(t: term): set[position] = {p: position | positionsOF(t)(p)}



  %%%%%%%%%%%% Definition: Order on positions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   
       p, q: VAR position
    s, r, t: VAR term
       j, i: VAR posnat


    <=(p, q): bool = (EXISTS (p1: position): q = p o p1);

    parallel(p, q): bool = (NOT p <= q) & (NOT q <= p)

    child(p, q): bool = (EXISTS (p1: position):
         (p1 /= empty_seq AND p = q o p1))

    left_without_children(p, q): bool = (EXISTS (r,p1,q1: position): 
         (q = r o q1 AND p = r o p1 AND 
          q1 /= empty_seq AND p1 /= empty_seq AND
          first(p1) < first(q1)))

    left_pos(p, q): bool = (EXISTS (r,p1,q1: position): 
         (q = r AND p1 /= empty_seq AND p = r o p1) OR
         (q = r o q1 AND p = r o p1 AND 
          q1 /= empty_seq AND p1 /= empty_seq AND
          first(p1) < first(q1))) 


  %%%% Auxiliar definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       

        fsp: VAR finseq[position]


    PP?(fsp): bool = IF fsp`length < 2
                     THEN true
                     ELSE
                       FORALL (i, j: below[length(fsp)]): i /= j  => 
                                       parallel(fsp(i), fsp(j))
                     ENDIF
   

    SP?(t)(fsp): bool = FORALL (i: below[length(fsp)]): 
                            positionsOF(t)(fsp(i))


    SPP?(t)(fsp): bool = PP?(fsp) & SP?(t)(fsp)

    
       PP : TYPE = (PP?)

     SP(t): TYPE = (SP?(t))
    
    SPP(t): TYPE = (SPP?(t))



  %%%%%%%%%%%% Properties of positions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


    positions_of_terms_finite : LEMMA is_finite(positionsOF(t))

    empty_pos: LEMMA q = empty_seq  &  p <= q => p = empty_seq

    closed_positions: LEMMA (positionsOF(t)(q) & p <= q) => positionsOF(t)(p)

    equal_symbol_equal_length_arg : LEMMA
        FORALL (s, t: term, fs, ft: symbol, 
                ss:{args: finite_sequence[term] | args`length = arity(fs)},
                st:{argt: finite_sequence[term] | argt`length = arity(ft)}) :
         (s = app(fs, ss) AND t = app(ft,st) AND fs = ft)
                                 IMPLIES ss`length = st`length

    not_var: LEMMA (positionsOF(t)(p) & p = add_first(i, q)) => app?(t)

    not_var1: LEMMA (positionsOF(t)(p) & p = add_last(q,i)) => app?(t)

    pos_ax: LEMMA positionsOF(t)(p o q) => positionsOF(t)(p)

    rest_of_positions: LEMMA (positionsOF(s)(p) & length(p) /= 0)  =>
  	                  positionsOF(args(s)(first(p) - 1))(rest(p))

    delete_is_position: LEMMA positionsOF(s)(p) & length(p) /= 0 =>
                                  positionsOF(s)(delete(p, length(p) - 1))


    parallel_comm: LEMMA parallel(p, q) => parallel(q, p)

    rest_parallel: LEMMA length(p)/= 0 & length(q)/= 0 & first(p) = first(q)
                             & parallel(p, q) => parallel(rest(p), rest(q))


    rest_of_PP_is_PP: LEMMA FORALL (fss: PP): PP?(rest(fss))


    rest_of_SP_is_SP: LEMMA  FORALL s, (fss: SP(s)): SP?(s)(rest(fss))


    delete_of_PP_is_PP: LEMMA
       FORALL (fss: PP), (i: below[length(fss)]): PP?(delete(fss, i))

    delete_of_SP_is_SP: LEMMA
       FORALL s, (fss: SP(s)), (i: below[length(fss)]): SP?(s)(delete(fss, i))



    add_first_parallel_pos_to_PP_is_PP : LEMMA 
     FORALL (fss: PP), (q: position): 
         (FORALL (i: below[length(fss)]): parallel(fss(i),q))
             =>
              PP?(add_first(q, fss))


    add_first_parallel_pos_to_SP_is_SP : LEMMA 
     FORALL s, (fss: SP(s)), (q: positions?(s)): SP?(s)(add_first(q, fss) )


    add_last_parallel_pos_to_PP_is_PP : LEMMA 
     FORALL (fss: PP), (q: position): 
         (FORALL (i: below[length(fss)]): parallel(fss(i),q))
             =>
              PP?(add_last(fss, q))


    add_last_parallel_pos_to_SP_is_SP : LEMMA 
     FORALL s, (fss: SP(s)), (q: positions?(s)): SP?(s)(add_last(fss, q))


  %%%% Auxiliary lemmas - Andréia B. Avelar %%%%%%%%%%%%%%%%%%%%%%

   positions_of_arg : LEMMA
        FORALL ( (s : term | app?(s) ), k : below[length(args(s))] ) :
        positionsOF(s)( #[posnat]( k+1 ) )

   left_pos_transitive : LEMMA
      FORALL (q1 : position) :
      left_pos(p, q1) AND left_pos(q1, q) IMPLIES left_pos(p, q)

   lwc_is_left_pos: LEMMA 
      left_without_children(p, q) IMPLIES left_pos(p, q)

   lwc_transitive : LEMMA
      FORALL (q1 : position) :
        left_without_children(p, q1) AND left_without_children(q1, q)
        IMPLIES left_without_children(p, q)

   subterm_if_le_arity : LEMMA
      ( app?(s) AND arity(f(s)) >= i )
       IMPLIES positionsOF(s)( #(i))

   subterms_acc_arity : LEMMA
      positionsOF(s)( #(i)) AND j <= i IMPLIES positionsOF(s)( #(j))

   lwc_add_last_delete : LEMMA
       FORALL (q1 : position) : 
          (p /= empty_seq AND left_without_children(p, q1)) IMPLIES
            LET q = add_last(delete(p, length(p) - 1), 1 + last(p)) IN
              left_without_children(q, q1) OR child(q1, q) OR q1 = q
        
   lwc_add_last_delete1 : LEMMA
       FORALL (q1 : position, p : position | p /= empty_seq) :
        LET q = add_last(delete(p, length(p) - 1), 1 + last(p)) IN
          left_without_children(q1, q) IMPLIES
            left_without_children(q1, p) OR child(q1, p) OR q1 = p

   leftmost_pos : LEMMA
     ( NOT positionsOF(s)( #(i + 1)) AND
       positionsOF(s)( #(i)) AND positionsOF(s)(q) )
       IMPLIES ( q = empty_seq OR left_pos(q, #(i)) OR q = #(i) )

   END positions

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 48, column 58) for  i - 1
      % expected type  below[length(st)]
  positionsOF_TCC1: OBLIGATION
    FORALL (t: term[variable, symbol, arity], f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND t = app(f, st) IMPLIES
       (FORALL (i: upto?[position](length(st))):
          i - 1 >= 0 AND i - 1 < length(st));

  % Termination TCC generated (at line 48, column 43) for
      % positionsOF(finseq_appl[term[variable, symbol, arity]](st)(i - 1))
  positionsOF_TCC2: OBLIGATION
    FORALL (t: term[variable, symbol, arity], f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND t = app(f, st) IMPLIES
       (FORALL (i: upto?[position](length(st))):
          <<[variable, symbol, arity]
              (finseq_appl[term[variable, symbol, arity]](st)(i - 1), t));

  % Subtype TCC generated (at line 77, column 14) for  p1
      % expected type  not_empty_seq[posnat]
  left_without_children_TCC1: OBLIGATION
    FORALL (p: position, q: position, r, p1, q1: position):
      p1 /= empty_seq AND q1 /= empty_seq AND p = r o p1 AND q = r o q1
       IMPLIES length(p1) /= 0;

  % Subtype TCC generated (at line 77, column 26) for  q1
      % expected type  not_empty_seq[posnat]
  left_without_children_TCC2: OBLIGATION
    FORALL (p: position, q: position, r, p1, q1: position):
      p1 /= empty_seq AND q1 /= empty_seq AND p = r o p1 AND q = r o q1
       IMPLIES length(q1) /= 0;

  % Subtype TCC generated (at line 138, column 39) for  first(p) - 1
      % expected type  below[length(args(s))]
  rest_of_positions_TCC1: OBLIGATION
    FORALL (p: position, s: term[variable, symbol, arity]):
      length(p) /= 0 AND positionsOF(s)(p) IMPLIES
       first[posnat](p) - 1 >= 0 AND
        first[posnat](p) - 1 < length(args[variable, symbol, arity](s));

  % Subtype TCC generated (at line 138, column 36) for  s
      % expected type  d: (app?[variable, symbol, arity])
  rest_of_positions_TCC2: OBLIGATION
    FORALL (p: position, s: term[variable, symbol, arity]):
      length(p) /= 0 AND positionsOF(s)(p) IMPLIES
       app?[variable, symbol, arity](s);

  % Subtype TCC generated (at line 141, column 57) for  length(p) - 1
      % expected type  below[length(p)]
  delete_is_position_TCC1: OBLIGATION
    FORALL (p: position, s: term[variable, symbol, arity]):
      length(p) /= 0 AND positionsOF(s)(p) IMPLIES
       length(p) - 1 >= 0 AND length(p) - 1 < length(p);

  % Subtype TCC generated (at line 214, column 37) for  length(p) - 1
      % expected type  below[length(p)]
  lwc_add_last_delete_TCC1: OBLIGATION
    FORALL (p, q1: position):
      p /= empty_seq AND left_without_children(p, q1) IMPLIES
       length(p) - 1 >= 0 AND length(p) - 1 < length(p);

  % Subtype TCC generated (at line 214, column 62) for  p
      % expected type  not_empty_seq[posnat]
  lwc_add_last_delete_TCC2: OBLIGATION
    FORALL (p, q1: position):
      p /= empty_seq AND left_without_children(p, q1) IMPLIES length(p) /= 0;

  % Subtype TCC generated (at line 219, column 33) for  length(p) - 1
      % expected type  below[length(p)]
  lwc_add_last_delete1_TCC1: OBLIGATION
    FORALL (p: position | p /= empty_seq[posnat]):
      length(p) - 1 >= 0 AND length(p) - 1 < length(p);

  % Subtype TCC generated (at line 219, column 58) for  p
      % expected type  not_empty_seq[posnat]
  lwc_add_last_delete1_TCC2: OBLIGATION
    FORALL (p: position | p /= empty_seq[posnat]): length(p) /= 0;


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%            
  %% Last Modified On: April 25, 2011
  %%                                                                          
  %%----------------------------------------------------------------------------



  subterm[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY
   BEGIN

       IMPORTING positions[variable,symbol, arity],
                 IUnion_extra[(V)],
                 sets_aux@infinite_nat_def[position] 

       x, y: VAR (V)
       p, q: VAR position
       s, t: VAR term
        i,j: VAR posnat
       m,n: VAR nat


  %%%% Definition: subterm of t at position p %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     subtermOF(t: term, (p: positions?(t))): RECURSIVE term =
           (IF length(p) = 0
            THEN
              t
            ELSE
              LET st = args(t),
                   i = first(p),
                   q = rest(p)  IN
              subtermOF(st(i-1), q)
            ENDIF)
     MEASURE length(p)

   
  %%%%%%%%%%%% Definition: variables occurring in t %%%%%%%%%%%%%%%%%%%%%%%%%

    Vars?(t): TYPE = 
            {x:term | V(x) &  EXISTS (p: positions?(t)): subtermOF(t, p) = x}

    Vars(t): set[(V)] = {x: (V) |  EXISTS (p: positions?(t)): subtermOF(t, p) = x}

    

     ground(t): bool = Vars(t) = emptyset

   
     Pos_var(t, x): positions = {p: positions?(t) | subtermOF(t,p) = x}


     pos_vars_subset_pos : LEMMA
                             LET Posv = Pos_var(t, x) IN
                             subset?(Posv, positionsOF(t))

     Pos_var_is_finite: LEMMA 
                          LET Posv = Pos_var(t, x) IN
                          is_finite(Posv)



  %%%%%%%%%%%% Properties of subterms %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


    Vars_is_var: LEMMA vars?(t) => Vars(t) = {y: (V) | y = t}


    vars_term_is_union: LEMMA 
    (CASES t OF 
      vars(t): Vars(vars(t)) = singleton(vars(t)),
      app(f, st): Vars(t) = IUnion(LAMBDA (i: below[length(st)]): Vars(st(i)))
     ENDCASES)

   
    vars_of_term_finite: LEMMA  is_finite(Vars(t))


    pos_subterm_ax: LEMMA positionsOF(t)(p o q) =>
                                              positionsOF(subtermOF(t, p))(q)

    pos_subterm: LEMMA  positionsOF(t)(p o q) => 
                          subtermOF(t, p o q) = subtermOF(subtermOF(t, p), q)

    pos_o_term: LEMMA positionsOF(t)(p)  &  positionsOF(subtermOF(t, p))(q)
                           => positionsOF(t)(p o q)

    subterm_is_app: LEMMA positionsOF(s)(p) AND length(p) /= 0 => 
                               app?(subtermOF(s,delete(p, length(p) - 1)))

    vars_subterm: LEMMA positionsOF(t)(p) => 
                                      subset?(Vars(subtermOF(t, p)), Vars(t))

    disjoint_subterm: LEMMA positionsOF(t)(p) =>
      ( disjoint?(Vars(t), Vars(s)) => disjoint?(Vars(subtermOF(t, p)), Vars(s)) )


    variable_positions_parallel: LEMMA
          FORALL (p, q: positions?(t)):
              subtermOF(t,p) = x &  
              subtermOF(t,q) = y & x /= y 
               =>     parallel(p,q)


    variable_positions: LEMMA  FORALL (p, q: positions?(t)):
                                 LET Posv = Pos_var(t, x) IN
                                 member(p, Posv) & 
                                 member(q, Posv) 
                                       =>  p = q OR parallel(p,q)



    pos_occ_var_HAStypePP: LEMMA    
                             LET Posv = Pos_var(t, x),
                                 seqv = set2seq(Posv) IN
                             PP?(seqv)



    pos_occ_var_HAStypeSP: LEMMA 
                             LET Posv = Pos_var(t, x),
                                 seqv = set2seq(Posv) IN
                             SP?(t)(seqv)


    no_empty_set_positions: LEMMA	FORALL t, x, (p: positions?(t)):
                                    LET Posv = Pos_var(t, x) IN
                                    subtermOF(t, p) = x =>  Posv(p) 

    length_seq_var_g0: LEMMA  FORALL t, x: 
                        LET Posv = Pos_var(t, x),
                            seqv = set2seq(Posv) IN
                         (EXISTS (p: positions?(t)): subtermOF(t, p) = x) 
                               => length(seqv) > 0  


  %%%% Auxiliary lemmas about subterms - Andréia B. Avelar                   %%%%
  %%%% Note: the constructor "subterm(?,?)" can be found in the term_adt.pvs %%%%

   subterm_empty_seq : LEMMA
      subtermOF(s, empty_seq) = s

   equal_subterms_equal_term : LEMMA
     IF FORALL (p : position | positionsOF(s)(p) AND
                               positionsOF(t)(p) ):
        subtermOF(s, p) = subtermOF(t, p)
     THEN s = t
     ELSE s /= t
     ENDIF


   subt_of_subt_is_subt_of_term : LEMMA
      FORALL (s : term,
             (k : posnat   | positionsOF(s)( #(k))),
             (p : position | positionsOF(subtermOF(s, #(k)))(p)),
             (x : position | positionsOF(s)(x))):
         x = add_first(k, p) IMPLIES 
                     subtermOF(s, x) = subtermOF( subtermOF(s, #(k)), p)

   subterm_to_subtermOF : LEMMA
      FORALL (s : term, t : term):
        subterm(s, t) IMPLIES
        (EXISTS ( p : position | positionsOF(t)(p) ) : subtermOF(t, p) = s)

   subtermOF_to_subterm : LEMMA
      FORALL (s : term, t: term, (p : position | positionsOF(t)(p))):
        subtermOF(t, p) = s IMPLIES subterm(s, t)

   subterm_to_subterm : LEMMA 
      FORALL (s : term, t : term, r : term):
        ( subterm(s, r) AND subterm(r, t) ) IMPLIES subterm(s, t)


   comp_of_pos(p : position, n : nat) : RECURSIVE  position =  
      IF n = 0 then empty_seq 
      ELSE p o comp_of_pos(p, n - 1) 
      ENDIF
    MEASURE n 


   set_of_seq_pos(p) : set[position] =
                    IUnion(LAMBDA (n : nat) : singleton(comp_of_pos(p,n))) 

   n_for_a_pstart : LEMMA
      FORALL (p : position, q : (set_of_seq_pos(p)) ) : 
         p /= empty_seq IMPLIES  EXISTS (n : nat) : q = comp_of_pos(p,n)


    length_comp_p : LEMMA 
     length(comp_of_pos(p,n)) = n * length(p)

    m_neq_n : LEMMA 
      p /= empty_seq AND m/= n IMPLIES comp_of_pos(p,n) /= comp_of_pos(p,m)


    function_inj(p)(n): position =  comp_of_pos(p,n)

    is_injective_function_inj: LEMMA 
       p /= empty_seq 
             IMPLIES injective?[nat,(set_of_seq_pos(p))](function_inj(p))


    infinite_set_of_seq_pos : LEMMA
      p /= empty_seq IMPLIES  is_infinite(set_of_seq_pos(p))


   comp_of_pos_is_pos: LEMMA 
      FORALL (n: nat): positionsOF(s)(p) AND subtermOF(s, p) = s 
                                          IMPLIES positionsOF(s)(comp_of_pos(p,n))

   subset_of_seq_pos : LEMMA
      positionsOF(s)(p) AND subtermOF(s, p) = s IMPLIES  
                          subset?(set_of_seq_pos(p),positionsOF(s))

   term_eq_subterm : LEMMA
      positionsOF(s)(p) AND subtermOF(s, p) = s IMPLIES p = empty_seq

   app_term : LEMMA
       ( positionsOF(s)(p) AND positionsOF(s)(q) AND child(p, q) )
       IMPLIES app?(subtermOF(s, q))


   positions_of_a_term : LEMMA
     FORALL (p : position | positionsOF(t)(p)) :
       positionsOF(t)(q) IMPLIES (left_without_children(p, q) OR
                                  left_without_children(q, p) OR
  				child(p, q) OR
  				(EXISTS(q1 : position) :
                                        positionsOF(subtermOF(t, p))(q1) 
                                        AND q = p o q1) )

   equal_app_term : LEMMA
    ( app?(s) AND app?(t) AND f(s) = f(t) AND args(s) = args(t) )
    IMPLIES s = t

   equal_term : LEMMA
     FORALL (s : term, 
             t : term, 
             p : position | positionsOF(s)(p) AND  
  	       		  positionsOF(t)(p)) :
     ( (FORALL (q: position | positionsOF(s)(q) AND 
                              positionsOF(t)(q)):
          left_without_children(p, q) =>
           subtermOF(s, q) = subtermOF(t, q))
      AND
       (FORALL (q: position | positionsOF(s)(q) AND
                              positionsOF(t)(q)):
          left_without_children(q, p) =>
           subtermOF(s, q) = subtermOF(t, q))
      AND
       (FORALL (p1: position | positionsOF(s)(p1) AND
                               positionsOF(t)(p1)):
          child(p, p1) => f(subtermOF(s, p1)) = f(subtermOF(t, p1)))
      AND
        subtermOF(s, p) = subtermOF(t, p)
      AND
        NOT p = empty_seq )
      IMPLIES s = t

  END subterm

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 39, column 27) for  p
      % expected type  not_empty_seq[posnat]
  subtermOF_TCC1: OBLIGATION
    FORALL (t: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](t))):
      NOT length(p) = 0 IMPLIES
       (FORALL (st:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length =
                            arity(f[variable, symbol, arity](t))}):
          st = args(t) IMPLIES length(p) /= 0);

  % Subtype TCC generated (at line 41, column 25) for  i - 1
      % expected type  below[length(st)]
  subtermOF_TCC2: OBLIGATION
    FORALL (t: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](t))):
      NOT length(p) = 0 IMPLIES
       (FORALL (st:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length =
                            arity(f[variable, symbol, arity](t))}):
          st = args(t) IMPLIES
           (FORALL (i: posnat):
              i = first(p) IMPLIES
               (FORALL (q: position[variable, symbol, arity]):
                  q = rest(p) IMPLIES i - 1 >= 0 AND i - 1 < length(st))));

  % Subtype TCC generated (at line 41, column 31) for  q
      % expected type  positions?
                     %     [variable, symbol,
                     %      arity](finseq_appl[term[variable, symbol, arity]]
                     %                 (st)(i - 1))
  subtermOF_TCC3: OBLIGATION
    FORALL (t: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](t))):
      NOT length(p) = 0 IMPLIES
       (FORALL (st:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length =
                            arity(f[variable, symbol, arity](t))}):
          st = args(t) IMPLIES
           (FORALL (i: posnat):
              i = first(p) IMPLIES
               (FORALL (q: position[variable, symbol, arity]):
                  q = rest(p) IMPLIES
                   positionsOF[variable, symbol, arity]
                       (finseq_appl[term[variable, symbol, arity]](st)(i - 1))
                       (q))));

  % Termination TCC generated (at line 41, column 12) for
      % subtermOF(finseq_appl[term[variable, symbol, arity]](st)(i - 1), q)
  subtermOF_TCC4: OBLIGATION
    FORALL (t: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](t))):
      NOT length(p) = 0 IMPLIES
       (FORALL (st:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length =
                            arity(f[variable, symbol, arity](t))}):
          st = args(t) IMPLIES
           (FORALL (i: posnat):
              i = first(p) IMPLIES
               (FORALL (q: position[variable, symbol, arity]):
                  q = rest(p) IMPLIES length(q) < length(p))));

  % Subtype TCC generated (at line 38, column 26) for  t
      % expected type  d: (app?)
  subtermOF_TCC5: OBLIGATION
    FORALL (t: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](t))):
      NOT length(p) = 0 IMPLIES app?[variable, symbol, arity](t);

  % Subtype TCC generated (at line 88, column 69) for  p
      % expected type  positions?[variable, symbol, arity](t)
  pos_subterm_ax_TCC1: OBLIGATION
    FORALL (p, q: position[variable, symbol, arity],
            t: term[variable, symbol, arity]):
      positionsOF(t)(p o q) IMPLIES
       positionsOF[variable, symbol, arity](t)(p);

  % Subtype TCC generated (at line 91, column 73) for  q
      % expected type  positions?[variable, symbol, arity](subtermOF(t, p))
  pos_subterm_TCC1: OBLIGATION
    FORALL (p, q: position[variable, symbol, arity],
            t: term[variable, symbol, arity]):
      positionsOF(t)(p o q) IMPLIES
       positionsOF[variable, symbol, arity](subtermOF(t, p))(q);

  % Subtype TCC generated (at line 97, column 56) for  length(p) - 1
      % expected type  below[length(p)]
  subterm_is_app_TCC1: OBLIGATION
    FORALL (p: position[variable, symbol, arity],
            s: term[variable, symbol, arity]):
      length(p) /= 0 AND positionsOF(s)(p) IMPLIES
       length(p) - 1 >= 0 AND length(p) - 1 < length(p);

  % Subtype TCC generated (at line 97, column 46) for
      % delete(p, length(p) - 1)
      % expected type  positions?[variable, symbol, arity](s)
  subterm_is_app_TCC2: OBLIGATION
    FORALL (p: position[variable, symbol, arity],
            s: term[variable, symbol, arity]):
      length(p) /= 0 AND positionsOF(s)(p) IMPLIES
       positionsOF[variable, symbol, arity]
           (s)(delete[posnat](p, length(p) - 1));

  % Subtype TCC generated (at line 123, column 46) for  Posv
      % expected type  finite_set[position[variable, symbol, arity]]
  pos_occ_var_HAStypePP_TCC1: OBLIGATION
    FORALL (t: term[variable, symbol, arity], x: (V),
            Posv: positions[variable, symbol, arity]):
      Posv = Pos_var(t, x) IMPLIES
       is_finite[position[variable, symbol, arity]](Posv);

  % Subtype TCC generated (at line 149, column 17) for  empty_seq
      % expected type  positions?[variable, symbol, arity](s)
  subterm_empty_seq_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity]):
      positionsOF[variable, symbol, arity](s)(empty_seq[posnat]);

  % Subtype TCC generated (at line 163, column 52) for   #(k)
      % expected type  positions?[variable, symbol, arity](s)
  subt_of_subt_is_subt_of_term_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (k: posnat
                 | positionsOF[variable, symbol, arity](s)( #[posnat](k)))):
      positionsOF[variable, symbol, arity](s)( #[posnat](k));

  % Subtype TCC generated (at line 184, column 28) for  n - 1
      % expected type  nat
  comp_of_pos_TCC1: OBLIGATION FORALL (n: nat): NOT n = 0 IMPLIES n - 1 >= 0;

  % Termination TCC generated (at line 184, column 13) for
      % comp_of_pos(p, n - 1)
  comp_of_pos_TCC2: OBLIGATION FORALL (n: nat): NOT n = 0 IMPLIES n - 1 < n;

  % Subtype TCC generated (at line 208, column 55) for  function_inj(p)
      % expected type  [nat -> (set_of_seq_pos(p))]
  is_injective_function_inj_TCC1: OBLIGATION
    FORALL (p: position[variable, symbol, arity]):
      p /= empty_seq IMPLIES
       (FORALL (x1: nat): set_of_seq_pos(p)(function_inj(p)(x1)));

  % Subtype TCC generated (at line 261, column 26) for  subtermOF(s, p1)
      % expected type  (app?)
  equal_term_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      ((FORALL (q: position[variable, symbol, arity]
                    | positionsOF(s)(q) AND positionsOF(t)(q)):
          left_without_children(q, p) => subtermOF(s, q) = subtermOF(t, q))
        AND
        (FORALL (q: position[variable, symbol, arity]
                     | positionsOF(s)(q) AND positionsOF(t)(q)):
           left_without_children(p, q) => subtermOF(s, q) = subtermOF(t, q)))
       IMPLIES
       (FORALL (p1: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity](s)(p1) AND
                       positionsOF[variable, symbol, arity](t)(p1)):
          child(p, p1) IMPLIES
           app?[variable, symbol, arity](subtermOF(s, p1)));

  % Subtype TCC generated (at line 261, column 48) for  subtermOF(t, p1)
      % expected type  (app?)
  equal_term_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      ((FORALL (q: position[variable, symbol, arity]
                    | positionsOF(s)(q) AND positionsOF(t)(q)):
          left_without_children(q, p) => subtermOF(s, q) = subtermOF(t, q))
        AND
        (FORALL (q: position[variable, symbol, arity]
                     | positionsOF(s)(q) AND positionsOF(t)(q)):
           left_without_children(p, q) => subtermOF(s, q) = subtermOF(t, q)))
       IMPLIES
       (FORALL (p1: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity](s)(p1) AND
                       positionsOF[variable, symbol, arity](t)(p1)):
          child(p, p1) IMPLIES
           app?[variable, symbol, arity](subtermOF(t, p1)));


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%              
  %% Last Modified On: September 29, 2009                                      
  %%                                                                          
  %%----------------------------------------------------------------------------


   replacement[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY
    BEGIN
      
     IMPORTING subterm[variable,symbol, arity]
    

    p, q, p1, p2, q1: VAR position
             s, r, t: VAR term
                   i: VAR posnat
                  fs: VAR finseq[term]
                x, y: VAR (V)


  %%%% Definition: replacing the subterm of s at position p by t %%%%%%%%%%%%%%%

   replaceTerm(s: term, t: term, (p: positions?(s))): RECURSIVE term =
       (IF length(p) = 0
        THEN
          t
        ELSE
          LET st = args(s),
               i = first(p),
               q = rest(p),
             rst = replace(replaceTerm(st(i-1), t, q), st,i-1) IN
          app(f(s), rst)
        ENDIF)
     MEASURE length(p)


  %%%% Properties %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   
   replace_preserv_pos: LEMMA positionsOF(s)(p) 
                              => 
                               positionsOF(replaceTerm(s, t, p))(p)


   replace_compose_pos: LEMMA positionsOF(t)(q) & positionsOF(s)(p)
                                =>
                                  positionsOF(replaceTerm(s, t, p))(p o q)


   replace_preserv_parallel_pos: LEMMA positionsOF(s)(q) & 
                                       positionsOF(s)(p) & 
                                       parallel(p, q)
                                          =>
                                            positionsOF(replaceTerm(s, t, p))(q)


   preserv_unchanged_pos: LEMMA positionsOF(s)(p) & 
                       positionsOF(replaceTerm(s, t, p))(q) & 
                       parallel(p, q)  
                            => positionsOF(s)(q)


   subterm_of_replace: LEMMA positionsOF(s)(p) 
                                => 
                                  subtermOF(replaceTerm(s, t, p),p) = t


   replace_subterm_of_term: LEMMA positionsOF(s)(p)
                                      => 
                                       replaceTerm(s, subtermOF(s, p), p) = s


   replace_embedding: LEMMA positionsOF(s)(p) & positionsOF(t)(q) =>
                      subtermOF(replaceTerm(s, t, p),p o q) = subtermOF(t, q)


   replace_associativity: LEMMA positionsOF(s)(p) & positionsOF(t)(q) =>
    replaceTerm(replaceTerm(s,t,p),r,p o q) = replaceTerm(s,replaceTerm(t,r,q),p)


   replace_distributivity: LEMMA positionsOF(s)(p o q) =>
     subtermOF(replaceTerm(s,t,p o q), p) = replaceTerm(subtermOF(s, p), t, q)


   replace_dominance: LEMMA positionsOF(s)(p o q) =>
                  replaceTerm(replaceTerm(s,t,p o q),r,p) = replaceTerm(s,r,p)


   replace_persistence: LEMMA positionsOF(s)(p) & 
                              positionsOF(s)(q) & 
                              parallel(p,q)
                               =>
                                subtermOF(replaceTerm(s, t, p), q) = subtermOF(s,q)


   replace_commutativity: LEMMA 
     positionsOF(s)(p) & positionsOF(s)(q) & parallel(p,q) 
       =>
        replaceTerm(replaceTerm(s,t,p),r,q) = replaceTerm(replaceTerm(s,r,q),t,p)


   pos_replaces_is_subset: LEMMA
         FORALL t, x, (p: positions?(t)): 
             subset?(positionsOF(replaceTerm(t, x, p)), positionsOF(t))


   pos_occ_var_replace: LEMMA
       FORALL t, y, x, (p: positions?(t)): 
             Pos_var(t, x)(p) & y /= x
               =>  Pos_var(replaceTerm(t, y, p), x) = remove(p, Pos_var(t, x))


    pos_occ_var_replace_as_diff: LEMMA
     FORALL t, y, x, (p: positions?(t)): 
      Pos_var(t, x)(p) & y /= x
      =>  
       Pos_var(replaceTerm(t, y, p), x) = difference(Pos_var(t, x), singleton(p))


  END replacement

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 37, column 23) for  p
      % expected type  not_empty_seq[posnat]
  replaceTerm_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](s))):
      NOT length(p) = 0 IMPLIES
       (FORALL (st:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length =
                            arity(f[variable, symbol, arity](s))}):
          st = args(s) IMPLIES length(p) /= 0);

  % Subtype TCC generated (at line 39, column 40) for  i - 1
      % expected type  below[length(st)]
  replaceTerm_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](s))):
      NOT length(p) = 0 IMPLIES
       (FORALL (st:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length =
                            arity(f[variable, symbol, arity](s))}):
          st = args(s) IMPLIES
           (FORALL (i: posnat):
              i = first(p) IMPLIES
               (FORALL (q: position[variable, symbol, arity]):
                  q = rest(p) IMPLIES i - 1 >= 0 AND i - 1 < length(st))));

  % Subtype TCC generated (at line 39, column 49) for  q
      % expected type  positions?
                     %     [variable, symbol,
                     %      arity](finseq_appl[term[variable, symbol, arity]]
                     %                 (st)(i - 1))
  replaceTerm_TCC3: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](s))):
      NOT length(p) = 0 IMPLIES
       (FORALL (st:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length =
                            arity(f[variable, symbol, arity](s))}):
          st = args(s) IMPLIES
           (FORALL (i: posnat):
              i = first(p) IMPLIES
               (FORALL (q: position[variable, symbol, arity]):
                  q = rest(p) IMPLIES
                   positionsOF[variable, symbol, arity]
                       (finseq_appl[term[variable, symbol, arity]](st)(i - 1))
                       (q))));

  % Termination TCC generated (at line 39, column 25) for
      % replaceTerm(finseq_appl[term[variable, symbol, arity]](st)(i - 1), t,
      %             q)
  replaceTerm_TCC4: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](s))):
      NOT length(p) = 0 IMPLIES
       (FORALL (st:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length =
                            arity(f[variable, symbol, arity](s))}):
          st = args(s) IMPLIES
           (FORALL (i: posnat):
              i = first(p) IMPLIES
               (FORALL (q: position[variable, symbol, arity]):
                  q = rest(p) IMPLIES length(q) < length(p))));

  % Subtype TCC generated (at line 40, column 14) for  s
      % expected type  (app?)
  replaceTerm_TCC5: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](s)),
            v:
              [{z:
                  [s: term, term[variable, symbol, arity],
                   positions?[variable, symbol, arity](s)] |
                        length(z`3) < length(p)} ->
                 term[variable, symbol, arity]]):
      NOT length(p) = 0 IMPLIES
       (FORALL (st:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length =
                            arity(f[variable, symbol, arity](s))}):
          st = args(s) IMPLIES
           (FORALL (i: posnat):
              i = first(p) IMPLIES
               (FORALL (q: position[variable, symbol, arity]):
                  q = rest(p) IMPLIES
                   (FORALL (rst: finseq[term[variable, symbol, arity]]):
                      rst =
                       replace(v(finseq_appl[term[variable, symbol, arity]]
                                     (st)(i - 1),
                                 t, q),
                               st, i - 1)
                       IMPLIES app?[variable, symbol, arity](s)))));

  % Subtype TCC generated (at line 40, column 18) for  rst
      % expected type  {args:
                     %    finite_sequence[term[variable, symbol, arity]] |
                     %          args`length = arity(f(s))}
  replaceTerm_TCC6: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](s)),
            v:
              [{z:
                  [s: term, term[variable, symbol, arity],
                   positions?[variable, symbol, arity](s)] |
                        length(z`3) < length(p)} ->
                 term[variable, symbol, arity]]):
      NOT length(p) = 0 IMPLIES
       (FORALL (st:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length =
                            arity(f[variable, symbol, arity](s))}):
          st = args(s) IMPLIES
           (FORALL (i: posnat):
              i = first(p) IMPLIES
               (FORALL (q: position[variable, symbol, arity]):
                  q = rest(p) IMPLIES
                   (FORALL (rst: finseq[term[variable, symbol, arity]]):
                      rst =
                       replace(v(finseq_appl[term[variable, symbol, arity]]
                                     (st)(i - 1),
                                 t, q),
                               st, i - 1)
                       IMPLIES
                       rst`length = arity(f[variable, symbol, arity](s))))));

  % Subtype TCC generated (at line 36, column 22) for  s
      % expected type  d: (app?)
  replaceTerm_TCC7: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (p: positions?[variable, symbol, arity](s))):
      NOT length(p) = 0 IMPLIES app?[variable, symbol, arity](s);

  % Subtype TCC generated (at line 73, column 63) for  p
      % expected type  positions?
                     %     [variable, symbol, arity](replaceTerm(s, t, p))
  subterm_of_replace_TCC1: OBLIGATION
    FORALL (p: position[variable, symbol, arity],
            s, t: term[variable, symbol, arity]):
      positionsOF(s)(p) IMPLIES
       positionsOF[variable, symbol, arity](replaceTerm(s, t, p))(p);

  % Subtype TCC generated (at line 82, column 51) for  p o q
      % expected type  positions?
                     %     [variable, symbol, arity](replaceTerm(s, t, p))
  replace_embedding_TCC1: OBLIGATION
    FORALL (p, q: position[variable, symbol, arity],
            s, t: term[variable, symbol, arity]):
      positionsOF(t)(q) AND positionsOF(s)(p) IMPLIES
       positionsOF[variable, symbol, arity]
           (replaceTerm(s, t, p))(o[posnat](p, q));

  % Subtype TCC generated (at line 90, column 37) for  p
      % expected type  positions?
                     %     [variable, symbol, arity](replaceTerm(s, t, p o q))
  replace_distributivity_TCC1: OBLIGATION
    FORALL (p, q: position[variable, symbol, arity],
            s, t: term[variable, symbol, arity]):
      positionsOF(s)(p o q) IMPLIES
       positionsOF[variable, symbol, arity]
           (replaceTerm(s, t, o[posnat](p, q)))(p);

  % Subtype TCC generated (at line 90, column 67) for  p
      % expected type  positions?[variable, symbol, arity](s)
  replace_distributivity_TCC2: OBLIGATION
    FORALL (p, q: position[variable, symbol, arity],
            s: term[variable, symbol, arity]):
      positionsOF(s)(p o q) IMPLIES
       positionsOF[variable, symbol, arity](s)(p);

  % Subtype TCC generated (at line 90, column 74) for  q
      % expected type  positions?[variable, symbol, arity](subtermOF(s, p))
  replace_distributivity_TCC3: OBLIGATION
    FORALL (p, q: position[variable, symbol, arity],
            s: term[variable, symbol, arity]):
      positionsOF(s)(p o q) IMPLIES
       positionsOF[variable, symbol, arity]
           (subtermOF[variable, symbol, arity](s, p))(q);

  % Subtype TCC generated (at line 101, column 62) for  q
      % expected type  positions?
                     %     [variable, symbol, arity](replaceTerm(s, t, p))
  replace_persistence_TCC1: OBLIGATION
    FORALL (p, q: position[variable, symbol, arity],
            s, t: term[variable, symbol, arity]):
      parallel(p, q) AND positionsOF(s)(q) AND positionsOF(s)(p) IMPLIES
       positionsOF[variable, symbol, arity](replaceTerm(s, t, p))(q);

  % Subtype TCC generated (at line 107, column 77) for  p
      % expected type  positions?
                     %     [variable, symbol, arity](replaceTerm(s, r, q))
  replace_commutativity_TCC1: OBLIGATION
    FORALL (p, q: position[variable, symbol, arity],
            r, s: term[variable, symbol, arity]):
      parallel(p, q) AND positionsOF(s)(q) AND positionsOF(s)(p) IMPLIES
       positionsOF[variable, symbol, arity](replaceTerm(s, r, q))(p);


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%              
  %% Last Modified On: September 29, 2009                                      
  %%                                                                          
  %%----------------------------------------------------------------------------


  compatibility[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY

   BEGIN

    IMPORTING replacement[variable,symbol, arity], 
              finite_sets[(V)] as fsetvar,
              ars[term]
              

        r, s, t: VAR term
              R: VAR pred[[term, term]]
              x: VAR (V)
              n: VAR nat



  %%%% Defining the set of all function symbols whose arity is n %%%%%%%%%%%%%%%%%

    arity_eq(n): TYPE = {f: symbol | arity(f) = n}



  %%%% Defining, respectively, the concepts closed under operations, compatible %% 
  %%%% with operations, and compatible with contexts                            %%

   close_op?(R): bool = 
      FORALL ( n: nat, (f: arity_eq(n)), (st1, st2: fset.fs_len(n))):
        (FORALL (m: below[n]): R(st1(m), st2(m))
           => R(app(f, st1), app(f, st2)))

        
   comp_op?(R): bool = 
      FORALL (n: nat, i: below[n], (f: arity_eq(n)), (st1: fset.fs_len(n)), t):
         LET s = st1(i), st2 = replace(t, st1, i) IN
           R(s,t) =>  R(app(f,st1), app(f,st2))


   comp_cont?(R): bool = FORALL (p: position), s: positionsOF(s)(p) =>
                          (FORALL r, t: R(r,t) =>  
                             R(replaceTerm(s, r, p), replaceTerm(s, t, p)))



  %%%% Properties %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


   comp_op_iff_comp_cont: LEMMA comp_op?(R) <=> comp_cont?(R)


   closure_comp_op: LEMMA comp_op?(R) => 
                   (comp_op?(TC(R)) & comp_op?(RTC(R)) & comp_op?(EC(R)))

   closure_comp_cont: LEMMA comp_cont?(R) => 
                   (comp_cont?(TC(R)) & comp_cont?(RTC(R)) & comp_cont?(EC(R)))

   END compatibility

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 43, column 35) for  m
      % expected type  below[length(st1)]
  close_op?_TCC1: OBLIGATION
    FORALL (n: nat, (f: arity_eq(n)),
            (st1, st2: fset[term[variable, symbol, arity]].fs_len(n)),
            m: below[n]):
      m < length(st1);

  % Subtype TCC generated (at line 43, column 43) for  m
      % expected type  below[length(st2)]
  close_op?_TCC2: OBLIGATION
    FORALL (n: nat, (f: arity_eq(n)),
            (st1, st2: fset[term[variable, symbol, arity]].fs_len(n)),
            m: below[n]):
      m < length(st2);

  % Subtype TCC generated (at line 44, column 21) for  st1
      % expected type  {args:
                     %    finite_sequence[term[variable, symbol, arity]] |
                     %          args`length = arity(f)}
  close_op?_TCC3: OBLIGATION
    FORALL (R:
              pred
                  [[term[variable, symbol, arity],
                    term[variable, symbol, arity]]],
            n: nat, (f: arity_eq(n)),
            (st1, st2: fset[term[variable, symbol, arity]].fs_len(n)),
            m: below[n]):
      R(finseq_appl[term[variable, symbol, arity]](st1)(m),
        finseq_appl[term[variable, symbol, arity]](st2)(m))
       IMPLIES st1`length = arity(f);

  % Subtype TCC generated (at line 44, column 34) for  st2
      % expected type  {args:
                     %    finite_sequence[term[variable, symbol, arity]] |
                     %          args`length = arity(f)}
  close_op?_TCC4: OBLIGATION
    FORALL (R:
              pred
                  [[term[variable, symbol, arity],
                    term[variable, symbol, arity]]],
            n: nat, (f: arity_eq(n)),
            (st1, st2: fset[term[variable, symbol, arity]].fs_len(n)),
            m: below[n]):
      R(finseq_appl[term[variable, symbol, arity]](st1)(m),
        finseq_appl[term[variable, symbol, arity]](st2)(m))
       IMPLIES st2`length = arity(f);

  % Subtype TCC generated (at line 49, column 19) for  i
      % expected type  below[length(st1)]
  comp_op?_TCC1: OBLIGATION
    FORALL (n: nat, i: below[n], (f: arity_eq(n)),
            (st1: fset[term[variable, symbol, arity]].fs_len(n))):
      i < length(st1);

  % Subtype TCC generated (at line 50, column 28) for  st1
      % expected type  {args:
                     %    finite_sequence[term[variable, symbol, arity]] |
                     %          args`length = arity(f)}
  comp_op?_TCC2: OBLIGATION
    FORALL (R:
              pred
                  [[term[variable, symbol, arity],
                    term[variable, symbol, arity]]],
            n: nat, i: below[n], (f: arity_eq(n)),
            (st1: fset[term[variable, symbol, arity]].fs_len(n)),
            t: term[variable, symbol, arity],
            s: term[variable, symbol, arity]):
      s = finseq_appl[term[variable, symbol, arity]](st1)(i) IMPLIES
       (FORALL (st2: finseq[term[variable, symbol, arity]]):
          R(s, t) AND st2 = replace(t, st1, i) IMPLIES st1`length = arity(f));

  % Subtype TCC generated (at line 50, column 40) for  st2
      % expected type  {args:
                     %    finite_sequence[term[variable, symbol, arity]] |
                     %          args`length = arity(f)}
  comp_op?_TCC3: OBLIGATION
    FORALL (R:
              pred
                  [[term[variable, symbol, arity],
                    term[variable, symbol, arity]]],
            n: nat, i: below[n], (f: arity_eq(n)),
            (st1: fset[term[variable, symbol, arity]].fs_len(n)),
            t: term[variable, symbol, arity],
            s: term[variable, symbol, arity]):
      s = finseq_appl[term[variable, symbol, arity]](st1)(i) IMPLIES
       (FORALL (st2: finseq[term[variable, symbol, arity]]):
          R(s, t) AND st2 = replace(t, st1, i) IMPLIES st2`length = arity(f));


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%            
  %% Last Modified On: April 26, 2011
  %%                                                                          
  %%----------------------------------------------------------------------------


  substitution[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY
  BEGIN

     ASSUMING
   
       IMPORTING compatibility[variable,symbol, arity],
                 sets_aux@countability[term],
                 sets_aux@countable_props[term], 
                 identity[(V)],
                 extending_rename[(V)]
                      
         var_countable: ASSUMPTION is_countably_infinite(V)
        
     ENDASSUMING


                   Vs: VAR set[(V)]
               V1, V2: VAR finite_set[(V)]
                   V3: VAR finite_set[term]
              x, y, z: VAR (V)
                  sig: VAR [(V) -> term] 
                   st: VAR finseq[term]
      r, s, t, t1, t2: VAR term
                    n: VAR nat
         p, q, p1, p2: VAR position
                    R: VAR pred[[term, term]]
   

  %%%% Defining Domain and Range (of a substitution "sigma") %%%%%%%%%%%%%%%%%%%%

   
        Dom(sig): set[(V)] = {x: (V) | sig(x) /= x}
        
        Ran(sig): set[term] = 
                   {y: term | EXISTS (x: (V)): member(x, Dom(sig)) &  y = sig(x)}

       VRan(sig): set[(V)] = IUnion(LAMBDA (x | Dom(sig)(x)): Vars(sig(x)))


  %%%% Defining a substitution "sigma" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

       Sub?(sig): bool = is_finite(Dom(sig))  


             Sub: TYPE = (Sub?)

    delta, theta,
      sigma, tau, 
        sg1, sg2: VAR Sub


  %%%% Defining renaming %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     Ren?(sigma): bool =  subset?(Ran(sigma),V) & 
                          (bijective?[(Dom(sigma)),(Ran(sigma))])(sigma)

             Ren: TYPE = (Ren?)

       rho, rho1: VAR Ren


  %%%% Properties of renaming %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    range_finite: LEMMA is_finite(Ran(rho))

      exists_var: LEMMA  EXISTS z: NOT member(z, union(V1, V2))


  %%%% Restriction of a substitution %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


    restriction(sigma)(Vs)(x): term = IF member(x, Vs)
                                 THEN 
                                    sigma(x)
                                  ELSE
                                    x
                                  ENDIF


    restriction_Dom: LEMMA  subset?(Dom(restriction(sigma)(Vs)), Dom(sigma))

    restriction_Dom_fin: LEMMA is_finite(Dom(restriction(sigma)(Vs)))

    restriction_Subs: LEMMA Sub?(restriction(sigma)(Vs))
    
    dom_restriction: LEMMA subset?(Dom(restriction(sigma)(Vs)), Vs)



  %%%%% Disjoint Domain %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


    disjoint_D?(sigma, tau): bool = disjoint?(Dom(sigma), Dom(tau))
   
    disjoint_D: TYPE = (disjoint_D?)

    sgi: VAR disjoint_D

    union_subs(sgi)(x): term = IF member(x, Dom(sgi`1)) 
                                   THEN sgi`1(x)
                                   ELSE 
                                    IF member(x, Dom(sgi`2)) 
                                    THEN sgi`2(x)
                                    ELSE x
                                    ENDIF 
                                   ENDIF


   
    Dom_union: LEMMA Dom(union_subs(sgi)) = union(Dom(sgi`1), Dom(sgi`2))

    union_is_sub: LEMMA Sub?(union_subs(sgi))

    union_commute: LEMMA disjoint?(Dom(sigma), Dom(tau)) => 
                             union_subs((sigma, tau)) = union_subs((tau, sigma))


  %%%%% Extending a substitution "sigma" to a mapping "ext: Term -> Term" %%%%%%%


   ext(sigma)(t): RECURSIVE term = 
      CASES t OF
        vars(t): sigma(t),
     app(f, st): IF length(st) = 0
                 THEN t
                 ELSE   
                   LET
                   sst = (# length := st`length,
                               seq := (LAMBDA (n: below[st`length]):
                                         ext(sigma)(st(n)))#)
                   IN
                    app(f, sst)
                 ENDIF
      ENDCASES
   MEASURE t BY <<



  %%%% Substitution identity %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


   iden_subs: LEMMA Sub?(identity)

   iden_rename: LEMMA Ren?(identity)
   
   ext_iden: LEMMA  ext(identity)(t) = t

   restriction_term: LEMMA subset?(Vars(t), Vs) =>  
                        ext(sigma)(t) =  ext(restriction(sigma)(Vs))(t)

   restriction_union: LEMMA disjoint?(Dom(sg1), Dom(sg2)) & 
                         disjoint?(Vars(t), Dom(sg2)) 
                          =>
                           ext(union_subs(sg1, sg2))(t) = ext(sg1)(t)


  %%%% Defining the composition of two substitution: comp %%%%%%%%%%%%%%%%%%%%%%%


   comp(sigma, tau)(x: (V)): term = ext(sigma)(tau(x))


   dom_o: LEMMA subset?(Dom(comp(sigma, tau)), union(Dom(sigma), Dom(tau)))

   dom_o_fin: LEMMA is_finite(Dom(comp(sigma, tau)))

   subs_o: LEMMA Sub?(comp(sigma, tau))

   ext_o: LEMMA ext(comp(sigma, tau)) = ext(sigma) o ext(tau)

   subs_o_identity: LEMMA comp(sigma, identity) = sigma

   ext_subs_o_identity: LEMMA ext(comp(sigma, identity)) = ext(sigma)

   o_ass: LEMMA comp(comp(sigma, delta), tau) = comp(sigma, comp(delta, tau))

   inverse_renaming: LEMMA
        EXISTS rho1: 
          FORALL x: Dom(rho)(x) => comp(rho1, rho)(x) = x

   inverse_rename_identity: LEMMA
      subset?(Vars(t), Dom(rho)) &
     (FORALL x: Dom(rho)(x) => comp(rho1, rho)(x) = x)
       => 
        ext(comp(rho1, rho))(t) = t
   


  %%%% Defining an idempotent substitution - Andréia B. Avelar %%%%%%%%%%%%%%%%%%


   idempotent_sub?(sigma): bool = comp(sigma, sigma) = sigma

   idempotent_sub: TYPE = (idempotent_sub?)

   idemp_sub_term_empty_inter: LEMMA
      FORALL (t: term, sigma: Sub): 
         ext(sigma)(t) = t IFF  empty?(intersection(Dom(sigma), Vars(t)))

   idemp_sub_iff_empty_intersection : LEMMA
        idempotent_sub?(sigma) IFF empty?(intersection( Dom(sigma), VRan(sigma)))



  %%%% Useful definition %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   
    DSigma(s,x)(y): term =
         IF y = x THEN s
         ELSE y
         ENDIF


    Dom_DSigma: LEMMA subset?(Dom(DSigma(s,x)),union(singleton(s), singleton(x)))

    Dom_DSigma_is_finite: LEMMA is_finite(Dom(DSigma(s,x)))

    DSigma_is_Sub: LEMMA Sub?(DSigma(s,x))


    DSigma_do_nothing: LEMMA
     FORALL t, s, x:
       empty?(Pos_var(s, x))
          IMPLIES ext(DSigma(t,x))(s) = s



    RSigma(R, sg1, sg2, x): bool = FORALL (y: (V)): IF y /= x 
                                                    THEN sg1(y) = sg2(y)
                                                    ELSE R(sg1(x), sg2(x))
                                                    ENDIF


    SigmaP(sigma, t, x, (p: positions?(sigma(x))))(y): term = 
         IF y /= x 
         THEN sigma(y)
         ELSE replaceTerm(sigma(x), t, p)
         ENDIF


    gamma(sg1, sg2, x, y)(z): term = IF y /= z 
                                     THEN sg1(z)
                                     ELSE sg2(x)
                                     ENDIF


    Rhop(rho, x, y)(z): (V) = IF x /= z 
                              THEN rho(z)
                              ELSE y
                              ENDIF


    SigmaP_Dom: LEMMA  positionsOF(sigma(x))(p) =>
      subset?(Dom(SigmaP(sigma, t, x, p)), union(Dom(sigma), singleton(x)))

    SigmaP_Dom_fin: LEMMA positionsOF(sigma(x))(p) =>
                          is_finite(Dom(SigmaP(sigma, t, x, p)))

    SigmaP_Subs: LEMMA positionsOF(sigma(x))(p) => 
                            Sub?(SigmaP(sigma, t, x, p))

    SigmaP_is_RSigma: LEMMA (positionsOF(sigma(x))(p) &
                                 comp_cont?(R) &
                                 R(subtermOF(sigma(x), p), t)) =>
                                 RSigma(R, sigma, SigmaP(sigma, t, x, p), x)


    gamma_Dom: LEMMA 
      LET sg1Usg2 = union(Dom(sg1), Dom(sg2)) IN 
      subset?(Dom(gamma(sg1, sg2, x, y)), union(sg1Usg2, singleton(y)))

     gamma_Dom_fin: LEMMA 
                     is_finite(Dom(gamma(sg1, sg2, x, y)))

     gamma_Subs: LEMMA 
                  Sub?(gamma(sg1, sg2, x, y))

     gamma_is_RSigma: LEMMA 
        RSigma(R, sg1, sg2, z) & z /= y
            => 
              RSigma(R, gamma(sg1, sg2, x, y), gamma(sg2, sg2, x, y), z)

    gamma_term: LEMMA 
                  NOT member(y, Vars(t)) 
                      => 
                        ext(gamma(sg1, sg2, x, y))(t) = ext(sg1)(t) &
                        ext(gamma(sg2, sg2, x, y))(t) = ext(sg2)(t)

     Rhop_Dom: LEMMA
              x /= y          &
              NOT Dom(rho)(x)
                =>  
                 Dom(Rhop(rho, x, y)) = union(Dom(rho), singleton(x))

     Rhop_Ran: LEMMA
              x /= y          &
              NOT Dom(rho)(x) &
              NOT Ran(rho)(y)
                =>  
                 Ran(Rhop(rho, x, y)) = union(Ran(rho), singleton(y))

     Rhop_Dom_fin: LEMMA 
              x /= y &
              NOT Dom(rho)(x)   
                =>   
                  is_finite(Dom(Rhop(rho, x, y)))

     Rhop_Subs: LEMMA 
             x /= y &
             NOT Dom(rho)(x)   
               =>   Sub?(Rhop(rho, x, y))

     Rhop_Ren: LEMMA	
                   x /= y &
                   NOT Dom(rho)(x) &
                   NOT Ran(rho)(y) => 
                   Ren?(Rhop(rho, x, y))     


  %%%% Properties %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


   ext_preserv_pos: LEMMA positionsOF(s)(p) => positionsOF(ext(sigma)(s))(p)


   subterm_ext_commute: LEMMA 
    positionsOF(s)(p) => subtermOF(ext(sigma)(s), p) = ext(sigma)(subtermOF(s, p))


   ext_replace_ext: LEMMA positionsOF(s)(p) =>
    ext(sigma)(replaceTerm(s, t, p)) 
          = replaceTerm(ext(sigma)(s), ext(sigma)(t), p)


   positions_of_ext: LEMMA positionsOF(ext(sigma)(t)) = 
     union({p | positionsOF(t)(p) & (NOT vars?(subtermOF(t, p)))}, 
           {q | EXISTS p1, p2: q = p1 o p2 AND 
                               positionsOF(t)(p1) AND 
                               vars?(subtermOF(t, p1)) AND 
                               positionsOF(ext(sigma)(subtermOF(t, p1)))(p2)})


  rename_preserv_pos: LEMMA positionsOF(ext(rho)(t)) = positionsOF(t)


  subterm_of_ext: LEMMA positionsOF(t)(p) => 
  (IF vars?(subtermOF(t, p))
   THEN 
   (positionsOF(ext(sigma)(subtermOF(t, p)))(p1) =>
    subtermOF(ext(sigma)(t), p o p1) = subtermOF(ext(sigma)(subtermOF(t, p)), p1))
   ELSE
   subtermOF(ext(sigma)(t), p) = ext(sigma)(subtermOF(t, p))
   ENDIF)


   rename_preserv_inclusion: LEMMA subset?(Vars(t), Vars(s)) => 
                                   subset?(Vars(ext(rho)(t)), Vars(ext(rho)(s)))


   same_substitution: LEMMA ext(sg1)(t) = ext(sg2)(t) => 
                             (FORALL x: member(x, Vars(t)) => sg1(x) = sg2(x))


    same_term: LEMMA (FORALL x: member(x, Vars(t)) => sg1(x) = sg2(x)) =>  
                                                      ext(sg1)(t) = ext(sg2)(t)


    term_is_a_var: LEMMA  ext(rho)(t) = x => vars?(t)
   

    vars_term_rename: LEMMA 
         Dom(rho) = Vars(t) => subset?(Vars(ext(rho)(t)), Ran(rho))


    exists_renaming: LEMMA 
          EXISTS rho: Dom(rho) = V1 & disjoint?(V2, Ran(rho))    



   add_parallel_pos: LEMMA FORALL t, sigma, (fst: SPP(t)), (p: positions?(t)):
         ( FORALL (i: below[length(fst)]): parallel(fst(i),p)) =>
                                         SPP?(ext(sigma)(t))(add_first(p,fst))


   ext_parallel_pos: LEMMA FORALL t, sigma, (fst: SPP(t)): SPP?(ext(sigma)(t))(fst)



   rest_parallel_first: LEMMA FORALL t, (fst: SPP(t)): fst`length /= 0 
                       =>
                         FORALL (i: below[length(rest(fst))]):
                                     parallel(rest(fst)(i), fst`seq(0))

   rest_parallel_pos_parallel: LEMMA  FORALL t, (fst: SPP(t)), (p: positions?(t)):
                 ( FORALL (i: below[length(fst)]): parallel(fst(i),p))
                  =>
                   FORALL (i: below[length(rest(fst))]):
                                           parallel(rest(fst)(i), p)

  vars_subst_not_in: LEMMA
    FORALL t, sigma, x: Dom(sigma)(x) AND 
                       (FORALL r: Ran(sigma)(r) IMPLIES NOT member(x, Vars(r)))
     IMPLIES NOT member(x, Vars(ext(sigma)(t)))

  ext_preserve_symbol : LEMMA
      FORALL (s : term,
              sig : Sub, 
              p : position | positionsOF(s)(p)):
         app?(subtermOF(s, p)) IMPLIES
             f(subtermOF(s, p)) = f(subtermOF(ext(sig)(s), p)) 


  END substitution

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 70, column 64) for
      % restrict
      %     [(V[variable, symbol, arity]), (Dom(sigma)),
      %      term[variable, symbol, arity]]
      %     (sigma)
      % expected type  [(Dom(sigma)) -> (Ran(sigma))]
  Ren?_TCC1: OBLIGATION
    FORALL (sigma: Sub):
      subset?(Ran(sigma), V) IMPLIES
       (FORALL (x1: (Dom(sigma))): Ran(sigma)(sigma(x1)));

  % Subtype TCC generated (at line 130, column 38) for  (sigma, tau)
      % expected type  disjoint_D
  union_commute_TCC1: OBLIGATION
    FORALL (sigma, tau: Sub):
      disjoint?(Dom(sigma), Dom(tau)) IMPLIES disjoint_D?(sigma, tau);

  % Subtype TCC generated (at line 130, column 65) for  (tau, sigma)
      % expected type  disjoint_D
  union_commute_TCC2: OBLIGATION
    FORALL (sigma, tau: Sub):
      disjoint?(Dom(sigma), Dom(tau)) IMPLIES disjoint_D?(tau, sigma);

  % Subtype TCC generated (at line 138, column 21) for  t
      % expected type  (V)
  ext_TCC1: OBLIGATION
    FORALL (sigma: Sub, t: term[variable, symbol, arity], t1: variable):
      t = vars(t1) IMPLIES V[variable, symbol, arity](t);

  % Subtype TCC generated (at line 147, column 25) for  sst
      % expected type  {args:
                     %    finite_sequence[term[variable, symbol, arity]] |
                     %          args`length = arity(f)}
  ext_TCC2: OBLIGATION
    FORALL (sigma: Sub, t: term[variable, symbol, arity],
            v:
              [Sub ->
                 [{z1: term[variable, symbol, arity] | z1 << t} ->
                    term[variable, symbol, arity]]],
            f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND t = app(f, st) IMPLIES
       (FORALL (sst:
                  [# length: nat,
                     seq:
                       [below[st`length] ->
                          term[variable, symbol, arity]] #]):
          sst =
           (# length := st`length,
              seq
                := LAMBDA (n: below[st`length]):
                     v(sigma)
                      (finseq_appl[term[variable, symbol, arity]](st)(n)) #)
           IMPLIES
           (FORALL (x: nat): x < st`length IFF x < sst`length) AND
            sst`length = arity(f));

  % Termination TCC generated (at line 145, column 39) for
      % ext(sigma)(finseq_appl[term[variable, symbol, arity]](st)(n))
  ext_TCC3: OBLIGATION
    FORALL (sigma: Sub, t: term[variable, symbol, arity],
            v:
              [Sub ->
                 [{z1: term[variable, symbol, arity] | z1 << t} ->
                    term[variable, symbol, arity]]],
            f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND t = app(f, st) IMPLIES
       (FORALL (n: below[st`length],
                sst:
                  [# length: nat,
                     seq:
                       [below[st`length] ->
                          term[variable, symbol, arity]] #]):
          sst =
           (# length := st`length,
              seq
                := LAMBDA (n: below[st`length]):
                     v(sigma)
                      (finseq_appl[term[variable, symbol, arity]](st)(n)) #)
           IMPLIES
           <<[variable, symbol, arity]
               (finseq_appl[term[variable, symbol, arity]](st)(n), t));

  % Subtype TCC generated (at line 159, column 25) for  identity
      % expected type  Sub
  iden_rename_TCC1: OBLIGATION Sub?(identity[(V)]);

  % Subtype TCC generated (at line 164, column 43) for  restriction(sigma)(Vs)
      % expected type  Sub
  restriction_term_TCC1: OBLIGATION
    FORALL (Vs: set[(V)], sigma: Sub, t: term[variable, symbol, arity]):
      subset?(Vars(t), Vs) IMPLIES Sub?(restriction(sigma)(Vs));

  % Subtype TCC generated (at line 169, column 29) for  union_subs(sg1, sg2)
      % expected type  Sub
  restriction_union_TCC1: OBLIGATION
    FORALL (sg1, sg2: Sub, t: term[variable, symbol, arity]):
      disjoint?(Vars(t), Dom(sg2)) AND disjoint?(Dom(sg1), Dom(sg2)) IMPLIES
       Sub?(union_subs(sg1, sg2));

  % Subtype TCC generated (at line 184, column 18) for  comp(sigma, tau)
      % expected type  Sub
  ext_o_TCC1: OBLIGATION FORALL (sigma, tau: Sub): Sub?(comp(sigma, tau));

  % Subtype TCC generated (at line 188, column 32) for  comp(sigma, identity)
      % expected type  Sub
  ext_subs_o_identity_TCC1: OBLIGATION
    FORALL (sigma: Sub): Sub?(comp(sigma, identity[(V)]));

  % Subtype TCC generated (at line 200, column 10) for  comp(rho1, rho)
      % expected type  Sub
  inverse_rename_identity_TCC1: OBLIGATION
    FORALL (rho, rho1: Ren, t: term[variable, symbol, arity]):
      (FORALL x: Dom(rho)(x) => comp(rho1, rho)(x) = x) AND
       subset?(Vars(t), Dom(rho))
       IMPLIES Sub?(comp(rho1, rho));

  % Subtype TCC generated (at line 239, column 20) for  DSigma(t, x)
      % expected type  Sub
  DSigma_do_nothing_TCC1: OBLIGATION
    FORALL (t, s, x): empty?(Pos_var(s, x)) IMPLIES Sub?(DSigma(t, x));

  % Subtype TCC generated (at line 263, column 33) for  rho(z)
      % expected type  (V)
  Rhop_TCC1: OBLIGATION
    FORALL (rho: Ren, x: (V[variable, symbol, arity]),
            y: (V[variable, symbol, arity]),
            z: (V[variable, symbol, arity])):
      x /= z IMPLIES V[variable, symbol, arity](rho(z));

  % Subtype TCC generated (at line 280, column 48) for  SigmaP(sigma, t, x, p)
      % expected type  Sub
  SigmaP_is_RSigma_TCC1: OBLIGATION
    FORALL (R: pred[[term, term]], p: position[variable, symbol, arity],
            sigma: Sub, t: term[variable, symbol, arity], x: (V)):
      R(subtermOF(sigma(x), p), t) AND
       comp_cont?(R) AND positionsOF(sigma(x))(p)
       IMPLIES Sub?(SigmaP(sigma, t, x, p));

  % Subtype TCC generated (at line 296, column 22) for  gamma(sg1, sg2, x, y)
      % expected type  Sub
  gamma_is_RSigma_TCC1: OBLIGATION
    FORALL (R: pred[[term, term]], sg1, sg2: Sub, x, y, z: (V)):
      z /= y AND RSigma(R, sg1, sg2, z) IMPLIES Sub?(gamma(sg1, sg2, x, y));

  % Subtype TCC generated (at line 296, column 45) for  gamma(sg2, sg2, x, y)
      % expected type  Sub
  gamma_is_RSigma_TCC2: OBLIGATION
    FORALL (R: pred[[term, term]], sg1, sg2: Sub, x, y, z: (V)):
      z /= y AND RSigma(R, sg1, sg2, z) IMPLIES Sub?(gamma(sg2, sg2, x, y));

  % Subtype TCC generated (at line 301, column 26) for  gamma(sg1, sg2, x, y)
      % expected type  Sub
  gamma_term_TCC1: OBLIGATION
    FORALL (sg1, sg2: Sub, t: term[variable, symbol, arity], x, y: (V)):
      NOT member(y, Vars(t)) IMPLIES Sub?(gamma(sg1, sg2, x, y));

  % Subtype TCC generated (at line 302, column 26) for  gamma(sg2, sg2, x, y)
      % expected type  Sub
  gamma_term_TCC2: OBLIGATION
    FORALL (sg1, sg2: Sub, t: term[variable, symbol, arity], x, y: (V)):
      NOT member(y, Vars(t)) AND ext(gamma(sg1, sg2, x, y))(t) = ext(sg1)(t)
       IMPLIES Sub?(gamma(sg2, sg2, x, y));

  % Subtype TCC generated (at line 332, column 22) for  Rhop(rho, x, y)
      % expected type  Sub
  Rhop_Ren_TCC1: OBLIGATION
    FORALL (rho: Ren, x, y: (V)):
      NOT Ran(rho)(y) AND NOT Dom(rho)(x) AND x /= y IMPLIES
       Sub?(Rhop(rho, x, y));

  % Subtype TCC generated (at line 342, column 48) for  p
      % expected type  positions?[variable, symbol, arity](ext(sigma)(s))
  subterm_ext_commute_TCC1: OBLIGATION
    FORALL (p: position[variable, symbol, arity],
            s: term[variable, symbol, arity], sigma: Sub):
      positionsOF(s)(p) IMPLIES
       positionsOF[variable, symbol, arity](ext(sigma)(s))(p);

  % Subtype TCC generated (at line 365, column 27) for  p o p1
      % expected type  positions?[variable, symbol, arity](ext(sigma)(t))
  subterm_of_ext_TCC1: OBLIGATION
    FORALL (p, p1: position[variable, symbol, arity], sigma: Sub,
            t: term[variable, symbol, arity]):
      positionsOF(t)(p) AND
       vars?(subtermOF(t, p)) AND
        positionsOF(ext(sigma)(subtermOF(t, p)))(p1)
       IMPLIES
       positionsOF[variable, symbol, arity](ext(sigma)(t))(o[posnat](p, p1));

  % Subtype TCC generated (at line 407, column 66) for  0
      % expected type  below[fst`length]
  rest_parallel_first_TCC1: OBLIGATION
    FORALL (t, fst: SPP[variable, symbol, arity](t)):
      fst`length /= 0 IMPLIES
       (FORALL (i:
                  below
                      [length
                         (rest[position[variable, symbol, arity]](fst))]):
          0 < fst`length);

  % Subtype TCC generated (at line 425, column 57) for  p
      % expected type  positions?[variable, symbol, arity](ext(sig)(s))
  ext_preserve_symbol_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity], sig: Sub,
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p)):
      app?(subtermOF(s, p)) IMPLIES
       positionsOF[variable, symbol, arity](ext(sig)(s))(p);

  % Subtype TCC generated (at line 425, column 34) for
      % subtermOF(ext(sig)(s), p)
      % expected type  (app?)
  ext_preserve_symbol_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity], sig: Sub,
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p)):
      app?(subtermOF(s, p)) IMPLIES
       app?[variable, symbol, arity]
           (subtermOF[variable, symbol, arity](ext(sig)(s), p));


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andréia Borges Avelar and
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil 
  %%
  %%                         and 
  %%
  %%                   Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil 
  %%    
  %% Last Modified On: September 29, 2009
  %%
  %%----------------------------------------------------------------------------

  unification[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY
  BEGIN

     ASSUMING

       IMPORTING variables_term[variable,symbol,arity],
                 sets_aux@countability[term],
                 sets_aux@countable_props[term]

       var_countable: ASSUMPTION is_countably_infinite(V)

     ENDASSUMING

     IMPORTING substitution[variable,symbol, arity]


                   Vs: VAR set[(V)]
               V1, V2: VAR finite_set[(V)]
                   V3: VAR finite_set[term]
              x, y, z: VAR (V)
      tau, sig, sigma, 
    delta, rho, theta: VAR Sub 
              st, stp: VAR finseq[term]
      r, s, t, t1, t2: VAR term
                    n: VAR nat
         p, q, p1, p2: VAR position
                    R: VAR pred[[term, term]]

              
  %%%% Defining an instance of a term %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   instance(t, s): bool = EXISTS sigma: ext(sigma)(s) = t;


  %%%% Defining substitution more general "<=" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   <=(theta, sigma): bool = EXISTS tau: sigma = comp(tau, theta)

   mg_po: LEMMA preorder?(<=)


  %%%% Defining unification between two terms %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   unifier(sigma)(s,t): bool = ext(sigma)(s) = ext(sigma)(t)

   unifiable(s,t): bool = EXISTS sigma: unifier(sigma)(s,t)

   U(s,t): set[Sub] = {sigma: Sub | unifier(sigma)(s,t)}


  %%%% Defining a most general unifier "mgu" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   mgu(theta)(s,t): bool = member(theta, U(s,t)) & 
                      FORALL sigma: member(sigma, U(s,t)) IMPLIES theta <= sigma


  %%%% Initial auxiliary lemma %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   uni_diff_equal_length_arg : LEMMA
        FORALL (s: term, (t: term | unifiable(s, t) & s /= t), f: symbol,
        	      st: {args: finite_sequence[term] | args`length = arity(f)}):
  	      NOT st`length = 0 AND s = app(f, st) IMPLIES
  	      (FORALL (fp: symbol, stp: {args: finite_sequence[term] |
                 args`length = arity(fp)}): t = app(fp, stp) IMPLIES
  	       (f = fp & st`length = stp`length))


  %%%% Position of the first difference between %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%% two unifiable and different terms %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   resolving_diff(s : term, (t : term | unifiable(s,t) & s /= t ) ):
     RECURSIVE position =
      (CASES s OF
         vars(s) : empty_seq,
         app(f, st) :
         IF length(st) = 0 THEN empty_seq
         ELSE 
          (CASES t OF
             vars(t) : empty_seq,
             app(fp, stp) :
             LET k : below[length(stp)] = 
               min({kk : below[length(stp)] |
                           subtermOF(s,#(kk+1)) /= subtermOF(t,#(kk+1))}) IN
               add_first(k+1,
                        resolving_diff(subtermOF(s,#(k+1)),subtermOF(t,#(k+1))))
           ENDCASES)
         ENDIF
       ENDCASES)
   MEASURE s BY << 


  %%%% Lemmas about resolving_diff %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   resol_diff_nonempty_implies_funct_terms : LEMMA
      FORALL (s: term, (t: term | unifiable(s, t) & s /= t)):
             resolving_diff(s,t) /= empty_seq IMPLIES
             (app?(s) AND app?(t))

   resol_diff_to_rest_resol_diff : LEMMA
      FORALL (s: term, (t: term | unifiable(s, t) & s /= t)):
          LET rd =  resolving_diff(s,t) IN
              rd /= empty_seq IMPLIES
              resolving_diff(subtermOF(s,#(first(rd))),
                             subtermOF(t,#(first(rd)))) = rest(rd)

   position_s_resolving_diff : LEMMA
      FORALL (s : term, t : term | unifiable(s, t) & s /= t, p : position):
          p = resolving_diff(s, t) IMPLIES positionsOF(s)(p);

   position_t_resolving_diff : LEMMA
      FORALL (s : term, t : term | unifiable(s, t) & s /= t, p : position):
          p = resolving_diff(s, t) IMPLIES positionsOF(t)(p);

   resolving_diff_has_diff_argument : LEMMA 
      FORALL (s : term, t : term | unifiable(s,t) & s /= t,
              p : position | positionsOF(s)(p) & positionsOF(t)(p)):
          p = resolving_diff(s, t) IMPLIES
            subtermOF(s, p) /= subtermOF(t, p)

   resolving_diff_has_unifiable_argument : LEMMA 
      FORALL (s : term, t : term | unifiable(s,t) & s /= t,
              p : position | positionsOF(s)(p) & positionsOF(t)(p)):
          p = resolving_diff(s, t) IMPLIES
            unifiable(subtermOF(s, p), subtermOF(t, p))

   resolving_diff_vars : LEMMA
      FORALL (s : term, t : term | unifiable(s, t) & s /= t,
  	    p : position | positionsOF(s)(p) & positionsOF(t)(p)):
          p = resolving_diff(s, t) IMPLIES
   	  vars?(subtermOF(s, p)) OR vars?(subtermOF(t, p))


  %%%% Auxiliary lemmas about substitutions and unifiers %%%%%%%%%%%%%%%%%%%%%%%%

   unifier_o : LEMMA
          member(sig, U(ext(theta)(s), ext(theta)(t))) IMPLIES
          member(comp(sig, theta), U(s, t))

   mgu_o : LEMMA
          sig <= rho IMPLIES comp(sig, theta) <= comp(rho, theta)

   unifier_and_subs : LEMMA
          member(theta, U(s, t)) IMPLIES 
          (FORALL (sig: Sub): member(comp(sig, theta), U(s, t)))

   idemp_mgu_iff_all_unifier : LEMMA
      FORALL (theta: Sub | member(theta, U(s, t))):
          mgu(theta)(s, t) & idempotent_sub?(theta) IFF
          (FORALL (sig: Sub | member(sig, U(s, t))): sig = comp(sig, theta))

   unifiable_terms_unifiable_args : LEMMA
      FORALL (s : term, t : term,
              p : position | positionsOF(s)(p) & positionsOF(t)(p)):
          member(sig, U(s, t)) IMPLIES
             member(sig, U(subtermOF(s, p), subtermOF(t, p)))

   var_term_unifiable_not_var_in_term : LEMMA 
      FORALL (s : term, t : term ):
          vars?(s) & unifiable(s, t) & s /= t IMPLIES
             NOT member(s, Vars(t))


  %%%% Substitution to fix the %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%% first difference %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   sub_of_frst_diff(s : term , (t : term | unifiable(s,t) & s /= t )) : Sub =
    LET k : position = resolving_diff(s,t) IN
       LET sp = subtermOF(s,k) , tp = subtermOF(t,k) IN 
          IF vars?(sp)
          THEN (LAMBDA (x : (V)) : IF x = sp THEN tp ELSE x ENDIF) 
          ELSE (LAMBDA (x : (V)) : IF x = tp THEN sp ELSE x ENDIF)
          ENDIF 


  %%%% Lemmas about "sub_of_frst_diff" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   dom_sub_of_frst_diff_is : LEMMA
      FORALL (s : term, t : term | unifiable(s, t) & s /= t, sig : Sub):
          sig = sub_of_frst_diff(s, t) AND p = resolving_diff(s, t)
          IMPLIES
             IF vars?(subtermOF(s, p))
               THEN Dom(sig) = singleton(subtermOF(s, p))
               ELSE Dom(sig) = singleton(subtermOF(t, p))
             ENDIF

   var_sub_1stdiff_not_member_term : LEMMA 
      FORALL (s : term, t : term | unifiable(s, t) & s /= t): 
          LET sig = sub_of_frst_diff(s ,t) IN
             FORALL ( x | member(x,Dom(sig)), r | member(r,Ran(sig) )) :
                 NOT member(x, Vars(r))

   sub_of_frst_diff_unifier_o : LEMMA
      FORALL (s : term, t : term | unifiable(s, t) & s /= t):
          member(rho, U(s, t)) IMPLIES
             LET sig = sub_of_frst_diff(s, t) IN
                EXISTS theta : rho = comp(theta, sig)

   ext_sub_of_frst_diff_unifiable : LEMMA
      FORALL (s : term, t : term | unifiable(s, t) & s /= t):
          LET sig = sub_of_frst_diff(s, t) IN
             unifiable(ext(sig)(s), (ext(sig)(t)))

   sub_of_frst_diff_remove_x : LEMMA
      FORALL (s : term, t : term | unifiable(s, t) & s /= t):
          LET sig = sub_of_frst_diff(s, t) IN
             Dom(sig)(x) IMPLIES  
                 (NOT member(x, Vars(ext(sig)(s)))) AND
                 (NOT member(x, Vars(ext(sig)(t))))

   vars_sub_of_frst_diff_s_is_subset_union : LEMMA
      FORALL (s : term, t : term | unifiable(s, t) & s /= t):
          LET sig = sub_of_frst_diff(s, t) IN
             subset?(Vars(ext(sig)(s)), union( Vars(s), Vars(t)))

   vars_sub_of_frst_diff_t_is_subset_union : LEMMA
      FORALL (s : term, t : term | unifiable(s, t) & s /= t):
          LET sig = sub_of_frst_diff(s, t) IN
             subset?(Vars(ext(sig)(t)), union( Vars(s), Vars(t)))

   union_vars_ext_sub_of_frst_diff : LEMMA
      FORALL (s : term, t : term | unifiable(s, t) & s /= t) :
          LET sig = sub_of_frst_diff(s, t) IN
             union(Vars(ext(sig)(s)), Vars(ext(sig)(t)))
             = difference(union( Vars(s), Vars(t)), Dom(sig))

   vars_ext_sub_of_frst_diff_decrease : LEMMA
      FORALL (s : term, t : term | unifiable(s, t) & s /= t):
          LET sig = sub_of_frst_diff(s, t) IN
             Card(union( Vars(ext(sig)(s)), Vars(ext(sig)(t))))
             < Card(union( Vars(s), Vars(t)))


  %%%% Function to compute a unifier of %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%%%%% two unifiable terms %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   unification_algorithm(s : term, (t : term | unifiable(s,t))) : RECURSIVE Sub =
      IF s = t THEN identity  
      ELSE LET sig = sub_of_frst_diff(s, t) IN
              comp( unification_algorithm(ext(sig)(s) , ext(sig)(t)) , sig)
      ENDIF
   MEASURE Card(union(Vars(s), Vars(t)))


  %%%% Lemmas about "unification_algorithm" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   unification_algorithm_gives_unifier : LEMMA 
      unifiable(s,t) IMPLIES member(unification_algorithm(s, t), U(s, t))
   
   unification_algorithm_gives_mg_subs : LEMMA 
      member(rho, U(s, t)) IMPLIES unification_algorithm(s, t) <= rho


  %%%% Existence of a most general unifier %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   unification : LEMMA
      unifiable(s,t) => EXISTS theta : mgu(theta)(s,t)


  END unification

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 29, column 13) for
      % substitution[variable, symbol, arity]
      % generated from assumption substitution.var_countable
  IMP_substitution_TCC1: OBLIGATION
    is_countably_infinite[term[variable, symbol, arity]]
        (V[variable, symbol, arity]);

  % Subtype TCC generated (at line 100, column 49) for   #(k + 1)
      % expected type  positions?[variable, symbol, arity](s)
  resolving_diff_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          t = app(fp, stp) IMPLIES
           (FORALL (k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               positionsOF[variable, symbol, arity](s)( #[posnat](k + 1))));

  % Subtype TCC generated (at line 100, column 69) for   #(k + 1)
      % expected type  positions?[variable, symbol, arity](t)
  resolving_diff_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          t = app(fp, stp) IMPLIES
           (FORALL (k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               positionsOF[variable, symbol, arity](t)( #[posnat](k + 1))));

  % Subtype TCC generated (at line 100, column 57) for
      % subtermOF(t,  #(k + 1))
      % expected type  {t: term |
                     %          unifiable(subtermOF(s,  #(1 + k)), t) &
                     %           NOT subtermOF(s,  #(1 + k)) = t}
  resolving_diff_TCC3: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          t = app(fp, stp) IMPLIES
           (FORALL (k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               unifiable(subtermOF[variable, symbol, arity]
                             (s,  #[posnat](1 + k)),
                         subtermOF[variable, symbol, arity]
                             (t,  #[posnat](k + 1)))
                &
                NOT subtermOF[variable, symbol, arity](s,  #[posnat](1 + k))
                     =
                     subtermOF[variable, symbol, arity]
                         (t,  #[posnat](k + 1))));

  % Termination TCC generated (at line 100, column 22) for
      % resolving_diff(subtermOF(s,  #(k + 1)), subtermOF(t,  #(k + 1)))
  resolving_diff_TCC4: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          t = app(fp, stp) IMPLIES
           (FORALL (k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               <<[variable, symbol, arity]
                   (subtermOF[variable, symbol, arity](s,  #[posnat](k + 1)),
                    s)));

  % Subtype TCC generated (at line 98, column 37) for   #(kk + 1)
      % expected type  positions?[variable, symbol, arity](s)
  resolving_diff_TCC5: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          t = app(fp, stp) IMPLIES
           (FORALL (kk: below[length(stp)], k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               positionsOF[variable, symbol, arity](s)( #[posnat](kk + 1))));

  % Subtype TCC generated (at line 98, column 61) for   #(kk + 1)
      % expected type  positions?[variable, symbol, arity](t)
  resolving_diff_TCC6: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          t = app(fp, stp) IMPLIES
           (FORALL (kk: below[length(stp)], k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               positionsOF[variable, symbol, arity](t)( #[posnat](kk + 1))));

  % Subtype TCC generated (at line 97, column 17) for
      % {kk: below[length(stp)] |
      %    subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))}
      % expected type  S: (nonempty?[below[length(stp)]])
  resolving_diff_TCC7: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          t = app(fp, stp) IMPLIES
           nonempty?[below[length(stp)]]
               ({kk: below[length(stp)] |
                   subtermOF[variable, symbol, arity](s,  #[posnat](kk + 1))
                    /=
                    subtermOF[variable, symbol, arity]
                        (t,  #[posnat](kk + 1))}));

  % Subtype TCC generated (at line 118, column 47) for  rd
      % expected type  not_empty_seq[posnat]
  resol_diff_to_rest_resol_diff_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            rd: position[variable, symbol, arity]):
      rd /= empty_seq AND rd = resolving_diff(s, t) IMPLIES length(rd) /= 0;

  % Subtype TCC generated (at line 118, column 39) for   #(first(rd))
      % expected type  positions?[variable, symbol, arity](s)
  resol_diff_to_rest_resol_diff_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            rd: position[variable, symbol, arity]):
      rd /= empty_seq AND rd = resolving_diff(s, t) IMPLIES
       positionsOF[variable, symbol, arity](s)( #[posnat](first[posnat](rd)));

  % Subtype TCC generated (at line 119, column 39) for   #(first(rd))
      % expected type  positions?[variable, symbol, arity](t)
  resol_diff_to_rest_resol_diff_TCC3: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            rd: position[variable, symbol, arity]):
      rd /= empty_seq AND rd = resolving_diff(s, t) IMPLIES
       positionsOF[variable, symbol, arity](t)( #[posnat](first[posnat](rd)));

  % Subtype TCC generated (at line 119, column 27) for
      % subtermOF(t,  #(first(rd)))
      % expected type  {t: term |
                     %          unifiable(subtermOF(s,  #(first(rd))), t) &
                     %           subtermOF(s,  #(first(rd))) /= t}
  resol_diff_to_rest_resol_diff_TCC4: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            rd: position[variable, symbol, arity]):
      rd /= empty_seq AND rd = resolving_diff(s, t) IMPLIES
       unifiable(subtermOF[variable, symbol, arity]
                     (s,  #[posnat](first[posnat](rd))),
                 subtermOF[variable, symbol, arity]
                     (t,  #[posnat](first[posnat](rd))))
        &
        subtermOF[variable, symbol, arity](s,  #[posnat](first[posnat](rd)))
         /=
         subtermOF[variable, symbol, arity](t,  #[posnat](first[posnat](rd)));

  % Subtype TCC generated (at line 152, column 15) for  comp(sig, theta)
      % expected type  Sub[variable, symbol, arity]
  unifier_o_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            sig: Sub[variable, symbol, arity],
            t: term[variable, symbol, arity],
            theta: Sub[variable, symbol, arity]):
      member(sig, U(ext(theta)(s), ext(theta)(t))) IMPLIES
       Sub?[variable, symbol, arity]
           (comp[variable, symbol, arity](sig, theta));

  % Subtype TCC generated (at line 155, column 27) for  comp(sig, theta)
      % expected type  Sub[variable, symbol, arity]
  mgu_o_TCC1: OBLIGATION
    FORALL (rho, sig, theta: Sub[variable, symbol, arity]):
      sig <= rho IMPLIES
       Sub?[variable, symbol, arity]
           (comp[variable, symbol, arity](sig, theta));

  % Subtype TCC generated (at line 155, column 47) for  comp(rho, theta)
      % expected type  Sub[variable, symbol, arity]
  mgu_o_TCC2: OBLIGATION
    FORALL (rho, sig, theta: Sub[variable, symbol, arity]):
      sig <= rho IMPLIES
       Sub?[variable, symbol, arity]
           (comp[variable, symbol, arity](rho, theta));

  % Subtype TCC generated (at line 159, column 35) for  comp(sig, theta)
      % expected type  Sub[variable, symbol, arity]
  unifier_and_subs_TCC1: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            theta: Sub[variable, symbol, arity]):
      member(theta, U(s, t)) IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          Sub?[variable, symbol, arity]
              (comp[variable, symbol, arity](sig, theta)));

  % Subtype TCC generated (at line 175, column 22) for  s
      % expected type  (V)
  var_term_unifiable_not_var_in_term_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity]):
      vars?(s) AND unifiable(s, t) AND s /= t IMPLIES
       V[variable, symbol, arity](s);

  % Subtype TCC generated (at line 183, column 26) for  k
      % expected type  positions?[variable, symbol, arity](s)
  sub_of_frst_diff_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            k: position[variable, symbol, arity]):
      k = resolving_diff(s, t) IMPLIES
       positionsOF[variable, symbol, arity](s)(k);

  % Subtype TCC generated (at line 183, column 48) for  k
      % expected type  positions?[variable, symbol, arity](t)
  sub_of_frst_diff_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            k: position[variable, symbol, arity]):
      k = resolving_diff(s, t) IMPLIES
       (FORALL (sp: term[variable, symbol, arity]):
          sp = subtermOF(s, k) IMPLIES
           positionsOF[variable, symbol, arity](t)(k));

  % Subtype TCC generated (at line 185, column 14) for
      % (LAMBDA (x: (V)): IF x = sp THEN tp ELSE x ENDIF)
      % expected type  Sub[variable, symbol, arity]
  sub_of_frst_diff_TCC3: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            k: position[variable, symbol, arity]):
      k = resolving_diff(s, t) IMPLIES
       (FORALL (sp: term[variable, symbol, arity]):
          sp = subtermOF(s, k) IMPLIES
           (FORALL (tp: term[variable, symbol, arity]):
              vars?(sp) AND tp = subtermOF(t, k) IMPLIES
               Sub?[variable, symbol, arity]
                   (LAMBDA (x: (V[variable, symbol, arity])):
                      IF x = sp THEN tp ELSE x ENDIF)));

  % Subtype TCC generated (at line 186, column 14) for
      % (LAMBDA (x: (V)): IF x = tp THEN sp ELSE x ENDIF)
      % expected type  Sub[variable, symbol, arity]
  sub_of_frst_diff_TCC4: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t) & s /= t),
            k: position[variable, symbol, arity]):
      k = resolving_diff(s, t) IMPLIES
       (FORALL (sp: term[variable, symbol, arity]):
          sp = subtermOF(s, k) IMPLIES
           (FORALL (tp: term[variable, symbol, arity]):
              NOT vars?(sp) AND tp = subtermOF(t, k) IMPLIES
               Sub?[variable, symbol, arity]
                   (LAMBDA (x: (V[variable, symbol, arity])):
                      IF x = tp THEN sp ELSE x ENDIF)));

  % Subtype TCC generated (at line 198, column 52) for  p
      % expected type  positions?[variable, symbol, arity](t)
  dom_sub_of_frst_diff_is_TCC1: OBLIGATION
    FORALL (p: position[variable, symbol, arity],
            s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | unifiable(s, t) & s /= t,
            sig: Sub[variable, symbol, arity]):
      NOT vars?(subtermOF(s, p)) AND
       sig = sub_of_frst_diff(s, t) AND p = resolving_diff(s, t)
       IMPLIES positionsOF[variable, symbol, arity](t)(p);

  % Subtype TCC generated (at line 244, column 16) for
      % union(Vars(ext(sig)(s)), Vars(ext(sig)(t)))
      % expected type  finite_set[(V)]
  vars_ext_sub_of_frst_diff_decrease_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | unifiable(s, t) & s /= t,
            sig: Sub[variable, symbol, arity]):
      sig = sub_of_frst_diff(s, t) IMPLIES
       is_finite[(V)]
           (union[(V)]
                (Vars[variable, symbol, arity]
                     (ext[variable, symbol, arity](sig)(s)),
                 Vars[variable, symbol, arity]
                     (ext[variable, symbol, arity](sig)(t))));

  % Subtype TCC generated (at line 245, column 18) for
      % union(Vars(s), Vars(t))
      % expected type  finite_set[(V)]
  vars_ext_sub_of_frst_diff_decrease_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | unifiable(s, t) & s /= t,
            sig: Sub[variable, symbol, arity]):
      sig = sub_of_frst_diff(s, t) IMPLIES
       is_finite[(V)]
           (union[(V)]
                (Vars[variable, symbol, arity](s),
                 Vars[variable, symbol, arity](t)));

  % Subtype TCC generated (at line 256, column 14) for
      % union(Vars(s), Vars(t))
      % expected type  finite_set[(V)]
  unification_algorithm_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t))):
      is_finite[(V)]
          (union[(V)]
               (Vars[variable, symbol, arity](s),
                Vars[variable, symbol, arity](t)));

  % Subtype TCC generated (at line 256, column 14) for
      % union(Vars(z`1), Vars(z`2))
      % expected type  finite_set[(V)]
  unification_algorithm_TCC2: OBLIGATION
    FORALL (z: [s: term, {t: term | unifiable(s, t)}]):
      is_finite[(V)]
          (union[(V)]
               (Vars[variable, symbol, arity](z`1),
                Vars[variable, symbol, arity](z`2)));

  % Subtype TCC generated (at line 252, column 18) for  identity
      % expected type  Sub[variable, symbol, arity]
  unification_algorithm_TCC3: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t))):
      s = t IMPLIES Sub?[variable, symbol, arity](identity[(V)]);

  % Subtype TCC generated (at line 254, column 54) for  ext(sig)(t)
      % expected type  {t: term | unifiable(ext(sig)(s), t)}
  unification_algorithm_TCC4: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t))):
      NOT s = t IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          sig = sub_of_frst_diff(s, t) IMPLIES
           unifiable(ext[variable, symbol, arity](sig)(s),
                     ext[variable, symbol, arity](sig)(t)));

  % Termination TCC generated (at line 254, column 18) for
      % unification_algorithm(ext(sig)(s), ext(sig)(t))
  unification_algorithm_TCC5: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t))):
      NOT s = t IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          sig = sub_of_frst_diff(s, t) IMPLIES
           Card[(V)]
               (union[(V)]
                    (Vars[variable, symbol, arity]
                         (ext[variable, symbol, arity](sig)(s)),
                     Vars[variable, symbol, arity]
                         (ext[variable, symbol, arity](sig)(t))))
            <
            Card[(V)]
                (union[(V)]
                     (Vars[variable, symbol, arity](s),
                      Vars[variable, symbol, arity](t))));

  % Subtype TCC generated (at line 254, column 12) for
      % comp(unification_algorithm(ext(sig)(s), ext(sig)(t)), sig)
      % expected type  Sub[variable, symbol, arity]
  unification_algorithm_TCC6: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t)),
            v:
              [{z: [s: term, {t: term | unifiable(s, t)}] |
                        Card(union(Vars(z`1), Vars(z`2))) <
                         Card(union(Vars(s), Vars(t)))} ->
                 Sub[variable, symbol, arity]]):
      NOT s = t IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          sig = sub_of_frst_diff(s, t) IMPLIES
           Sub?[variable, symbol, arity]
               (comp[variable, symbol, arity]
                    (v(ext[variable, symbol, arity](sig)(s),
                       ext[variable, symbol, arity](sig)(t)),
                     sig)));

  % Subtype TCC generated (at line 253, column 39) for  t
      % expected type  {t: term | unifiable(s, t) & s /= t}
  unification_algorithm_TCC7: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | unifiable(s, t))):
      NOT s = t IMPLIES unifiable(s, t) & s /= t;

  % Subtype TCC generated (at line 265, column 58) for  t
      % expected type  {t: term | unifiable(s, t)}
  unification_algorithm_gives_mg_subs_TCC1: OBLIGATION
    FORALL (rho: Sub[variable, symbol, arity],
            s, t: term[variable, symbol, arity]):
      member(rho, U(s, t)) IMPLIES unifiable(s, t);


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%       
  %% Last Modified On: September 29, 2009                                      
  %%                                                                          
  %%----------------------------------------------------------------------------


  rewrite_rules[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY

   BEGIN

     ASSUMING
   
       IMPORTING variables_term[variable,symbol, arity],
                 sets_aux@countability[term],
                 sets_aux@countable_props[term]
   
         var_countable: ASSUMPTION is_countably_infinite(V)
        
     ENDASSUMING

       IMPORTING substitution[variable,symbol, arity]

    l, r: VAR term
     rho: VAR Ren 


  %%%% Defining rewriting rules in agreement with Baader and Terese %%%%%%%%%%%%
      

   rewrite_rule?(l,r): bool = (NOT vars?(l)) & subset?(Vars(r), Vars(l))

   rewrite_rule: TYPE = (rewrite_rule?)

   ren_rewrite: LEMMA rewrite_rule?(l,r) => rewrite_rule?(ext(rho)(l),ext(rho)(r))



  %%%% A subset of rewrite rules %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   
             E: VAR set[rewrite_rule]

             e: VAR rewrite_rule
        lhs(e): term = e`1
        rhs(e): term = e`2


  END rewrite_rules

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 30, column 15) for
      % substitution[variable, symbol, arity]
      % generated from assumption substitution.var_countable
  IMP_substitution_TCC1: OBLIGATION
    is_countably_infinite[term[variable, symbol, arity]]
        (V[variable, symbol, arity]);


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%             
  %% Last Modified On: September 29, 2009                                      
  %%                                                                          
  %%----------------------------------------------------------------------------


  reduction[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY

   BEGIN

     ASSUMING
   
       IMPORTING variables_term[variable,symbol, arity],
                 sets_aux@countability[term],
                 sets_aux@countable_props[term]
   
         var_countable: ASSUMPTION is_countably_infinite(V)
        
     ENDASSUMING

    IMPORTING rewrite_rules[variable,symbol, arity]            
                          

     s, t, t1, t2: VAR term
  sigma, sg1, sg2: VAR Sub
                x: VAR (V)
                R: VAR pred[[term, term]] 
                E: VAR set[rewrite_rule]
                e: VAR rewrite_rule


  %%%% Defining, respectively, the concepts Reduction relation and closed under %%
  %%%% substitutions,Close under substitution                                   %%

   reduction?(E)(s,t): bool =  
       EXISTS ( (e | member(e, E)), sigma, (p: positions?(s))): 
                        subtermOF(s, p) = ext(sigma)(lhs(e)) & 
                                      t = replaceTerm(s, ext(sigma)(rhs(e)), p)


   close_subs?(R): bool = FORALL s, t, sigma: R(s,t) => 
                                              R(ext(sigma)(s),ext(sigma)(t))


  %%%% Properties %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   closure_close_subs: LEMMA close_subs?(R)  =>
                  (close_subs?(TC(R)) & close_subs?(RTC(R)) & close_subs?(EC(R)))

   reduction_is_subs_op: LEMMA close_subs?(reduction?(E)) & comp_op?(reduction?(E))

   lhs_reduces_to_rhs: LEMMA
                      FORALL (E, (e | member(e, E))): reduction?(E)(lhs(e), rhs(e))

  END reduction

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 30, column 12) for
      % rewrite_rules[variable, symbol, arity]
      % generated from assumption rewrite_rules.var_countable
  IMP_rewrite_rules_TCC1: OBLIGATION
    is_countably_infinite[term[variable, symbol, arity]]
        (V[variable, symbol, arity]);


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%          
  %% Last Modified On: September 29, 2009                                      
  %%                                                                          
  %%----------------------------------------------------------------------------


  replace_positions[variable:TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY

   BEGIN

     ASSUMING
   
       IMPORTING variables_term[variable,symbol, arity],
                 sets_aux@countability[term],
                 sets_aux@countable_props[term]
   
         var_countable: ASSUMPTION is_countably_infinite(V)
        
     ENDASSUMING


       IMPORTING substitution[variable,symbol, arity]
   

            s, t, t1, t2: VAR term
       sig, delta, alpha: VAR Sub
                       x: VAR (V)
                       f: VAR symbol  
                    args: VAR finite_sequence[term]   


  %%%% Definition: replacing all subterms of s occurring in a sequence of %%%%%%%
  %%%% parallel positions by t.                                           %%%%%%%


   replace_pos(s, t, (fssp:SPP(s)) ): RECURSIVE term =
      IF length(fssp) = 0
      THEN 
       s
      ELSE
       replace_pos(replaceTerm(s, t, fssp(0)), t, rest(fssp))
      ENDIF
    MEASURE length(fssp)




  %%%% Properties %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


  % compatibility with substitution
   replace_pos_is_stable: LEMMA 
     FORALL t, s, (fss: SPP(s)), sig:
       ext(sig)(replace_pos(s, t, fss)) = replace_pos(ext(sig)(s),ext(sig)(t),fss)


  % Preserves first replaced position
   preserv_first_position: LEMMA
     FORALL t, s, (fss: SPP(s)), (q: positions?(s)): 
         (FORALL (i: below[length(fss)]): parallel(fss(i),q))
             =>
              positionsOF(replace_pos(s, t, add_first(q, fss)))(q)


  % Preserves all parallel positions
   preserv_all_parallel_positions: LEMMA
     FORALL t, s, (fss: SPP(s)), (q: positions?(s)): 
         (FORALL (i: below[length(fss)]): parallel(fss(i),q))
             => 
              positionsOF(replace_pos(s, t, fss))(q)


  % Preserves all replaced positions
   preserv_all_replaced_positions: LEMMA 
    FORALL t, s, (fssp: SPP(s)), (i: below[fssp`length]): 
              positionsOF(replace_pos(s, t, fssp))(fssp(i))


  % preserves unchanged subterms
   preserv_unchanged_subterms: LEMMA
    FORALL t, s, (fss: SPP(s)), (q: positions?(s)): 
     (FORALL (i: below[length(fss)]): parallel(fss(i),q))
        => 
         subtermOF(replace_pos(s, t, fss), q) = subtermOF(s, q)


   replace_pos_subterm_to_term: LEMMA
      FORALL t, s, (fss: SPP(s)):
        (FORALL (i: below[length(fss)]): subtermOF(s, fss(i)) = t)
            IMPLIES replace_pos(s, t, fss) = s       


   replace_pos_to_term : LEMMA  replace_pos(s, x, set2seq(Pos_var(s, x))) = s 



    CP_lemma_aux2a: LEMMA
    FORALL t, s, (fss: SPP(s)), (q: positions?(s)): 
     (FORALL (i: below[length(fss)]): parallel(fss(i),q))
        => 
    replace_pos(s, t, add_last(fss,q)) = replaceTerm(replace_pos(s, t, fss), t, q)



    CP_lemma_aux2a1: LEMMA
    FORALL t, s, (fss: SPP(s)), (q: positions?(s)): 
     (FORALL (i: below[length(fss)]): parallel(fss(i),q))
        => 
    replace_pos(s, t, add_first(q, fss)) = replaceTerm(replace_pos(s, t, fss), t, q)



    CP_lemma_aux2a2: LEMMA
    FORALL t, s, (fss: SPP(s)), (i: below[length(fss)]): 
       replace_pos(s, t, fss) = 
                        replaceTerm(replace_pos(s, t, delete(fss,i)), t, fss(i))


    CP_lemma_aux2a3: LEMMA
    FORALL t, s, (fss1, fss2: SPP(s)): 
      equivalent(fss1, fss2)
         =>
       replace_pos(s, t, fss1) = replace_pos(s, t, fss2)


  END replace_positions

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 31, column 15) for
      % substitution[variable, symbol, arity]
      % generated from assumption substitution.var_countable
  IMP_substitution_TCC1: OBLIGATION
    is_countably_infinite[term[variable, symbol, arity]]
        (V[variable, symbol, arity]);

  % Subtype TCC generated (at line 50, column 40) for  0
      % expected type  below[length(fssp)]
  replace_pos_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (fssp: SPP[variable, symbol, arity](s))):
      NOT length(fssp) = 0 IMPLIES 0 < length(fssp);

  % Subtype TCC generated (at line 50, column 35) for
      % finseq_appl[position[variable, symbol, arity]](fssp)(0)
      % expected type  positions?[variable, symbol, arity](s)
  replace_pos_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (fssp: SPP[variable, symbol, arity](s))):
      NOT length(fssp) = 0 IMPLIES
       positionsOF[variable, symbol, arity]
           (s)(finseq_appl[position[variable, symbol, arity]](fssp)(0));

  % Subtype TCC generated (at line 50, column 48) for  rest(fssp)
      % expected type  SPP
                     %     [variable, symbol, arity](replaceTerm
                     %                               (s,
                     %                                t,
                     %                                finseq_appl
                     %                                [position
                     %                                 [variable,
                     %                                  symbol,
                     %                                  arity]]
                     %                                (fssp)(0)))
  replace_pos_TCC3: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            (fssp: SPP[variable, symbol, arity](s))):
      NOT length(fssp) = 0 IMPLIES
       SPP?[variable, symbol, arity]
           (replaceTerm[variable, symbol, arity]
                (s, t,
                 finseq_appl[position[variable, symbol, arity]](fssp)(0)))
           (rest[position[variable, symbol, arity]](fssp));

  % Termination TCC generated (at line 50, column 5) for
      % replace_pos(replaceTerm(s, t,
      %                         finseq_appl[position[variable, symbol, arity]]
      %                             (fssp)(0)),
      %             t, rest(fssp))
  replace_pos_TCC4: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (fssp: SPP[variable, symbol, arity](s))):
      NOT length(fssp) = 0 IMPLIES
       length(rest[position[variable, symbol, arity]](fssp)) < length(fssp);

  % Subtype TCC generated (at line 63, column 76) for  fss
      % expected type  SPP[variable, symbol, arity](ext(sig)(s))
  replace_pos_is_stable_TCC1: OBLIGATION
    FORALL (s, fss: SPP[variable, symbol, arity](s), sig):
      SPP?[variable, symbol, arity]
          (ext[variable, symbol, arity](sig)(s))(fss);

  % Subtype TCC generated (at line 71, column 42) for  add_first(q, fss)
      % expected type  SPP[variable, symbol, arity](s)
  preserv_first_position_TCC1: OBLIGATION
    FORALL (s, fss: SPP[variable, symbol, arity](s),
            q: positions?[variable, symbol, arity](s)):
      (FORALL (i: below[length(fss)]):
         parallel(finseq_appl[position[variable, symbol, arity]](fss)(i), q))
       IMPLIES
       SPP?[variable, symbol, arity]
           (s)(add_first[position[variable, symbol, arity]](q, fss));

  % Subtype TCC generated (at line 93, column 41) for  q
      % expected type  positions?
                     %     [variable, symbol, arity](replace_pos(s, t, fss))
  preserv_unchanged_subterms_TCC1: OBLIGATION
    FORALL (t, s, fss: SPP[variable, symbol, arity](s),
            q: positions?[variable, symbol, arity](s)):
      (FORALL (i: below[length(fss)]):
         parallel(finseq_appl[position[variable, symbol, arity]](fss)(i), q))
       IMPLIES
       positionsOF[variable, symbol, arity](replace_pos(s, t, fss))(q);

  % Subtype TCC generated (at line 98, column 52) for
      % finseq_appl[position[variable, symbol, arity]](fss)(i)
      % expected type  positions?[variable, symbol, arity](s)
  replace_pos_subterm_to_term_TCC1: OBLIGATION
    FORALL (s, fss: SPP[variable, symbol, arity](s), i: below[length(fss)]):
      positionsOF[variable, symbol, arity]
          (s)(finseq_appl[position[variable, symbol, arity]](fss)(i));

  % Subtype TCC generated (at line 102, column 56) for  Pos_var(s, x)
      % expected type  finite_set[position[variable, symbol, arity]]
  replace_pos_to_term_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity], x: (V)):
      is_finite[position[variable, symbol, arity]]
          (Pos_var[variable, symbol, arity](s, x));

  % Subtype TCC generated (at line 102, column 48) for  set2seq(Pos_var(s, x))
      % expected type  SPP[variable, symbol, arity](s)
  replace_pos_to_term_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity], x: (V)):
      SPP?[variable, symbol, arity]
          (s)
          (set2seq[position[variable, symbol, arity]]
               (Pos_var[variable, symbol, arity](s, x)));

  % Subtype TCC generated (at line 110, column 20) for  add_last(fss, q)
      % expected type  SPP[variable, symbol, arity](s)
  CP_lemma_aux2a_TCC1: OBLIGATION
    FORALL (s, fss: SPP[variable, symbol, arity](s),
            q: positions?[variable, symbol, arity](s)):
      (FORALL (i: below[length(fss)]):
         parallel(finseq_appl[position[variable, symbol, arity]](fss)(i), q))
       IMPLIES
       SPP?[variable, symbol, arity]
           (s)(add_last[position[variable, symbol, arity]](fss, q));

  % Subtype TCC generated (at line 125, column 52) for  delete(fss, i)
      % expected type  SPP[variable, symbol, arity](s)
  CP_lemma_aux2a2_TCC1: OBLIGATION
    FORALL (s, fss: SPP[variable, symbol, arity](s), i: below[length(fss)]):
      SPP?[variable, symbol, arity]
          (s)(delete[position[variable, symbol, arity]](fss, i));

  % Subtype TCC generated (at line 125, column 71) for
      % finseq_appl[position[variable, symbol, arity]](fss)(i)
      % expected type  positions?
                     %     [variable, symbol, arity](replace_pos
                     %                               (s, t, delete(fss, i)))
  CP_lemma_aux2a2_TCC2: OBLIGATION
    FORALL (t, s, fss: SPP[variable, symbol, arity](s),
            i: below[length(fss)]):
      positionsOF[variable, symbol, arity]
          (replace_pos(s, t,
                       delete[position[variable, symbol, arity]](fss, i)))
          (finseq_appl[position[variable, symbol, arity]](fss)(i));


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%            
  %% Last Modified On: September 29, 2009                                      
  %%                                                                          
  %%----------------------------------------------------------------------------


  critical_pairs_aux[variable:TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY

   BEGIN

     ASSUMING
   
       IMPORTING variables_term[variable,symbol, arity],
                 sets_aux@countability[term],
                 sets_aux@countable_props[term]
   
         var_countable: ASSUMPTION is_countably_infinite(V)
        
     ENDASSUMING


       IMPORTING rewrite_rules[variable,symbol, arity],
                 replace_positions[variable,symbol, arity]
   

            s, t, t1, t2: VAR term
        sigma, sg1, sg2, 
       sig, delta, alpha: VAR Sub
                     rho: VAR Ren 
             e1, e2, e2p: VAR rewrite_rule
                       E: VAR set[rewrite_rule]
                       R: VAR pred[[term, term]]
                       x: VAR (V)


   CP_lemma_aux2b: LEMMA
     FORALL R, t, x, sg1, sg2, (fstp: SPP(t)):
       LET Mtn = replace_pos(ext(sg1)(t), ext(sg2)(x), fstp) IN
       (FORALL (i: below[length(fstp)]): subtermOF(t,fstp(i)) = x) &
                                         comp_cont?(R) & 
                                         RSigma(R, sg1, sg2, x) 
                   => iterate(R, length(fstp))(ext(sg1)(t), Mtn)




   CP_lemma_aux2c1: LEMMA
     FORALL R, t, x, sg1, sg2, (fst: SPP(t)), (q: positions?(t)):
         ( FORALL (i: below[length(fst)]): parallel(fst(i),q)           &
                                            subtermOF(t, fst(i)) = x  ) &
                                            subtermOF(t, q) = x         &
                                            comp_cont?(R)               & 
                                            RSigma(R, sg1, sg2, x)
     => 
  iterate(R, length(fst))(replace_pos(ext(sg1)(t), ext(sg2)(x), #(q)), 
                          replace_pos(ext(sg1)(t), ext(sg2)(x), add_first(q,fst)))



   CP_lemma_aux2c: LEMMA
     FORALL R, t, x, sg1, sg2, (fstp: SPP(t)):
       fstp`length /= 0 &
       ( FORALL (i: below[length(fstp)]): subtermOF(t,fstp(i)) = x  ) &
                                          comp_cont?(R) & 
                                          RSigma(R, sg1, sg2, x)
     => ( FORALL (i: below[length(fstp)]):
  iterate(R, length(fstp) - 1)(replace_pos(ext(sg1)(t), ext(sg2)(x), #(fstp(i))), 
                               replace_pos(ext(sg1)(t), ext(sg2)(x), fstp))  )


   

  CP_lemma_aux2d: LEMMA
     FORALL R, t, x, sg1, sg2:
       LET Posv = Pos_var(t, x),
           seqv = set2seq(Posv) IN
       comp_cont?(R) & 
       RSigma(R, sg1, sg2, x) 
          => replace_pos(ext(sg1)(t), ext(sg2)(x), seqv) = ext(sg2)(t)


  END critical_pairs_aux

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 32, column 15) for
      % rewrite_rules[variable, symbol, arity]
      % generated from assumption rewrite_rules.var_countable
  IMP_rewrite_rules_TCC1: OBLIGATION
    is_countably_infinite[term[variable, symbol, arity]]
        (V[variable, symbol, arity]);

  % Subtype TCC generated (at line 48, column 53) for  fstp
      % expected type  SPP[variable, symbol, arity](ext(sg1)(t))
  CP_lemma_aux2b_TCC1: OBLIGATION
    FORALL (t, x, sg1, sg2, fstp: SPP[variable, symbol, arity](t)):
      SPP?[variable, symbol, arity]
          (ext[variable, symbol, arity](sg1)(t))(fstp);

  % Subtype TCC generated (at line 49, column 51) for
      % finseq_appl[position[variable, symbol, arity]](fstp)(i)
      % expected type  positions?[variable, symbol, arity](t)
  CP_lemma_aux2b_TCC2: OBLIGATION
    FORALL (t, x, sg1, sg2, fstp: SPP[variable, symbol, arity](t),
            Mtn: term[variable, symbol, arity]):
      Mtn = replace_pos(ext(sg1)(t), ext(sg2)(x), fstp) IMPLIES
       (FORALL (i: below[length(fstp)]):
          positionsOF[variable, symbol, arity]
              (t)(finseq_appl[position[variable, symbol, arity]](fstp)(i)));

  % Subtype TCC generated (at line 60, column 55) for
      % finseq_appl[position[variable, symbol, arity]](fst)(i)
      % expected type  positions?[variable, symbol, arity](t)
  CP_lemma_aux2c1_TCC1: OBLIGATION
    FORALL (t, x, sg1, sg2, fst: SPP[variable, symbol, arity](t),
            q: positions?[variable, symbol, arity](t),
            i: below[length(fst)]):
      parallel(finseq_appl[position[variable, symbol, arity]](fst)(i), q)
       IMPLIES
       positionsOF[variable, symbol, arity]
           (t)(finseq_appl[position[variable, symbol, arity]](fst)(i));

  % Subtype TCC generated (at line 65, column 62) for   #(q)
      % expected type  SPP[variable, symbol, arity](ext(sg1)(t))
  CP_lemma_aux2c1_TCC2: OBLIGATION
    FORALL (R, t, x, sg1, sg2, fst: SPP[variable, symbol, arity](t),
            q: positions?[variable, symbol, arity](t)):
      (FORALL (i: below[length(fst)]):
         parallel(finseq_appl[position[variable, symbol, arity]](fst)(i), q)
          &
          subtermOF(t,
                    finseq_appl[position[variable, symbol, arity]](fst)(i))
           = x)
       AND subtermOF(t, q) = x AND comp_cont?(R) AND RSigma(R, sg1, sg2, x)
       IMPLIES
       SPP?[variable, symbol, arity]
           (ext[variable, symbol, arity](sg1)(t))
           ( #[position[variable, symbol, arity]](q));

  % Subtype TCC generated (at line 66, column 62) for  add_first(q, fst)
      % expected type  SPP[variable, symbol, arity](ext(sg1)(t))
  CP_lemma_aux2c1_TCC3: OBLIGATION
    FORALL (R, t, x, sg1, sg2, fst: SPP[variable, symbol, arity](t),
            q: positions?[variable, symbol, arity](t)):
      (FORALL (i: below[length(fst)]):
         parallel(finseq_appl[position[variable, symbol, arity]](fst)(i), q)
          &
          subtermOF(t,
                    finseq_appl[position[variable, symbol, arity]](fst)(i))
           = x)
       AND subtermOF(t, q) = x AND comp_cont?(R) AND RSigma(R, sg1, sg2, x)
       IMPLIES
       SPP?[variable, symbol, arity]
           (ext[variable, symbol, arity](sg1)(t))
           (add_first[position[variable, symbol, arity]](q, fst));

  % Subtype TCC generated (at line 73, column 52) for
      % finseq_appl[position[variable, symbol, arity]](fstp)(i)
      % expected type  positions?[variable, symbol, arity](t)
  CP_lemma_aux2c_TCC1: OBLIGATION
    FORALL (t, x, sg1, sg2, fstp: SPP[variable, symbol, arity](t)):
      fstp`length /= 0 IMPLIES
       (FORALL (i: below[length(fstp)]):
          positionsOF[variable, symbol, arity]
              (t)(finseq_appl[position[variable, symbol, arity]](fstp)(i)));

  % Subtype TCC generated (at line 77, column 67) for
      %  #(finseq_appl[position[variable, symbol, arity]](fstp)(i))
      % expected type  SPP[variable, symbol, arity](ext(sg1)(t))
  CP_lemma_aux2c_TCC2: OBLIGATION
    FORALL (R, t, x, sg1, sg2, fstp: SPP[variable, symbol, arity](t)):
      fstp`length /= 0 AND
       (FORALL (i: below[length(fstp)]):
          subtermOF(t,
                    finseq_appl[position[variable, symbol, arity]](fstp)(i))
           = x)
        AND comp_cont?(R) AND RSigma(R, sg1, sg2, x)
       IMPLIES
       (FORALL (i1: below[length(fstp)]):
          SPP?[variable, symbol, arity]
              (ext[variable, symbol, arity](sg1)(t))
              ( #[position[variable, symbol, arity]]
                   (finseq_appl[position[variable, symbol, arity]]
                        (fstp)(i1))));

  % Subtype TCC generated (at line 77, column 11) for  length(fstp) - 1
      % expected type  nat
  CP_lemma_aux2c_TCC3: OBLIGATION
    FORALL (R, t, x, sg1, sg2, fstp: SPP[variable, symbol, arity](t)):
      fstp`length /= 0 AND
       (FORALL (i: below[length(fstp)]):
          subtermOF(t,
                    finseq_appl[position[variable, symbol, arity]](fstp)(i))
           = x)
        AND comp_cont?(R) AND RSigma(R, sg1, sg2, x)
       IMPLIES (FORALL (i1: below[length(fstp)]): length(fstp) - 1 >= 0);

  % Subtype TCC generated (at line 86, column 24) for  Posv
      % expected type  finite_set[position[variable, symbol, arity]]
  CP_lemma_aux2d_TCC1: OBLIGATION
    FORALL (t, x, sg1, sg2, Posv: positions[variable, symbol, arity]):
      Posv = Pos_var(t, x) IMPLIES
       is_finite[position[variable, symbol, arity]](Posv);

  % Subtype TCC generated (at line 89, column 49) for  seqv
      % expected type  SPP[variable, symbol, arity](ext(sg1)(t))
  CP_lemma_aux2d_TCC2: OBLIGATION
    FORALL (R, t, x, sg1, sg2, Posv: positions[variable, symbol, arity]):
      Posv = Pos_var(t, x) IMPLIES
       (FORALL (seqv: finite_sequence[position[variable, symbol, arity]]):
          comp_cont?(R) AND RSigma(R, sg1, sg2, x) AND seqv = set2seq(Posv)
           IMPLIES
           SPP?[variable, symbol, arity]
               (ext[variable, symbol, arity](sg1)(t))(seqv));


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%                   
  %% Last Modified On: September 29, 2009                                      
  %%                                                                          
  %%----------------------------------------------------------------------------


  critical_pairs[variable:TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY

   BEGIN

     ASSUMING
   
       IMPORTING variables_term[variable,symbol, arity],
                 sets_aux@countability[term],
                 sets_aux@countable_props[term]
   
         var_countable: ASSUMPTION is_countably_infinite(V)
        
     ENDASSUMING

      IMPORTING critical_pairs_aux[variable,symbol, arity],
                reduction[variable,symbol, arity],
                unification[variable,symbol, arity]
   

            s, t, t1, t2: VAR term
         sigma, sg1, sg2, 
            alpha, delta: VAR Sub
         rho, rho1, rho2: VAR Ren 
             e1, e2, e2p: VAR rewrite_rule
                       E: VAR set[rewrite_rule]
                       R: VAR pred[[term, term]]
                       x: VAR (V)
   

  %%%% Definition of Critical Pair (CP?) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   CP?(E)(t1, t2): bool = 
      EXISTS (sigma,rho,
             (e1 | member(e1, E)), 
             (e2p | member(e2p, E)), 
             (p: positions?(lhs(e1)))): 
           LET e2 = (# lhs := ext(rho)(lhs(e2p)), rhs := ext(rho)(rhs(e2p)) #) IN
                 disjoint?(Vars(lhs(e1)),Vars(lhs(e2)))                        &
                 NOT vars?(subtermOF(lhs(e1), p))                              &
                 mgu(sigma)(subtermOF(lhs(e1), p), lhs(e2))                    &
                 t1 = ext(sigma)(rhs(e1))                                      &
                 t2 = replaceTerm(ext(sigma)(lhs(e1)), ext(sigma)(rhs(e2)), p)


  %%%% The case critical overlap %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  CP_lemma_aux1a: LEMMA 
   FORALL E, (p: position), (e1 | member(e1, E)), (e2 | member(e2, E)):
   ( positionsOF(lhs(e1))(p)                                                    & 
     NOT vars?(subtermOF(lhs(e1), p))                                           &
     ext(sg1)(subtermOF(lhs(e1), p)) = ext(sg2)(lhs(e2)) )
          => 
            EXISTS alpha, rho: 
               disjoint?(Vars(lhs(e1)), Vars(ext(rho)(lhs(e2))))                &
               ext(sg1)(subtermOF(lhs(e1), p)) = ext(comp(alpha, rho))(lhs(e2))


   CP_lemma_aux1: LEMMA
    FORALL E, (p: position), (e1 | member(e1, E)), (e2 | member(e2, E)):
    ( positionsOF(lhs(e1))(p)                                                & 
      NOT vars?(subtermOF(lhs(e1), p))                                       &
      ext(sg1)(subtermOF(lhs(e1), p)) = ext(sg2)(lhs(e2)) )
           => 
            EXISTS t1, t2, delta: 
              CP?(E)(t1, t2)                                                 &
              ext(delta)(t1) = ext(sg1)(rhs(e1))                             &
            ext(delta)(t2) = replaceTerm(ext(sg1)(lhs(e1)), ext(sg2)(rhs(e2)), p)



  %%%% The case non-critical overlap %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


   CP_lemma_aux2: LEMMA
     FORALL R, t, x, sg1, sg2:
      LET Posv = Pos_var(t, x),
          seqv = set2seq(Posv) IN
       comp_cont?(R) & 
       RSigma(R, sg1, sg2, x) 
          => 
          (FORALL (i: below[length(seqv)]):
            RTC(R)(replace_pos(ext(sg1)(t), ext(sg2)(x), #(seqv(i))),ext(sg2)(t)))
                                    &
                    RTC(R)(ext(sg1)(t), ext(sg2)(t))




  %%%% Critical Pair Theorem %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  CP_Theorem: THEOREM 
   FORALL E: 
     LET RRE = reduction?(E) IN
     locally_confluent?(RRE)
                 <=> 
  (FORALL t1, t2: CP?(E)(t1, t2) => joinable?(RRE)(t1,t2))

  END critical_pairs

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 31, column 14) for
      % critical_pairs_aux[variable, symbol, arity]
      % generated from assumption critical_pairs_aux.var_countable
  IMP_critical_pairs_aux_TCC1: OBLIGATION
    is_countably_infinite[term[variable, symbol, arity]]
        (V[variable, symbol, arity]);

  % Subtype TCC generated (at line 58, column 74) for  p
      % expected type  positions?
                     %     [variable, symbol, arity](ext(sigma)(lhs(e1)))
  CP?_TCC1: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            t1: term[variable, symbol, arity],
            sigma: Sub[variable, symbol, arity],
            rho: Ren[variable, symbol, arity],
            (e1: rewrite_rule[variable, symbol, arity]
                 | member[rewrite_rule[variable, symbol, arity]](e1, E)),
            (e2p: rewrite_rule[variable, symbol, arity]
                 | member[rewrite_rule[variable, symbol, arity]](e2p, E)),
            (p:
               positions?
                   [variable, symbol, arity](lhs[variable, symbol, arity]
                                             (e1))),
            e2:
              [# lhs: term[variable, symbol, arity],
                 rhs: term[variable, symbol, arity] #]):
           t1 = ext(sigma)(rhs(e1))
       AND mgu(sigma)(subtermOF(lhs(e1), p), lhs(e2))
       AND NOT vars?(subtermOF(lhs(e1), p))
       AND disjoint?(Vars(lhs(e1)), Vars(lhs(e2)))
       AND e2 = (# lhs := ext(rho)(lhs(e2p)), rhs := ext(rho)(rhs(e2p)) #)
       IMPLIES
       positionsOF[variable, symbol, arity]
           (ext[variable, symbol, arity]
                (sigma)(lhs[variable, symbol, arity](e1)))
           (p);

  % Subtype TCC generated (at line 71, column 51) for  comp(alpha, rho)
      % expected type  Sub[variable, symbol, arity]
  CP_lemma_aux1a_TCC1: OBLIGATION
    FORALL (sg1, sg2: Sub[variable, symbol, arity], E,
            p: position[variable, symbol, arity],
            e1: rewrite_rule[variable, symbol, arity]
                | member[rewrite_rule[variable, symbol, arity]](e1, E),
            e2: rewrite_rule[variable, symbol, arity]
                | member[rewrite_rule[variable, symbol, arity]](e2, E)):
      positionsOF(lhs(e1))(p) AND
       NOT vars?(subtermOF(lhs(e1), p)) AND
        ext(sg1)(subtermOF(lhs(e1), p)) = ext(sg2)(lhs(e2))
       IMPLIES
       (FORALL (alpha, rho):
          disjoint?(Vars(lhs(e1)), Vars(ext(rho)(lhs(e2)))) IMPLIES
           Sub?[variable, symbol, arity]
               (comp[variable, symbol, arity](alpha, rho)));

  % Subtype TCC generated (at line 83, column 77) for  p
      % expected type  positions?[variable, symbol, arity](ext(sg1)(lhs(e1)))
  CP_lemma_aux1_TCC1: OBLIGATION
    FORALL (sg1, sg2: Sub[variable, symbol, arity], E,
            p: position[variable, symbol, arity],
            e1: rewrite_rule[variable, symbol, arity]
                | member[rewrite_rule[variable, symbol, arity]](e1, E),
            e2: rewrite_rule[variable, symbol, arity]
                | member[rewrite_rule[variable, symbol, arity]](e2, E)):
      positionsOF(lhs(e1))(p) AND
       NOT vars?(subtermOF(lhs(e1), p)) AND
        ext(sg1)(subtermOF(lhs(e1), p)) = ext(sg2)(lhs(e2))
       IMPLIES
       (FORALL (t1, t2, delta):
          ext(delta)(t1) = ext(sg1)(rhs(e1)) AND CP?(E)(t1, t2) IMPLIES
           positionsOF[variable, symbol, arity]
               (ext[variable, symbol, arity]
                    (sg1)(lhs[variable, symbol, arity](e1)))
               (p));

  % Subtype TCC generated (at line 93, column 23) for  Posv
      % expected type  finite_set[position[variable, symbol, arity]]
  CP_lemma_aux2_TCC1: OBLIGATION
    FORALL (t, x, sg1, sg2, Posv: positions[variable, symbol, arity]):
      Posv = Pos_var(t, x) IMPLIES
       is_finite[position[variable, symbol, arity]](Posv);

  % Subtype TCC generated (at line 98, column 55) for
      %  #(finseq_appl[position[variable, symbol, arity]](seqv)(i))
      % expected type  SPP[variable, symbol, arity](ext(sg1)(t))
  CP_lemma_aux2_TCC2: OBLIGATION
    FORALL (R, t, x, sg1, sg2, Posv: positions[variable, symbol, arity]):
      Posv = Pos_var(t, x) IMPLIES
       (FORALL (seqv: finite_sequence[position[variable, symbol, arity]]):
          comp_cont?(R) AND RSigma(R, sg1, sg2, x) AND seqv = set2seq(Posv)
           IMPLIES
           (FORALL (i: below[length(seqv)]):
              SPP?[variable, symbol, arity]
                  (ext[variable, symbol, arity](sg1)(t))
                  ( #[position[variable, symbol, arity]]
                       (finseq_appl[position[variable, symbol, arity]]
                            (seqv)(i)))));


body:
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %% Orthogonality contains specification of notions related with orthogonal
  %% rewriting systems, parallel rewriting and the formalization of theorems
  %% of confluence of left and right linear non-ambiguous TRSs and the main 
  %% theorem of confluence of orthogonal TRSs.
  %% The inductive proof of the main theorem uses the Parallel Moves Lemma. 
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  orthogonality[variable:TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY

   BEGIN

     ASSUMING
   
       IMPORTING 
                 variables_term[variable,symbol, arity],
                 sets_aux@countability[term],
                 sets_aux@countable_props[term]
   
       var_countable: ASSUMPTION	 is_countably_infinite(V)
        

     ENDASSUMING


      IMPORTING critical_pairs[variable,symbol,arity],
                mem_test[term],
                mem_test[position],
                mem_test[rewrite_rule],
                mem_test[Sub]       
                                         
                                 n: VAR nat
                      s, t, t1, t2: VAR term 
     sigma, sg1, sg2, alpha, delta, theta: VAR Sub
                p,q,p1,p2,p3,q1,q2: VAR position
                   rho, rho1, rho2: VAR Ren 
     e, e1o, e2o, e1, e1p, e2, e2p: VAR rewrite_rule
                                 E: VAR set[rewrite_rule]
                                 R: VAR pred[[term, term]]
                              x, y: VAR (V)
              fsq, fsp, fsp1, fsp2: VAR finseq[position]
                   fse, fse1, fse2: VAR finseq[rewrite_rule]
                   fss, fss1, fss2: VAR finseq[Sub]
                               fsv: VAR finseq[(V)]
                   fst, fst1, fst2: VAR finseq[term]
                      PO1, PO2, PE: VAR PP
   
  %%%% Basic specific definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%% ntCP? is the predicate for non trivially generated CPs %%%%%%%%%%%%%%%%%%%%%%%%
  %%%%% This in contrast with CP? excludes all CPs generated by sobreposition of %%%%%%
  %%%%% a rule with itself at root position and is used to define ambiguity.     %%%%%%
  %%%%% The necessity of this notion was gently pointed out by Rene Thiemann.    %%%%%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    ntCP?(E)(t1, t2): bool =
      EXISTS (sigma,rho,
             (e1 | member(e1, E)),
             (e2p | member(e2p, E)),
             (p: positions?(lhs(e1)))):
           NOT (e1 = e2p AND p = empty_seq) AND
           LET e2 = (# lhs := ext(rho)(lhs(e2p)), rhs := ext(rho)(rhs(e2p)) #) IN
                 disjoint?(Vars(lhs(e1)),Vars(lhs(e2)))                        &
                 NOT vars?(subtermOF(lhs(e1), p))                              &
                 mgu(sigma)(subtermOF(lhs(e1), p), lhs(e2))                    &
                 t1 = ext(sigma)(rhs(e1))                                      &
                 t2 = replaceTerm(ext(sigma)(lhs(e1)), ext(sigma)(rhs(e2)), p)

   ntCP_lemma_aux1: LEMMA
     FORALL E, (p: position), (e1 | member(e1, E)), (e2 | member(e2, E)):
      ( ( positionsOF(lhs(e1))(p) &
         NOT vars?(subtermOF(lhs(e1), p))                                     &
         ext(sg1)(subtermOF(lhs(e1), p)) = ext(sg2)(lhs(e2)) )                &
         NOT (e1 = e2 AND p = empty_seq) )
            =>
             EXISTS t1, t2, delta:
               ntCP?(E)(t1, t2)                                               &
               ext(delta)(t1) = ext(sg1)(rhs(e1))                             &
               ext(delta)(t2) = replaceTerm(ext(sg1)(lhs(e1)), ext(sg2)(rhs(e2)), p)

   Ambiguous?(E): bool =  EXISTS (t1, t2) : ntCP?(E)(t1,t2)

   linear?(t): bool = FORALL (x | member(x,Vars(t))) : Card[position](Pos_var(t,x)) = 1 

   Right_Linear?(E): bool = FORALL (e1 | member(e1, E)) : linear?(rhs(e1))   

   Left_Linear?(E): bool = FORALL (e1 | member(e1, E)) : linear?(lhs(e1))   

   Linear?(E): bool = Left_Linear?(E) AND Right_Linear?(E)

   
   local_joinability_triangle?(R) : bool = FORALL(t, t1, t2) : R(t, t1) & R(t, t2) =>
                 EXISTS s : (RC(R)(t1, s) & RC(R)(t2, s))


  %%%% Some Lemmas %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   Orth_lemma_aux0 : LEMMA
    Card(Pos_var(t, x)) = 1  => EXISTS (p1) : (positionsOF(t)(p1) AND subtermOF(t,p1) = x )
   
   equality_replaceTerm : LEMMA 
    positionsOF(s)(p) =>
    (t1 = t2 iff replaceTerm(s, t1, p) =  replaceTerm(s, t2, p))


   Var_occurs_only_once_also_in_subterms : LEMMA
    vars?(x) & positionsOF(s)(p) & p`length /= 0 &
    x = subtermOF(s, p) &
    card(Pos_var(s,x)) = 1   => 
        card(Pos_var(subtermOF(s, #(first(p))),x)) = 1	
   

   SigmaP_equivalence : LEMMA 
    (NOT member(x, Vars(s)) &
    positionsOF(ext(sigma)(x))(p2))
        =>   ext(SigmaP(sigma, t, x, p2))(s) = ext(sigma)(s)


   SigmaP_vs_replaceTerm_linearR : LEMMA
    vars?(x) & positionsOF(s)(p1) &
    positionsOF(ext(sigma)(x))(p2) &
    x = subtermOF(s, p1) &
    Card(Pos_var(s,x)) = 1   => 
        ext(SigmaP(sigma, t, x, p2))(s) =
           replaceTerm( ext(sigma)(s), t, p1 o p2)
   
   Orth_lemma_aux: LEMMA
       LET e1o = (# lhs := ext(rho1)(lhs(e1p)), rhs := ext(rho1)(rhs(e1p)) #) IN
         LET e2o = (# lhs := ext(rho2)(lhs(e2p)), rhs := ext(rho2)(rhs(e2p)) #) IN
         member(e1p,E) & 
         member(e2p,E) &
         positionsOF(t)(p1) &
         positionsOF(t)(p3) &
         NOT Ambiguous?(E) &
         p3 = p1 o p2 &
         Linear?(E) &
           subtermOF(t, p1) = ext(sg1)(lhs(e1o)) & 
           t1 = replaceTerm(t, ext(sg1)(rhs(e1o)), p1) &
           subtermOF(t, p3) = ext(sg2)(lhs(e2o)) &
           t2 = replaceTerm(t, ext(sg2)(rhs(e2o)), p3) &
           disjoint?(Vars(lhs(e1o)),Vars(t))&
           disjoint?(Vars(lhs(e2o)),Vars(t))
     =>
       EXISTS s:  (RC(reduction?(E))(t1, s) & RC(reduction?(E))(t2, s))

   Linear_and_Non_ambiguous_implies_triangle: LEMMA
    FORALL (E) :  
      (Linear?(E) AND NOT Ambiguous?(E) ) IMPLIES
       local_joinability_triangle?(reduction?(E))

   Triangle_implies_conflent: LEMMA
          local_joinability_triangle?(R)
          IMPLIES confluent?(R)

   Linear_and_Non_ambiguous_implies_confluent: LEMMA
    FORALL (E) :  
      ((Linear?(E) AND NOT Ambiguous?(E) ) IMPLIES
       confluent?(reduction?(E)))
   


  %%%% More definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   Orthogonal?(E): bool =  Left_Linear?(E) & NOT Ambiguous?(E)

   Orthogonal: TYPE = (Orthogonal?)


   replace_par_pos(s, (fsp : SPP(s)), fst | fst`length = fsp`length): RECURSIVE 
      term =
        IF length(fsp) = 0
         THEN 
          s
         ELSE
          replace_par_pos(replaceTerm(s, fst(0), fsp(0)), rest(fsp), rest(fst))
        ENDIF
     MEASURE length(fsp)

   reduction_fix?(E)(s,t,(p:positions?(s))): bool =
        EXISTS (e|member(e,E), sigma):
          subtermOF(s,p)=ext(sigma)(lhs(e))
            AND t=replaceTerm(s,ext(sigma)(rhs(e)),p)

   sigma_rhs(fss, (fse | fse`length = fss`length)): finseq[term] = 
       IF fss`length = 0 THEN empty_seq[term]
       ELSE
            (# length := fss`length,
                  seq := (LAMBDA (i: below[fss`length]): ext(fss(i))(rhs(fse(i)))) #)
       ENDIF

   sigma_lhs(fss, (fse | fse`length = fss`length)): finseq[term] = 
       IF fss`length = 0 THEN empty_seq[term]
       ELSE
            (# length := fss`length,
                  seq := (LAMBDA (i: below[fss`length]): ext(fss(i))(lhs(fse(i)))) #)
       ENDIF

    subtermsOF(t,(fsp:SP(t))): 
              finseq[term] = (# length := fsp`length,
                                seq := (LAMBDA (i: below[fsp`length]): subtermOF(t,fsp(i))) #);

   parallel_reduction_fix?(E)(s,t, (fsp: SPP(s))): bool =  
      EXISTS ((fse | member(fse, E)), fss) :
             fsp`length = fse`length AND fsp`length = fss`length
             AND subtermsOF(s,fsp) = sigma_lhs(fss, fse)
             AND t = replace_par_pos(s, fsp, sigma_rhs(fss, fse))

   parallel_reduction?(E)(s,t): bool =  EXISTS (fsp: SPP(s)): parallel_reduction_fix?(E)(s,t,fsp)


  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   sub_pos((fsp : PP), p): RECURSIVE finseq[position] =
       IF  length(fsp) = 0 THEN empty_seq[position]
          ELSIF p <= fsp`seq(0) AND p /= fsp`seq(0)
                  THEN add_first(fsp`seq(0), sub_pos(rest(fsp), p))
                  ELSE sub_pos(rest(fsp), p)
       ENDIF
      MEASURE length(fsp)

  % Positions of fsp1 that have positions of fsp2 strictly below or are parallel to fsp2
   Pos_Over((fsp1 : PP), (fsp2 : PP)): RECURSIVE finseq[position] =
     (IF length(fsp1) = 0
         THEN empty_seq[position]
         ELSE (IF ( length(sub_pos(fsp2, fsp1`seq(0))) > 0  
                   OR PP?(add_first(fsp1`seq(0), fsp2)))
                  THEN add_first(fsp1`seq(0), Pos_Over(rest(fsp1), fsp2))
                  ELSE Pos_Over(rest(fsp1), fsp2)
               ENDIF)
       ENDIF)
      MEASURE length(fsp1)

  % Positions of fsp1 that are strictly below some position of fsp2.

   Pos_Under((fsp1 : PP), (fsp2 : PP)): RECURSIVE finseq[position] =
       IF length(fsp2)=0
          THEN empty_seq[position]
          ELSE sub_pos(fsp1, fsp2`seq(0)) o Pos_Under(fsp1,rest(fsp2))
       ENDIF
     MEASURE length(fsp2)

  % Positions of fsp1 and fsp2

   Pos_Equal((fsp1 : PP), (fsp2 : PP)): RECURSIVE finseq[position] =
       IF length(fsp1) = 0 THEN empty_seq[position]
       ELSIF member_seq(fsp1`seq(0),fsp2)
       THEN add_first(fsp1`seq(0), Pos_Equal(rest(fsp1), fsp2))
       ELSE Pos_Equal(rest(fsp1), fsp2)
       ENDIF
    MEASURE length(fsp1)

  %%%% Lemmas about parallel reduction %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   comp_SPP_commute: LEMMA
      SPP?(s)(fsp1 o fsp2) IMPLIES SPP?(s)(fsp2 o fsp1)

   sub_pos_element: LEMMA
      PP?(fsp) & member_seq(p1 o p2, fsp) & p2`length /= 0
      IMPLIES sub_pos(fsp, p1)`length /= 0 & 
              member_seq(p1 o p2, sub_pos(fsp, p1))

   parallel_pos_are_dif: LEMMA
      PP?(fsp) IMPLIES FORALL(i,j: below[fsp`length]): i /= j => fsp(i) /= fsp(j)

   same_pos_in_Pos_Equal: LEMMA
      PP?(fsp1) & PP?(fsp2) & member_seq(p, fsp1) & member_seq(p, fsp2)
      IMPLIES member_seq(p, Pos_Equal(fsp1, fsp2))

   Pos_Over_is_sub_seq: LEMMA
      PP?(fsp1) & PP?(fsp2)
       IMPLIES subseq(Pos_Over(fsp1,fsp2), fsp1)

   Pos_Equal_is_sub_seq: LEMMA
      PP?(fsp1) & PP?(fsp2)
      IMPLIES subseq(Pos_Equal(fsp1,fsp2),fsp1)
   
   sub_pos_is_sub_seq: LEMMA
      PP?(fsp) IMPLIES subseq(sub_pos(fsp,p), fsp)
   
   Pos_Under_is_sub_seq: LEMMA
      PP?(fsp1) & PP?(fsp2)
      IMPLIES subseq(Pos_Under(fsp1,fsp2), fsp1)

   Pos_Over_is_PP: LEMMA
      PP?(fsp1) & PP?(fsp2) IMPLIES
      PP?(Pos_Over(fsp1, fsp2))

   Pos_Over_is_SPP: LEMMA 
      SPP?(s)(fsp1) & SPP?(s)(fsp2) IMPLIES
      SPP?(s)(Pos_Over(fsp1, fsp2))

   pos_up_in_Pos_Over: LEMMA
      PP?(fsp1) & PP?(fsp2) &
      p2`length /= 0 & member_seq(p1, fsp1) & member_seq(p1 o p2, fsp2)
      IMPLIES member_seq(p1, Pos_Over(fsp1, fsp2))

   parallel_pos_in_Pos_Over:  LEMMA    
      PP?(fsp1) & PP?(fsp2) & member_seq(p, fsp1) & PP?(add_first(p, fsp2))
      IMPLIES member_seq(p, Pos_Over(fsp1, fsp2))

   sub_pos_in_Pos_Under_aux: LEMMA
      PP?(fsp) & member_seq(p2, fsp) &
      p1 /= p2 & p1 <= p2 IMPLIES
      member_seq(p2, sub_pos(fsp,p1))
      
   sub_pos_in_Pos_Under: LEMMA
      PP?(fsp1) & PP?(fsp2) & member_seq(p1, fsp1) &
      member_seq(p2, fsp2) & p1 /= p2 & p2 <= p1 IMPLIES
        member_seq(p1, Pos_Under(fsp1, fsp2))

   sub_pos_is_under: LEMMA
      PP?(fsp) & member_seq(p1, sub_pos(fsp,p))
        IMPLIES p<=p1 & p/=p1

   sub_pos_is_PP: LEMMA
      PP?(fsp) IMPLIES PP?(sub_pos(fsp,p))

   sub_pos_is_SPP: LEMMA
      SPP?(s)(fsp) IMPLIES SPP?(s)(sub_pos(fsp,p))

   Pos_Under_character: LEMMA
      PP?(fsp1) & PP?(fsp2) & member_seq(p, Pos_Under(fsp1,fsp2))
       IMPLIES  EXISTS(j:below[fsp2`length]):
             member_seq(p, sub_pos(fsp1,fsp2(j)))

   union_positions: LEMMA 
      PP?(fsp1) & PP?(fsp2) IMPLIES
      seq2set(fsp1) = seq2set(Pos_Over(fsp1, fsp2) o Pos_Equal(fsp1, fsp2) o Pos_Under(fsp1, fsp2))

  %% Auxiliary lemma on sigma_rhs.
   sigma_rhs_rest: LEMMA
       fse`length = fss`length 
          IMPLIES rest(sigma_rhs(fss, fse)) = sigma_rhs(rest(fss), rest(fse))

  %% Auxiliary lemma on sigma_rhs. 
   sigma_rhs_o: LEMMA
     fse1`length = fss1`length AND fse2`length = fss2`length
       IMPLIES
         sigma_rhs(fss1 o fss2, fse1 o fse2) = sigma_rhs(fss1, fse1) o sigma_rhs(fss2, fse2)

  %% Auxiliary lemma on subtermsOF.
   subtermsOF_rest: LEMMA
       SP?(t)(fsp) IMPLIES rest(subtermsOF(t,fsp)) = subtermsOF(t, rest(fsp))

  % Lemma of inclusions of the rewriting relation in the parallel rewriting relation
  % and the latter in the reflexive-transitive closure of the former relation.
   parallel_reduction_inclusion: LEMMA 
    subset?(reduction?(E), parallel_reduction?(E)) 
     & subset?(parallel_reduction?(E), RTC(reduction?(E)))

  % The reflexive-transitive clousures of the rewriting and the parallel 
  % rewriting relations are equivalent.
   parallel_reduction_RTC: LEMMA
    RTC(reduction?(E)) = RTC(parallel_reduction?(E))

  % Once you rewrite in parallel at positions fsp which are
  % parallel to position p ("p || fsp"), a term in which position p is 
  % preserved is obtained.
   replace_par_pos_preservs_pos: LEMMA
    SPP?(t)(add_first(p,fsp)) AND fst`length = fsp`length
          => positionsOF(replace_par_pos(t, fsp, fst))(p)

  % When you replace the subterms at the positions in fsp,
  % those positions are preserved in the resulting term.
    replace_par_pos_preservs_PP: LEMMA
     SPP?(t)(fsp) AND fst`length = fsp`length
           => (FORALL (i : below[fsp`length]) : positionsOF(replace_par_pos(t, fsp, fst))(fsp(i)))

  % Same of replace_par_pos_preserv_pos but instead for
  % a unique position p || fsp for a sequence of positions fsq || fsp.
   replace_par_pos_preservs_PP_o_PP: LEMMA
    SPP?(t)(fsp o fsq ) AND fst`length = fsp`length
          => (FORALL (i : below[fsq`length]) : positionsOF(replace_par_pos(t, fsp, fst))(fsq(i)))

  % If you replace the first parallel position firstly or lastly,
  % that does not change the resulting term.
   replace_par_pos_equivalence: LEMMA
    SPP?(s)(fsp) AND fsp`length /= 0 AND fst`length = fsp`length
      => replace_par_pos(replaceTerm(s, fst(0), fsp(0)), rest(fsp), rest(fst)) = 
              replaceTerm(replace_par_pos(s, rest(fsp), rest(fst)), fst(0), fsp(0))

  % Generalization of the previous result: you can pick up any position to start to work
  % with replace_par_pos and that does not change the result.
   replace_par_pos_equivalence1: LEMMA
    SPP?(s)(fsp) AND fsp`length /= 0 AND fst`length = fsp`length AND n < fsp`length
      => replace_par_pos(replaceTerm(s, fst(n), fsp(n)), delete(fsp,n), delete[term](fst,n)) = 
              replace_par_pos(s,fsp,fst)

  % If you apply replace_par_pos in positions fsp, then the subterm
  % at any position p || fsp is preserved.
   replace_par_pos_preservs_subterm: LEMMA
    SPP?(t)(add_first(p,fsp)) AND fst`length = fsp`length
          => subtermOF(replace_par_pos(t, fsp, fst), p) = subtermOF(t, p)

  % When one rewrites in parallel at fsp, the subterms of the resulting term
  % at fsp are exatly the terms in fst.
    replace_par_pos_subterm: LEMMA
      SPP?(t)(fsp) AND fst`length = fsp`length
           => (FORALL (i : below[fsp`length]) : subtermOF(replace_par_pos(t, fsp, fst),fsp(i))=fst(i))

  % If you replace the subterms at a composition of sequences 'fsp1 o fsp2',
  % that are parallel, it is the same that doing it separately.
   replace_par_pos_comp: LEMMA
    SPP?(t)(fsp1 o fsp2) AND fst1`length = fsp1`length
                         AND fst2`length = fsp2`length
           => replace_par_pos(t, fsp1 o fsp2, fst1 o fst2) =
                          replace_par_pos(replace_par_pos(t, fsp1, fst1),fsp2, fst2)

  %% In general, applying replace_par_pos at a parallel composition of sequences
  %% fsp1 o fsp2 is commutative.
   replace_par_pos_comp_commute: LEMMA
      SPP?(t)(fsp1 o fsp2) AND fst1`length = fsp1`length AND fst2`length = fsp2`length
        IMPLIES 
          replace_par_pos(t, fsp1 o fsp2, fst1 o fst2) = 
                                                replace_par_pos(t, fsp2 o fsp1, fst2 o fst1)

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   complement_pos_set(p1,p): set[position] = 
           IF p1 <= p & p1 /= p 
             THEN {p2 | p=p1 o p2}
             ELSE emptyset
           ENDIF

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   complement_pos(p,(fsp:PP)):
         RECURSIVE finseq[position] = 
             IF length(fsp)=0 THEN empty_seq
             ELSIF nonempty?(complement_pos_set(p,fsp`seq(0)))
                THEN add_first(choose(complement_pos_set(p,fsp`seq(0))),
                               complement_pos(p,rest(fsp)))
                ELSE complement_pos(p,rest(fsp))
             ENDIF
         MEASURE(length(fsp))

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   parallel_pos_same_prefix: LEMMA
      parallel(p1,p2) & p1= p o q1 & p2= p o q2
       IMPLIES parallel(q1,q2)

   complement_pos_character: LEMMA
      PP?(fsp) & member_seq(p1, complement_pos(p,fsp))
       IMPLIES EXISTS (i:below[fsp`length]):
               fsp`seq(i)= p o p1

   complement_pos_is_PP: LEMMA
      PP?(fsp) IMPLIES PP?(complement_pos(p,fsp))

   complement_pos_preservs_sub_pos_length1: LEMMA
     PP?(fsp) IMPLIES
    complement_pos(p, fsp)`length = sub_pos(fsp, p)`length

   complement_pos_empty: LEMMA
     PP?(add_first(p, fsp)) => complement_pos(p, fsp)`length = 0

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   comp_pos(p,fsp): finseq[position] = (# length := fsp`length,
                                                seq := (LAMBDA (i: below[fsp`length]): p o fsp(i)) #);

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   comp_preservs_parallel_pos: LEMMA
       parallel(p1,p2) IMPLIES parallel(p o p1,p o p2)

   comp_preservs_parallel_pos2: LEMMA
      parallel(p1,p2) IMPLIES parallel(p1 o q1,p2)

   comp_preservs_parallel_pos3: LEMMA
      parallel(p1,p2) IMPLIES parallel(p1 o q1,p2 o q2)

   comp_pos_rest: LEMMA
       comp_pos(p,rest(fsp)) = rest(comp_pos(p,fsp))

   comp_pos_preservs_length: LEMMA
       comp_pos(p, fsp)`length=fsp`length

   comp_pos_character: LEMMA
       FORALL(i:below[fsp`length]):
       comp_pos(p,fsp)`seq(i)= p o fsp`seq(i)

   comp_pos_is_PP: LEMMA
       PP?(fsp) IMPLIES PP?(comp_pos(p,fsp))

  %% Replacing at the position q of t by the result of replacing in parallel at positions fsp of s
  %% gives as result the same as replacing at positions q o fsp of t[q<-s].
   replace_replace_par_pos: LEMMA
      positionsOF(t)(q) AND SPP?(s)(fsp) AND fst`length = fsp`length
         IMPLIES
         replaceTerm(t, replace_par_pos(s,fsp,fst), q) = replace_par_pos(replaceTerm(t,s,q), comp_pos(q,fsp), fst)

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   complement_pos_preservs_sub_pos_length: LEMMA
     PP?(fsp) IMPLIES 
      complement_pos(p1,complement_pos(p, fsp))`length
         = sub_pos(fsp, p o p1)`length

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   Pos_Over_character: LEMMA
       PP?(fsp1) & PP?(fsp2)
         => FORALL (i:below[Pos_Over(fsp1,fsp2)`length]):
         	  	 PP?(add_first(Pos_Over(fsp1,fsp2)`seq(i),fsp2))
               OR  EXISTS (j:below[fsp2`length]):
                           Pos_Over(fsp1,fsp2)`seq(i) <= fsp2`seq(j)
                           & Pos_Over(fsp1,fsp2)`seq(i) /= fsp2`seq(j)

   Pos_Equal_character: LEMMA
       PP?(fsp1) & PP?(fsp2) 
         => FORALL (i:below[Pos_Equal(fsp1,fsp2)`length]):
               EXISTS (j:below[fsp2`length]):
                       Pos_Equal(fsp1,fsp2)`seq(i) = fsp2`seq(j)

   Pos_Equal_is_PP: LEMMA
       PP?(fsp1) & PP?(fsp2)
         => PP?(Pos_Equal(fsp1, fsp2))
         	  	 
   Pos_Over_and_Pos_Equal_is_PP: LEMMA
       PP?(fsp1) & PP?(fsp2)
         => PP?(Pos_Over(fsp1, fsp2) o Pos_Over(fsp2, fsp1) o Pos_Equal(fsp1,fsp2))


  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    comp_pos_in_SP_preservs_SP_in_replace: LEMMA
      SPP?(t)(fsp) & SP?(s)(fsp1) & fsp`length > 0 IMPLIES
       SP?(replaceTerm(t, s, fsp`seq(0)))(comp_pos(fsp`seq(0), fsp1) o rest(fsp))

    comp_pos_in_PP_preservs_PP: LEMMA
      PP?(fsp) & PP?(fsp1) & fsp`length > 0 IMPLIES
       PP?(comp_pos(fsp`seq(0), fsp1) o rest(fsp))

    comp_pos_in_SPP_preservs_SPP_in_replace: LEMMA
      SPP?(t)(fsp) & SPP?(s)(fsp1) & fsp`length > 0 IMPLIES
       SPP?(replaceTerm(t, s, fsp`seq(0)))(comp_pos(fsp`seq(0), fsp1) o rest(fsp))

    comp_pos_in_SPP_preservs_SPP_in_replace_par_pos: LEMMA
      SPP?(t)(fsp) & fsp`length=fst`length & fsp`length /= 0 &
      SPP?(fst`seq(0))(fsp1) &
      SPP?(replace_par_pos(t, fsp, fst))(fsp2) &
      PP?(add_first(fsp`seq(0),fsp2)) IMPLIES
       SPP?(replace_par_pos(t, fsp, fst))(comp_pos(fsp`seq(0), fsp1) o fsp2)

    parallel_reduction_reflexive: LEMMA reflexive?(parallel_reduction?(E))

    non_ambiguous_implies_same_term: LEMMA
         NOT Ambiguous?(E) & positionsOF(s)(p) &
         reduction_fix?(E)(s,t1,p) &
         reduction_fix?(E)(s,t2,p)
           IMPLIES t1 = t2

    parallel_reduction_context_aux2: LEMMA   
      SPP?(t)(fsp) AND fst1`length = fsp`length AND fst2`length = fsp`length AND
      (FORALL (i : below[fsp`length]): parallel_reduction?(E)(fst1(i),fst2(i)))
          IMPLIES EXISTS (fsq:SPP(replace_par_pos(t, fsp, fst1))):
             parallel_reduction_fix?(E)(replace_par_pos(t, fsp, fst1),replace_par_pos(t, fsp, fst2), fsq)
              AND (FORALL(p:positions?(t)): PP?(add_first(p,fsp)) => PP?(add_first(p,fsq)))

    parallel_reduction_context: LEMMA
      SPP?(t)(fsp) AND fst1`length = fsp`length AND fst2`length = fsp`length AND
      (FORALL (i : below[fsp`length]): parallel_reduction?(E)(fst1(i),fst2(i)))
          IMPLIES 
             parallel_reduction?(E)(replace_par_pos(t, fsp, fst1),replace_par_pos(t, fsp, fst2))

    replace_par_pos_of_app_is_app: LEMMA
      app?(t) & SPP?(t)(fsp) & fst`length = fsp`length IMPLIES
       fsp = #(empty_seq) OR
            app?(replace_par_pos(t, fsp, fst))

    replace_par_pos_preservs_f: LEMMA
      app?(t) & SPP?(t)(fsp) & fst`length = fsp`length IMPLIES
       fsp = #(empty_seq) OR
         f(t) = f(replace_par_pos(t,fsp,fst))

    parallel_reduction_closed_subs: LEMMA
      (FORALL (x: Vars?(t)): parallel_reduction?(E)(ext(sigma)(x), ext(theta)(x)))
        IMPLIES
          parallel_reduction?(E)(ext(sigma)(t), ext(theta)(t))

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    compo_sufix(fsp:PP, p): 
        finseq[position] = (# length := fsp`length,
                                 seq := (LAMBDA(i:below[fsp`length]): fsp`seq(i) o p) #)

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    parallel_reduction_result: LEMMA
       Orthogonal?(E) & E(e) & SPP?(ext(sigma)(lhs(e)))(fsp) &
       parallel_reduction_fix?(E)(ext(sigma)(lhs(e)), t, fsp)
         IMPLIES
            fsp = #(empty_seq) OR
            EXISTS(theta): t = ext(theta)(lhs(e))

    replace_par_pos_subterm2: LEMMA
        SPP?(s)(fsp) & member_seq(p1, fsp) &
        p <= p1 & p /= p1 &
        fsp`length = fst`length IMPLIES
          EXISTS fst1 : (complement_pos(p, fsp)`length = fst1`length &
            subtermOF(replace_par_pos(s, fsp, fst), p) =
                   replace_par_pos(subtermOF(s, p), complement_pos(p, fsp), fst1))

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    C(e, sigma, s, t, (p|positionsOF(s)(p) & positionsOF(t)(p))): bool = 
          subtermOF(s, p) = ext(sigma)(lhs(e)) AND
          subtermOF(t, p) = ext(sigma)(rhs(e))

    D(s, t, (fsp|SPP?(s)(fsp) & SPP?(t)(fsp)), E)(i:below[fsp`length], e): bool =
             member(e, E) &
              EXISTS sigma : C(e, sigma, s, t, fsp`seq(i))

    G(s, t, (fsp|SPP?(s)(fsp) & SPP?(t)(fsp)),E)(i:below[fsp`length], sigma): bool =
              EXISTS (e|member(e, E)) : C(e, sigma, s, t, fsp`seq(i))

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    parallel_reduction_variables: LEMMA
     NOT Ambiguous?(E) & E(e) &
      SPP?(ext(sigma)(lhs(e)))(fsp) &
      parallel_reduction_fix?(E)(ext(sigma)(lhs(e)), ext(theta)(lhs(e)),fsp) &
      NOT fsp = #(empty_seq)    
        IMPLIES
          FORALL (x:Vars?(lhs(e))):
           parallel_reduction?(E)(ext(sigma)(x), ext(theta)(x))


    Parallel_Moves_Lemma: LEMMA
        Orthogonal?(E) & member(e,E) &
        parallel_reduction?(E)(ext(sigma)(lhs(e)), t)
        IMPLIES EXISTS s: parallel_reduction?(E)(ext(sigma)(rhs(e)),s) &
                          parallel_reduction?(E)(t,s)


  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    replace_par_pos_dominance: LEMMA
      SPP?(t)(fsp) & SPP?(t)(fsp1) & parallel_reduction_fix?(E)(t,s,fsp1) &
      (FORALL(i:below[fsp1`length]):
                 EXISTS(j:below[fsp`length]):fsp`seq(j) <= fsp1`seq(i))
         IMPLIES s = replace_par_pos(t,fsp,subtermsOF(s,fsp))

    Pos_Over_and_Pos_Equal_dominance: LEMMA
      SPP?(t)(fsp1) & SPP?(t)(fsp2) IMPLIES
      (FORALL(i:below[fsp1`length]):
          EXISTS(j:below[(Pos_Over(fsp1,fsp2) o Pos_Over(fsp2,fsp1) o Pos_Equal(fsp1,fsp2))`length]):
           (Pos_Over(fsp1,fsp2) o Pos_Over(fsp2,fsp1) o Pos_Equal(fsp1,fsp2))`seq(j) <= fsp1`seq(i))

    divergence_in_Pos_Over_aux: LEMMA
       SPP?(t)(fsp2) &
       parallel_reduction_fix?(E)(t, t2, fsp2) &
       positionsOF(t)(p) &
       member_seq(p, Pos_Over( #(p), fsp2))
              => parallel_reduction_fix?(E)(subtermOF(t, p), subtermOF(t2, p), complement_pos(p, fsp2))

    divergence_in_Pos_Over: LEMMA
       SPP?(t)(fsp1) & SPP?(t)(fsp2) &
       parallel_reduction_fix?(E)(t, t1, fsp1) &
       parallel_reduction_fix?(E)(t, t2, fsp2) &
       member_seq(p, Pos_Over(fsp1, fsp2))
              => (EXISTS((e | member(e, E)), sigma):
                       subtermOF(t, p) = ext(sigma)(lhs(e)) &
                       subtermOF(t1, p) = ext(sigma)(rhs(e)) &
                       parallel_reduction?(E)(subtermOF(t, p),subtermOF(t2,p)) )

    subterm_joinability: LEMMA
      Orthogonal?(E) &
      SPP?(t)(fsp1) & SPP?(t)(fsp2) &
           parallel_reduction_fix?(E)(t,t1,fsp1) &
           parallel_reduction_fix?(E)(t,t2,fsp2) &
           fsp = Pos_Over(fsp1,fsp2) o Pos_Over(fsp2,fsp1) o Pos_Equal(fsp1,fsp2)
       IMPLIES FORALL(i:below[fsp`length]): 
           EXISTS s :
         parallel_reduction?(E)(subtermOF(t1,fsp(i)), s) &
         parallel_reduction?(E)(subtermOF(t2,fsp(i)), s)

    subterms_joinability: LEMMA
      Orthogonal?(E) &
      SPP?(t)(fsp1) & SPP?(t)(fsp2) &
           parallel_reduction_fix?(E)(t,t1,fsp1) &
           parallel_reduction_fix?(E)(t,t2,fsp2) &
           fsp = Pos_Over(fsp1,fsp2) o Pos_Over(fsp2,fsp1) o Pos_Equal(fsp1,fsp2)
       IMPLIES EXISTS fst : fsp`length = fst`length AND
       FORALL(i:below[fsp`length]): 
         parallel_reduction?(E)(subtermOF(t1,fsp(i)), fst(i)) &
         parallel_reduction?(E)(subtermOF(t2,fsp(i)), fst(i))

   

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   parallel_reduction_has_DP: LEMMA
    Orthogonal?(E) => diamond_property?(parallel_reduction?(E))

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   Orthogonal_implies_confluent: LEMMA 
    FORALL (E : Orthogonal) :  
      LET RRE = reduction?(E) IN
      confluent?(RRE)

   END orthogonality

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 99, column 14) for
      % critical_pairs[variable, symbol, arity]
      % generated from assumption critical_pairs.var_countable
  IMP_critical_pairs_TCC1: OBLIGATION
    is_countably_infinite[term[variable, symbol, arity]]
        (V[variable, symbol, arity]);

  % Subtype TCC generated (at line 140, column 74) for  p
      % expected type  positions?
                     %     [variable, symbol, arity](ext(sigma)(lhs(e1)))
  ntCP?_TCC1: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            t1: term[variable, symbol, arity],
            sigma: Sub[variable, symbol, arity],
            rho: Ren[variable, symbol, arity],
            (e1: rewrite_rule[variable, symbol, arity]
                 | member[rewrite_rule[variable, symbol, arity]](e1, E)),
            (e2p: rewrite_rule[variable, symbol, arity]
                 | member[rewrite_rule[variable, symbol, arity]](e2p, E)),
            (p:
               positions?
                   [variable, symbol, arity](lhs[variable, symbol, arity]
                                             (e1)))):
      NOT (e1 = e2p AND p = empty_seq) IMPLIES
       (FORALL (e2:
                  [# lhs: term[variable, symbol, arity],
                     rhs: term[variable, symbol, arity] #]):
               t1 = ext(sigma)(rhs(e1))
           AND mgu(sigma)(subtermOF(lhs(e1), p), lhs(e2))
           AND NOT vars?(subtermOF(lhs(e1), p))
           AND disjoint?(Vars(lhs(e1)), Vars(lhs(e2)))
           AND e2 =
                (# lhs := ext(rho)(lhs(e2p)), rhs := ext(rho)(rhs(e2p)) #)
           IMPLIES
           positionsOF[variable, symbol, arity]
               (ext[variable, symbol, arity]
                    (sigma)(lhs[variable, symbol, arity](e1)))
               (p));

  % Subtype TCC generated (at line 152, column 80) for  p
      % expected type  positions?[variable, symbol, arity](ext(sg1)(lhs(e1)))
  ntCP_lemma_aux1_TCC1: OBLIGATION
    FORALL (sg1, sg2: Sub[variable, symbol, arity], E,
            p: position[variable, symbol, arity],
            e1: rewrite_rule[variable, symbol, arity]
                | member[rewrite_rule[variable, symbol, arity]](e1, E),
            e2: rewrite_rule[variable, symbol, arity]
                | member[rewrite_rule[variable, symbol, arity]](e2, E)):
      positionsOF(lhs(e1))(p) AND
       NOT vars?(subtermOF(lhs(e1), p)) AND
        ext(sg1)(subtermOF(lhs(e1), p)) = ext(sg2)(lhs(e2)) AND
         NOT (e1 = e2 AND p = empty_seq)
       IMPLIES
       (FORALL (t1, t2, delta):
          ext(delta)(t1) = ext(sg1)(rhs(e1)) AND ntCP?(E)(t1, t2) IMPLIES
           positionsOF[variable, symbol, arity]
               (ext[variable, symbol, arity]
                    (sg1)(lhs[variable, symbol, arity](e1)))
               (p));

  % Subtype TCC generated (at line 156, column 68) for  Pos_var(t, x)
      % expected type  finite_set[position[variable, symbol, arity]]
  linear?_TCC1: OBLIGATION
    FORALL (t: term[variable, symbol, arity],
            x: (V) | member[(V)](x, Vars[variable, symbol, arity](t))):
      is_finite[position[variable, symbol, arity]]
          (Pos_var[variable, symbol, arity](t, x));

  % Subtype TCC generated (at line 172, column 7) for  Pos_var(t, x)
      % expected type  finite_set[position[variable, symbol, arity]]
  Orth_lemma_aux0_TCC1: OBLIGATION
    FORALL (t: term[variable, symbol, arity], x: (V)):
      is_finite[position[variable, symbol, arity]]
          (Pos_var[variable, symbol, arity](t, x));

  % Subtype TCC generated (at line 183, column 32) for   #(first(p))
      % expected type  positions?[variable, symbol, arity](s)
  Var_occurs_only_once_also_in_subterms_TCC1: OBLIGATION
    FORALL (p: position[variable, symbol, arity],
            s: term[variable, symbol, arity], x: (V)):
           card(Pos_var(s, x)) = 1 AND x = subtermOF(s, p) AND p`length /= 0
       AND positionsOF(s)(p) AND vars?(x)
       IMPLIES
       positionsOF[variable, symbol, arity](s)( #[posnat](first[posnat](p)));

  % Subtype TCC generated (at line 183, column 11) for
      % Pos_var(subtermOF(s,  #(first(p))), x)
      % expected type  S: finite_set[position[variable, symbol, arity]]
  Var_occurs_only_once_also_in_subterms_TCC2: OBLIGATION
    FORALL (p: position[variable, symbol, arity],
            s: term[variable, symbol, arity], x: (V)):
           card(Pos_var(s, x)) = 1 AND x = subtermOF(s, p) AND p`length /= 0
       AND positionsOF(s)(p) AND vars?(x)
       IMPLIES
       is_finite[position[variable, symbol, arity]]
           (Pos_var[variable, symbol, arity]
                (subtermOF[variable, symbol, arity]
                     (s,  #[posnat](first[posnat](p))),
                 x));

  % Subtype TCC generated (at line 189, column 35) for  p2
      % expected type  positions?[variable, symbol, arity](sigma(x))
  SigmaP_equivalence_TCC1: OBLIGATION
    FORALL (p2: position[variable, symbol, arity],
            s: term[variable, symbol, arity],
            sigma: Sub[variable, symbol, arity], x: (V)):
      positionsOF(ext(sigma)(x))(p2) AND NOT member(x, Vars(s)) IMPLIES
       positionsOF[variable, symbol, arity](sigma(x))(p2);

  % Subtype TCC generated (at line 189, column 15) for
      % SigmaP(sigma, t, x, p2)
      % expected type  Sub[variable, symbol, arity]
  SigmaP_equivalence_TCC2: OBLIGATION
    FORALL (p2: position[variable, symbol, arity],
            s: term[variable, symbol, arity],
            sigma: Sub[variable, symbol, arity],
            t: term[variable, symbol, arity], x: (V)):
      positionsOF(ext(sigma)(x))(p2) AND NOT member(x, Vars(s)) IMPLIES
       Sub?[variable, symbol, arity]
           (SigmaP[variable, symbol, arity](sigma, t, x, p2));

  % Subtype TCC generated (at line 197, column 30) for  p2
      % expected type  positions?[variable, symbol, arity](sigma(x))
  SigmaP_vs_replaceTerm_linearR_TCC1: OBLIGATION
    FORALL (p1, p2: position[variable, symbol, arity],
            s: term[variable, symbol, arity],
            sigma: Sub[variable, symbol, arity], x: (V)):
           Card(Pos_var(s, x)) = 1 AND x = subtermOF(s, p1)
       AND positionsOF(ext(sigma)(x))(p2) AND positionsOF(s)(p1) AND vars?(x)
       IMPLIES positionsOF[variable, symbol, arity](sigma(x))(p2);

  % Subtype TCC generated (at line 197, column 10) for
      % SigmaP(sigma, t, x, p2)
      % expected type  Sub[variable, symbol, arity]
  SigmaP_vs_replaceTerm_linearR_TCC2: OBLIGATION
    FORALL (p1, p2: position[variable, symbol, arity],
            s: term[variable, symbol, arity],
            sigma: Sub[variable, symbol, arity],
            t: term[variable, symbol, arity], x: (V)):
           Card(Pos_var(s, x)) = 1 AND x = subtermOF(s, p1)
       AND positionsOF(ext(sigma)(x))(p2) AND positionsOF(s)(p1) AND vars?(x)
       IMPLIES
       Sub?[variable, symbol, arity]
           (SigmaP[variable, symbol, arity](sigma, t, x, p2));

  % Subtype TCC generated (at line 198, column 40) for  p1 o p2
      % expected type  positions?[variable, symbol, arity](ext(sigma)(s))
  SigmaP_vs_replaceTerm_linearR_TCC3: OBLIGATION
    FORALL (p1, p2: position[variable, symbol, arity],
            s: term[variable, symbol, arity],
            sigma: Sub[variable, symbol, arity], x: (V)):
           Card(Pos_var(s, x)) = 1 AND x = subtermOF(s, p1)
       AND positionsOF(ext(sigma)(x))(p2) AND positionsOF(s)(p1) AND vars?(x)
       IMPLIES
       positionsOF[variable, symbol, arity]
           (ext[variable, symbol, arity](sigma)(s))(o[posnat](p1, p2));

  % Subtype TCC generated (at line 248, column 43) for  0
      % expected type  below[length(fst)]
  replace_par_pos_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (fsp: SPP[variable, symbol, arity](s)),
            fst: finseq[term] | fst`length = fsp`length):
      NOT length(fsp) = 0 IMPLIES 0 < length(fst);

  % Subtype TCC generated (at line 248, column 51) for  0
      % expected type  below[length(fsp)]
  replace_par_pos_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (fsp: SPP[variable, symbol, arity](s)),
            fst: finseq[term] | fst`length = fsp`length):
      NOT length(fsp) = 0 IMPLIES 0 < length(fsp);

  % Subtype TCC generated (at line 248, column 47) for
      % finseq_appl[position[variable, symbol, arity]](fsp)(0)
      % expected type  positions?[variable, symbol, arity](s)
  replace_par_pos_TCC3: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (fsp: SPP[variable, symbol, arity](s)),
            fst: finseq[term] | fst`length = fsp`length):
      NOT length(fsp) = 0 IMPLIES
       positionsOF[variable, symbol, arity]
           (s)(finseq_appl[position[variable, symbol, arity]](fsp)(0));

  % Subtype TCC generated (at line 248, column 56) for  rest(fsp)
      % expected type  SPP
                     %     [variable, symbol, arity](replaceTerm
                     %                               (s,
                     %                                finseq_appl
                     %                                [term
                     %                                 [variable,
                     %                                  symbol,
                     %                                  arity]]
                     %                                (fst)(0),
                     %                                finseq_appl
                     %                                [position
                     %                                 [variable,
                     %                                  symbol,
                     %                                  arity]]
                     %                                (fsp)(0)))
  replace_par_pos_TCC4: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (fsp: SPP[variable, symbol, arity](s)),
            fst: finseq[term] | fst`length = fsp`length):
      NOT length(fsp) = 0 IMPLIES
       SPP?[variable, symbol, arity]
           (replaceTerm[variable, symbol, arity]
                (s, finseq_appl[term[variable, symbol, arity]](fst)(0),
                 finseq_appl[position[variable, symbol, arity]](fsp)(0)))
           (rest[position[variable, symbol, arity]](fsp));

  % Subtype TCC generated (at line 248, column 67) for  rest(fst)
      % expected type  {fst_1 | fst_1`length = rest(fsp)`length}
  replace_par_pos_TCC5: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (fsp: SPP[variable, symbol, arity](s)),
            fst: finseq[term] | fst`length = fsp`length):
      NOT length(fsp) = 0 IMPLIES
       rest[term[variable, symbol, arity]](fst)`length =
        rest[position[variable, symbol, arity]](fsp)`length;

  % Termination TCC generated (at line 248, column 8) for
      % replace_par_pos(replaceTerm(s,
      %                             finseq_appl[term[variable, symbol, arity]]
      %                                 (fst)(0),
      %                             finseq_appl
      %                                 [position[variable, symbol, arity]]
      %                                 (fsp)(0)),
      %                 rest(fsp), rest(fst))
  replace_par_pos_TCC6: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (fsp: SPP[variable, symbol, arity](s)),
            fst: finseq[term] | fst`length = fsp`length):
      NOT length(fsp) = 0 IMPLIES
       length(rest[position[variable, symbol, arity]](fsp)) < length(fsp);

  % Subtype TCC generated (at line 261, column 75) for  i
      % expected type  below[length(fse)]
  sigma_rhs_TCC1: OBLIGATION
    FORALL (fss: finseq[Sub[variable, symbol, arity]],
            (fse: finseq[rewrite_rule] | fse`length = fss`length)):
      NOT fss`length = 0 IMPLIES
       (FORALL (i: below[fss`length]): i < length(fse));

  % Subtype TCC generated (at line 273, column 81) for
      % finseq_appl[position[variable, symbol, arity]](fsp)(i)
      % expected type  positions?[variable, symbol, arity](t)
  subtermsOF_TCC1: OBLIGATION
    FORALL (t: term[variable, symbol, arity],
            (fsp: SP[variable, symbol, arity](t)), i: below[fsp`length]):
      positionsOF[variable, symbol, arity]
          (t)(finseq_appl[position[variable, symbol, arity]](fsp)(i));

  % Subtype TCC generated (at line 278, column 28) for  fsp
      % expected type  SP[variable, symbol, arity](s)
  parallel_reduction_fix?_TCC1: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            s: term[variable, symbol, arity],
            (fsp: SPP[variable, symbol, arity](s)),
            (fse: finseq[rewrite_rule] | member[rewrite_rule](fse, E)),
            fss: finseq[Sub[variable, symbol, arity]]):
      fsp`length = fss`length AND fsp`length = fse`length IMPLIES
       SP?[variable, symbol, arity](s)(fsp);

  % Subtype TCC generated (at line 278, column 50) for  fse
      % expected type  {fse | fse`length = fss`length}
  parallel_reduction_fix?_TCC2: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            s: term[variable, symbol, arity],
            (fsp: SPP[variable, symbol, arity](s)),
            (fse: finseq[rewrite_rule] | member[rewrite_rule](fse, E)),
            fss: finseq[Sub[variable, symbol, arity]]):
      fsp`length = fss`length AND fsp`length = fse`length IMPLIES
       fse`length = fss`length;

  % Subtype TCC generated (at line 279, column 43) for  sigma_rhs(fss, fse)
      % expected type  {fst | fst`length = fsp`length}
  parallel_reduction_fix?_TCC3: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            s: term[variable, symbol, arity],
            (fsp: SPP[variable, symbol, arity](s)),
            (fse: finseq[rewrite_rule] | member[rewrite_rule](fse, E)),
            fss: finseq[Sub[variable, symbol, arity]]):
      subtermsOF(s, fsp) = sigma_lhs(fss, fse) AND
       fsp`length = fss`length AND fsp`length = fse`length
       IMPLIES sigma_rhs(fss, fse)`length = fsp`length;

  % Subtype TCC generated (at line 288, column 27) for  0
      % expected type  below[fsp`length]
  sub_pos_TCC1: OBLIGATION
    FORALL ((fsp: PP[variable, symbol, arity])):
      NOT length(fsp) = 0 IMPLIES 0 < fsp`length;

  % Subtype TCC generated (at line 289, column 51) for  rest(fsp)
      % expected type  PP[variable, symbol, arity]
  sub_pos_TCC2: OBLIGATION
    FORALL ((fsp: PP[variable, symbol, arity]),
            p: position[variable, symbol, arity]):
      p <= fsp`seq(0) AND p /= fsp`seq(0) AND NOT length(fsp) = 0 IMPLIES
       PP?[variable, symbol, arity]
           (rest[position[variable, symbol, arity]](fsp));

  % Termination TCC generated (at line 289, column 43) for
      % sub_pos(rest(fsp), p)
  sub_pos_TCC3: OBLIGATION
    FORALL ((fsp: PP[variable, symbol, arity]),
            p: position[variable, symbol, arity]):
      p <= fsp`seq(0) AND p /= fsp`seq(0) AND NOT length(fsp) = 0 IMPLIES
       length(rest[position[variable, symbol, arity]](fsp)) < length(fsp);

  % Subtype TCC generated (at line 290, column 29) for  rest(fsp)
      % expected type  PP[variable, symbol, arity]
  sub_pos_TCC4: OBLIGATION
    FORALL ((fsp: PP[variable, symbol, arity]),
            p: position[variable, symbol, arity]):
      NOT (p <= fsp`seq(0) AND p /= fsp`seq(0)) AND NOT length(fsp) = 0
       IMPLIES
       PP?[variable, symbol, arity]
           (rest[position[variable, symbol, arity]](fsp));

  % Termination TCC generated (at line 290, column 21) for
      % sub_pos(rest(fsp), p)
  sub_pos_TCC5: OBLIGATION
    FORALL ((fsp: PP[variable, symbol, arity]),
            p: position[variable, symbol, arity]):
      NOT (p <= fsp`seq(0) AND p /= fsp`seq(0)) AND NOT length(fsp) = 0
       IMPLIES
       length(rest[position[variable, symbol, arity]](fsp)) < length(fsp);

  % Subtype TCC generated (at line 300, column 53) for  rest(fsp1)
      % expected type  PP[variable, symbol, arity]
  Pos_Over_TCC1: OBLIGATION
    FORALL ((fsp1: PP[variable, symbol, arity]),
            (fsp2: PP[variable, symbol, arity])):
      (length(sub_pos(fsp2, fsp1`seq(0))) > 0 OR
        PP?(add_first(fsp1`seq(0), fsp2)))
       AND NOT length(fsp1) = 0
       IMPLIES
       PP?[variable, symbol, arity]
           (rest[position[variable, symbol, arity]](fsp1));

  % Termination TCC generated (at line 300, column 44) for
      % Pos_Over(rest(fsp1), fsp2)
  Pos_Over_TCC2: OBLIGATION
    FORALL ((fsp1: PP[variable, symbol, arity]),
            (fsp2: PP[variable, symbol, arity])):
      (length(sub_pos(fsp2, fsp1`seq(0))) > 0 OR
        PP?(add_first(fsp1`seq(0), fsp2)))
       AND NOT length(fsp1) = 0
       IMPLIES
       length(rest[position[variable, symbol, arity]](fsp1)) < length(fsp1);

  % Subtype TCC generated (at line 301, column 30) for  rest(fsp1)
      % expected type  PP[variable, symbol, arity]
  Pos_Over_TCC3: OBLIGATION
    FORALL ((fsp1: PP[variable, symbol, arity]),
            (fsp2: PP[variable, symbol, arity])):
      NOT length(sub_pos(fsp2, fsp1`seq(0))) > 0 AND
       NOT PP?(add_first(fsp1`seq(0), fsp2)) AND NOT length(fsp1) = 0
       IMPLIES
       PP?[variable, symbol, arity]
           (rest[position[variable, symbol, arity]](fsp1));

  % Termination TCC generated (at line 301, column 21) for
      % Pos_Over(rest(fsp1), fsp2)
  Pos_Over_TCC4: OBLIGATION
    FORALL ((fsp1: PP[variable, symbol, arity]),
            (fsp2: PP[variable, symbol, arity])):
      NOT length(sub_pos(fsp2, fsp1`seq(0))) > 0 AND
       NOT PP?(add_first(fsp1`seq(0), fsp2)) AND NOT length(fsp1) = 0
       IMPLIES
       length(rest[position[variable, symbol, arity]](fsp1)) < length(fsp1);

  % Subtype TCC generated (at line 311, column 36) for  0
      % expected type  below[fsp2`length]
  Pos_Under_TCC1: OBLIGATION
    FORALL ((fsp1: PP[variable, symbol, arity]),
            (fsp2: PP[variable, symbol, arity])):
      NOT length(fsp2) = 0 IMPLIES 0 < fsp2`length;

  % Subtype TCC generated (at line 311, column 57) for  rest(fsp2)
      % expected type  PP[variable, symbol, arity]
  Pos_Under_TCC2: OBLIGATION
    FORALL ((fsp1: PP[variable, symbol, arity]),
            (fsp2: PP[variable, symbol, arity])):
      NOT length(fsp2) = 0 IMPLIES
       PP?[variable, symbol, arity]
           (rest[position[variable, symbol, arity]](fsp2));

  % Termination TCC generated (at line 311, column 42) for
      % Pos_Under(fsp1, rest(fsp2))
  Pos_Under_TCC3: OBLIGATION
    FORALL ((fsp1: PP[variable, symbol, arity]),
            (fsp2: PP[variable, symbol, arity])):
      NOT length(fsp2) = 0 IMPLIES
       length(rest[position[variable, symbol, arity]](fsp2)) < length(fsp2);

  % Subtype TCC generated (at line 320, column 43) for  rest(fsp1)
      % expected type  PP[variable, symbol, arity]
  Pos_Equal_TCC1: OBLIGATION
    FORALL ((fsp1: PP[variable, symbol, arity]),
            (fsp2: PP[variable, symbol, arity])):
      member_seq(fsp1`seq(0), fsp2) AND NOT length(fsp1) = 0 IMPLIES
       PP?[variable, symbol, arity]
           (rest[position[variable, symbol, arity]](fsp1));

  % Termination TCC generated (at line 320, column 33) for
      % Pos_Equal(rest(fsp1), fsp2)
  Pos_Equal_TCC2: OBLIGATION
    FORALL ((fsp1: PP[variable, symbol, arity]),
            (fsp2: PP[variable, symbol, arity])):
      member_seq(fsp1`seq(0), fsp2) AND NOT length(fsp1) = 0 IMPLIES
       length(rest[position[variable, symbol, arity]](fsp1)) < length(fsp1);

  % Subtype TCC generated (at line 321, column 20) for  rest(fsp1)
      % expected type  PP[variable, symbol, arity]
  Pos_Equal_TCC3: OBLIGATION
    FORALL ((fsp1: PP[variable, symbol, arity]),
            (fsp2: PP[variable, symbol, arity])):
      NOT member_seq(fsp1`seq(0), fsp2) AND NOT length(fsp1) = 0 IMPLIES
       PP?[variable, symbol, arity]
           (rest[position[variable, symbol, arity]](fsp1));

  % Termination TCC generated (at line 321, column 10) for
      % Pos_Equal(rest(fsp1), fsp2)
  Pos_Equal_TCC4: OBLIGATION
    FORALL ((fsp1: PP[variable, symbol, arity]),
            (fsp2: PP[variable, symbol, arity])):
      NOT member_seq(fsp1`seq(0), fsp2) AND NOT length(fsp1) = 0 IMPLIES
       length(rest[position[variable, symbol, arity]](fsp1)) < length(fsp1);

  % Subtype TCC generated (at line 363, column 21) for  fsp1
      % expected type  PP[variable, symbol, arity]
  Pos_Over_is_SPP_TCC1: OBLIGATION
    FORALL (fsp1, fsp2: finseq[position], s: term[variable, symbol, arity]):
      SPP?(s)(fsp2) AND SPP?(s)(fsp1) IMPLIES
       PP?[variable, symbol, arity](fsp1);

  % Subtype TCC generated (at line 363, column 27) for  fsp2
      % expected type  PP[variable, symbol, arity]
  Pos_Over_is_SPP_TCC2: OBLIGATION
    FORALL (fsp1, fsp2: finseq[position], s: term[variable, symbol, arity]):
      SPP?(s)(fsp2) AND SPP?(s)(fsp1) IMPLIES
       PP?[variable, symbol, arity](fsp2);

  % Subtype TCC generated (at line 392, column 41) for  fsp
      % expected type  PP[variable, symbol, arity]
  sub_pos_is_SPP_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], s: term[variable, symbol, arity]):
      SPP?(s)(fsp) IMPLIES PP?[variable, symbol, arity](fsp);

  % Subtype TCC generated (at line 406, column 65) for  rest(fse)
      % expected type  {fse | fse`length = rest(fss)`length}
  sigma_rhs_rest_TCC1: OBLIGATION
    FORALL (fse: finseq[rewrite_rule], fss: finseq[Sub]):
      fse`length = fss`length IMPLIES
       rest[rewrite_rule](fse)`length = rest[Sub](fss)`length;

  % Subtype TCC generated (at line 412, column 30) for  fse1 o fse2
      % expected type  {fse | fse`length = (fss1 o fss2)`length}
  sigma_rhs_o_TCC1: OBLIGATION
    FORALL (fse1, fse2: finseq[rewrite_rule], fss1, fss2: finseq[Sub]):
      fse2`length = fss2`length AND fse1`length = fss1`length IMPLIES
       (o[rewrite_rule](fse1, fse2))`length = (o[Sub](fss1, fss2))`length;

  % Subtype TCC generated (at line 416, column 65) for  rest(fsp)
      % expected type  SP[variable, symbol, arity](t)
  subtermsOF_rest_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], t: term[variable, symbol, arity]):
      SP?(t)(fsp) IMPLIES
       SP?[variable, symbol, arity]
           (t)(rest[position[variable, symbol, arity]](fsp));

  % Subtype TCC generated (at line 434, column 42) for  fsp
      % expected type  SPP[variable, symbol, arity](t)
  replace_par_pos_preservs_pos_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            p: position[variable, symbol, arity],
            t: term[variable, symbol, arity]):
      fst`length = fsp`length AND SPP?(t)(add_first(p, fsp)) IMPLIES
       SPP?[variable, symbol, arity](t)(fsp);

  % Subtype TCC generated (at line 446, column 76) for  fsp
      % expected type  SPP[variable, symbol, arity](t)
  replace_par_pos_preservs_PP_o_PP_TCC1: OBLIGATION
    FORALL (fsp, fsq: finseq[position], fst: finseq[term],
            t: term[variable, symbol, arity]):
      fst`length = fsp`length AND SPP?(t)(fsp o fsq) IMPLIES
       (FORALL (i: below[fsq`length]): SPP?[variable, symbol, arity](t)(fsp));

  % Subtype TCC generated (at line 452, column 42) for  0
      % expected type  below[length(fst)]
  replace_par_pos_equivalence_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            s: term[variable, symbol, arity]):
      fst`length = fsp`length AND fsp`length /= 0 AND SPP?(s)(fsp) IMPLIES
       0 < length(fst);

  % Subtype TCC generated (at line 452, column 50) for  0
      % expected type  below[length(fsp)]
  replace_par_pos_equivalence_TCC2: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            s: term[variable, symbol, arity]):
      fst`length = fsp`length AND fsp`length /= 0 AND SPP?(s)(fsp) IMPLIES
       0 < length(fsp);

  % Subtype TCC generated (at line 452, column 46) for
      % finseq_appl[position[variable, symbol, arity]](fsp)(0)
      % expected type  positions?[variable, symbol, arity](s)
  replace_par_pos_equivalence_TCC3: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            s: term[variable, symbol, arity]):
      fst`length = fsp`length AND fsp`length /= 0 AND SPP?(s)(fsp) IMPLIES
       positionsOF[variable, symbol, arity]
           (s)(finseq_appl[position[variable, symbol, arity]](fsp)(0));

  % Subtype TCC generated (at line 452, column 55) for  rest(fsp)
      % expected type  SPP
                     %     [variable, symbol, arity](replaceTerm
                     %                               (s,
                     %                                finseq_appl
                     %                                [term
                     %                                 [variable,
                     %                                  symbol,
                     %                                  arity]]
                     %                                (fst)(0),
                     %                                finseq_appl
                     %                                [position
                     %                                 [variable,
                     %                                  symbol,
                     %                                  arity]]
                     %                                (fsp)(0)))
  replace_par_pos_equivalence_TCC4: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            s: term[variable, symbol, arity]):
      fst`length = fsp`length AND fsp`length /= 0 AND SPP?(s)(fsp) IMPLIES
       SPP?[variable, symbol, arity]
           (replaceTerm[variable, symbol, arity]
                (s, finseq_appl[term[variable, symbol, arity]](fst)(0),
                 finseq_appl[position[variable, symbol, arity]](fsp)(0)))
           (rest[position[variable, symbol, arity]](fsp));

  % Subtype TCC generated (at line 452, column 66) for  rest(fst)
      % expected type  {fst_1 | fst_1`length = rest(fsp)`length}
  replace_par_pos_equivalence_TCC5: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            s: term[variable, symbol, arity]):
      fst`length = fsp`length AND fsp`length /= 0 AND SPP?(s)(fsp) IMPLIES
       rest[term[variable, symbol, arity]](fst)`length =
        rest[position[variable, symbol, arity]](fsp)`length;

  % Subtype TCC generated (at line 453, column 43) for  rest(fsp)
      % expected type  SPP[variable, symbol, arity](s)
  replace_par_pos_equivalence_TCC6: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            s: term[variable, symbol, arity]):
      fst`length = fsp`length AND fsp`length /= 0 AND SPP?(s)(fsp) IMPLIES
       SPP?[variable, symbol, arity]
           (s)(rest[position[variable, symbol, arity]](fsp));

  % Subtype TCC generated (at line 453, column 74) for
      % finseq_appl[position[variable, symbol, arity]](fsp)(0)
      % expected type  positions?
                     %     [variable, symbol, arity](replace_par_pos
                     %                               (s,
                     %                                rest(fsp),
                     %                                rest(fst)))
  replace_par_pos_equivalence_TCC7: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            s: term[variable, symbol, arity]):
      fst`length = fsp`length AND fsp`length /= 0 AND SPP?(s)(fsp) IMPLIES
       positionsOF[variable, symbol, arity]
           (replace_par_pos(s, rest[position[variable, symbol, arity]](fsp),
                            rest[term[variable, symbol, arity]](fst)))
           (finseq_appl[position[variable, symbol, arity]](fsp)(0));

  % Subtype TCC generated (at line 459, column 42) for  n
      % expected type  below[length(fst)]
  replace_par_pos_equivalence1_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term], n: nat,
            s: term[variable, symbol, arity]):
      n < fsp`length AND
       fst`length = fsp`length AND fsp`length /= 0 AND SPP?(s)(fsp)
       IMPLIES n < length(fst);

  % Subtype TCC generated (at line 459, column 46) for
      % finseq_appl[position[variable, symbol, arity]](fsp)(n)
      % expected type  positions?[variable, symbol, arity](s)
  replace_par_pos_equivalence1_TCC2: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term], n: nat,
            s: term[variable, symbol, arity]):
      n < fsp`length AND
       fst`length = fsp`length AND fsp`length /= 0 AND SPP?(s)(fsp)
       IMPLIES
       positionsOF[variable, symbol, arity]
           (s)(finseq_appl[position[variable, symbol, arity]](fsp)(n));

  % Subtype TCC generated (at line 459, column 55) for  delete(fsp, n)
      % expected type  SPP
                     %     [variable, symbol, arity](replaceTerm
                     %                               (s,
                     %                                finseq_appl
                     %                                [term
                     %                                 [variable,
                     %                                  symbol,
                     %                                  arity]]
                     %                                (fst)(n),
                     %                                finseq_appl
                     %                                [position
                     %                                 [variable,
                     %                                  symbol,
                     %                                  arity]]
                     %                                (fsp)(n)))
  replace_par_pos_equivalence1_TCC3: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term], n: nat,
            s: term[variable, symbol, arity]):
      n < fsp`length AND
       fst`length = fsp`length AND fsp`length /= 0 AND SPP?(s)(fsp)
       IMPLIES
       SPP?[variable, symbol, arity]
           (replaceTerm[variable, symbol, arity]
                (s, finseq_appl[term[variable, symbol, arity]](fst)(n),
                 finseq_appl[position[variable, symbol, arity]](fsp)(n)))
           (delete[position[variable, symbol, arity]](fsp, n));

  % Subtype TCC generated (at line 459, column 70) for  delete[term](fst, n)
      % expected type  {fst_1 | fst_1`length = delete(fsp, n)`length}
  replace_par_pos_equivalence1_TCC4: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term], n: nat,
            s: term[variable, symbol, arity]):
      n < fsp`length AND
       fst`length = fsp`length AND fsp`length /= 0 AND SPP?(s)(fsp)
       IMPLIES
       delete[term[variable, symbol, arity]](fst, n)`length =
        delete[position[variable, symbol, arity]](fsp, n)`length;

  % Subtype TCC generated (at line 466, column 51) for  p
      % expected type  positions?
                     %     [variable, symbol, arity](replace_par_pos
                     %                               (t, fsp, fst))
  replace_par_pos_preservs_subterm_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            p: position[variable, symbol, arity],
            t: term[variable, symbol, arity]):
      fst`length = fsp`length AND SPP?(t)(add_first(p, fsp)) IMPLIES
       positionsOF[variable, symbol, arity](replace_par_pos(t, fsp, fst))(p);

  % Subtype TCC generated (at line 466, column 69) for  p
      % expected type  positions?[variable, symbol, arity](t)
  replace_par_pos_preservs_subterm_TCC2: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            p: position[variable, symbol, arity],
            t: term[variable, symbol, arity]):
      fst`length = fsp`length AND SPP?(t)(add_first(p, fsp)) IMPLIES
       positionsOF[variable, symbol, arity](t)(p);

  % Subtype TCC generated (at line 472, column 85) for
      % finseq_appl[position[variable, symbol, arity]](fsp)(i)
      % expected type  positions?
                     %     [variable, symbol, arity](replace_par_pos
                     %                               (t, fsp, fst))
  replace_par_pos_subterm_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            t: term[variable, symbol, arity]):
      fst`length = fsp`length AND SPP?(t)(fsp) IMPLIES
       (FORALL (i: below[fsp`length]):
          positionsOF[variable, symbol, arity]
              (replace_par_pos(t, fsp, fst))
              (finseq_appl[position[variable, symbol, arity]](fsp)(i)));

  % Subtype TCC generated (at line 472, column 97) for  i
      % expected type  below[length(fst)]
  replace_par_pos_subterm_TCC2: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            t: term[variable, symbol, arity]):
      fst`length = fsp`length AND SPP?(t)(fsp) IMPLIES
       (FORALL (i: below[fsp`length]): i < length(fst));

  % Subtype TCC generated (at line 479, column 44) for  fst1 o fst2
      % expected type  {fst | fst`length = (fsp1 o fsp2)`length}
  replace_par_pos_comp_TCC1: OBLIGATION
    FORALL (fsp1, fsp2: finseq[position], fst1, fst2: finseq[term],
            t: term[variable, symbol, arity]):
      fst2`length = fsp2`length AND
       fst1`length = fsp1`length AND SPP?(t)(fsp1 o fsp2)
       IMPLIES
       (o[term[variable, symbol, arity]](fst1, fst2))`length =
        (o[position[variable, symbol, arity]](fsp1, fsp2))`length;

  % Subtype TCC generated (at line 480, column 59) for  fsp1
      % expected type  SPP[variable, symbol, arity](t)
  replace_par_pos_comp_TCC2: OBLIGATION
    FORALL (fsp1, fsp2: finseq[position], fst1, fst2: finseq[term],
            t: term[variable, symbol, arity]):
      fst2`length = fsp2`length AND
       fst1`length = fsp1`length AND SPP?(t)(fsp1 o fsp2)
       IMPLIES SPP?[variable, symbol, arity](t)(fsp1);

  % Subtype TCC generated (at line 480, column 71) for  fsp2
      % expected type  SPP
                     %     [variable, symbol, arity](replace_par_pos
                     %                               (t, fsp1, fst1))
  replace_par_pos_comp_TCC3: OBLIGATION
    FORALL (fsp1, fsp2: finseq[position], fst1, fst2: finseq[term],
            t: term[variable, symbol, arity]):
      fst2`length = fsp2`length AND
       fst1`length = fsp1`length AND SPP?(t)(fsp1 o fsp2)
       IMPLIES
       SPP?[variable, symbol, arity](replace_par_pos(t, fsp1, fst1))(fsp2);

  % Subtype TCC generated (at line 488, column 65) for  fsp2 o fsp1
      % expected type  SPP[variable, symbol, arity](t)
  replace_par_pos_comp_commute_TCC1: OBLIGATION
    FORALL (fsp1, fsp2: finseq[position], fst1, fst2: finseq[term],
            t: term[variable, symbol, arity]):
      fst2`length = fsp2`length AND
       fst1`length = fsp1`length AND SPP?(t)(fsp1 o fsp2)
       IMPLIES
       SPP?[variable, symbol, arity]
           (t)(o[position[variable, symbol, arity]](fsp2, fsp1));

  % Subtype TCC generated (at line 488, column 78) for  fst2 o fst1
      % expected type  {fst | fst`length = (fsp2 o fsp1)`length}
  replace_par_pos_comp_commute_TCC2: OBLIGATION
    FORALL (fsp1, fsp2: finseq[position], fst1, fst2: finseq[term],
            t: term[variable, symbol, arity]):
      fst2`length = fsp2`length AND
       fst1`length = fsp1`length AND SPP?(t)(fsp1 o fsp2)
       IMPLIES
       (o[term[variable, symbol, arity]](fst2, fst1))`length =
        (o[position[variable, symbol, arity]](fsp2, fsp1))`length;

  % Subtype TCC generated (at line 506, column 46) for  rest(fsp)
      % expected type  PP[variable, symbol, arity]
  complement_pos_TCC1: OBLIGATION
    FORALL (p: position[variable, symbol, arity],
            (fsp: PP[variable, symbol, arity])):
      nonempty?(complement_pos_set(p, fsp`seq(0))) AND NOT length(fsp) = 0
       IMPLIES
       PP?[variable, symbol, arity]
           (rest[position[variable, symbol, arity]](fsp));

  % Termination TCC generated (at line 506, column 29) for
      % complement_pos(p, rest(fsp))
  complement_pos_TCC2: OBLIGATION
    FORALL (p: position[variable, symbol, arity],
            (fsp: PP[variable, symbol, arity])):
      nonempty?(complement_pos_set(p, fsp`seq(0))) AND NOT length(fsp) = 0
       IMPLIES
       (length(rest[position[variable, symbol, arity]](fsp))) < (length(fsp));

  % Subtype TCC generated (at line 507, column 36) for  rest(fsp)
      % expected type  PP[variable, symbol, arity]
  complement_pos_TCC3: OBLIGATION
    FORALL (p: position[variable, symbol, arity],
            (fsp: PP[variable, symbol, arity])):
      NOT nonempty?(complement_pos_set(p, fsp`seq(0))) AND
       NOT length(fsp) = 0
       IMPLIES
       PP?[variable, symbol, arity]
           (rest[position[variable, symbol, arity]](fsp));

  % Termination TCC generated (at line 507, column 19) for
      % complement_pos(p, rest(fsp))
  complement_pos_TCC4: OBLIGATION
    FORALL (p: position[variable, symbol, arity],
            (fsp: PP[variable, symbol, arity])):
      NOT nonempty?(complement_pos_set(p, fsp`seq(0))) AND
       NOT length(fsp) = 0
       IMPLIES
       (length(rest[position[variable, symbol, arity]](fsp))) < (length(fsp));

  % Subtype TCC generated (at line 530, column 47) for  fsp
      % expected type  PP[variable, symbol, arity]
  complement_pos_empty_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], p: position[variable, symbol, arity]):
      PP?(add_first(p, fsp)) IMPLIES PP?[variable, symbol, arity](fsp);

  % Subtype TCC generated (at line 556, column 25) for  i
      % expected type  below[comp_pos(p, fsp)`length]
  comp_pos_character_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], p: position[variable, symbol, arity],
            i: below[fsp`length]):
      i < comp_pos(p, fsp)`length;

  % Subtype TCC generated (at line 566, column 91) for  comp_pos(q, fsp)
      % expected type  SPP[variable, symbol, arity](replaceTerm(t, s, q))
  replace_replace_par_pos_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            q: position[variable, symbol, arity],
            s, t: term[variable, symbol, arity]):
      fst`length = fsp`length AND SPP?(s)(fsp) AND positionsOF(t)(q) IMPLIES
       SPP?[variable, symbol, arity]
           (replaceTerm[variable, symbol, arity](t, s, q))(comp_pos(q, fsp));

  % Subtype TCC generated (at line 566, column 108) for  fst
      % expected type  {fst | fst`length = comp_pos(q, fsp)`length}
  replace_replace_par_pos_TCC2: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            q: position[variable, symbol, arity],
            s, t: term[variable, symbol, arity]):
      fst`length = fsp`length AND SPP?(s)(fsp) AND positionsOF(t)(q) IMPLIES
       fst`length = comp_pos(q, fsp)`length;

  % Subtype TCC generated (at line 572, column 22) for  complement_pos(p, fsp)
      % expected type  PP[variable, symbol, arity]
  complement_pos_preservs_sub_pos_length_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], p: position[variable, symbol, arity]):
      PP?(fsp) IMPLIES PP?[variable, symbol, arity](complement_pos(p, fsp));

  % Subtype TCC generated (at line 606, column 57) for  0
      % expected type  below[fsp`length]
  comp_pos_in_SP_preservs_SP_in_replace_TCC1: OBLIGATION
    FORALL (fsp, fsp1: finseq[position],
            s, t: term[variable, symbol, arity]):
      fsp`length > 0 AND SP?(s)(fsp1) AND SPP?(t)(fsp) IMPLIES 0 < fsp`length;

  % Subtype TCC generated (at line 606, column 27) for  fsp`seq(0)
      % expected type  positions?[variable, symbol, arity](t)
  comp_pos_in_SP_preservs_SP_in_replace_TCC2: OBLIGATION
    FORALL (fsp, fsp1: finseq[position],
            s, t: term[variable, symbol, arity]):
      fsp`length > 0 AND SP?(s)(fsp1) AND SPP?(t)(fsp) IMPLIES
       positionsOF[variable, symbol, arity](t)(fsp`seq(0));

  % Subtype TCC generated (at line 610, column 26) for  0
      % expected type  below[fsp`length]
  comp_pos_in_PP_preservs_PP_TCC1: OBLIGATION
    FORALL (fsp, fsp1: finseq[position]):
      fsp`length > 0 AND PP?(fsp1) AND PP?(fsp) IMPLIES 0 < fsp`length;

  % Subtype TCC generated (at line 614, column 58) for  0
      % expected type  below[fsp`length]
  comp_pos_in_SPP_preservs_SPP_in_replace_TCC1: OBLIGATION
    FORALL (fsp, fsp1: finseq[position],
            s, t: term[variable, symbol, arity]):
      fsp`length > 0 AND SPP?(s)(fsp1) AND SPP?(t)(fsp) IMPLIES
       0 < fsp`length;

  % Subtype TCC generated (at line 614, column 28) for  fsp`seq(0)
      % expected type  positions?[variable, symbol, arity](t)
  comp_pos_in_SPP_preservs_SPP_in_replace_TCC2: OBLIGATION
    FORALL (fsp, fsp1: finseq[position],
            s, t: term[variable, symbol, arity]):
      fsp`length > 0 AND SPP?(s)(fsp1) AND SPP?(t)(fsp) IMPLIES
       positionsOF[variable, symbol, arity](t)(fsp`seq(0));

  % Subtype TCC generated (at line 618, column 17) for  0
      % expected type  below[fst`length]
  comp_pos_in_SPP_preservs_SPP_in_replace_par_pos_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            t: term[variable, symbol, arity]):
      SPP?(t)(fsp) AND fsp`length = fst`length AND fsp`length /= 0 IMPLIES
       0 < fst`length;

  % Subtype TCC generated (at line 619, column 33) for  fst
      % expected type  {fst | fst`length = fsp`length}
  comp_pos_in_SPP_preservs_SPP_in_replace_par_pos_TCC2: OBLIGATION
    FORALL (fsp, fsp1: finseq[position], fst: finseq[term],
            t: term[variable, symbol, arity]):
      SPP?(t)(fsp) AND
       fsp`length = fst`length AND fsp`length /= 0 AND SPP?(fst`seq(0))(fsp1)
       IMPLIES fst`length = fsp`length;

  % Subtype TCC generated (at line 620, column 26) for  0
      % expected type  below[fsp`length]
  comp_pos_in_SPP_preservs_SPP_in_replace_par_pos_TCC3: OBLIGATION
    FORALL (fsp, fsp1, fsp2: finseq[position], fst: finseq[term],
            t: term[variable, symbol, arity]):
           SPP?(t)(fsp) AND fsp`length = fst`length AND fsp`length /= 0
       AND SPP?(fst`seq(0))(fsp1)
       AND SPP?(replace_par_pos(t, fsp, fst))(fsp2)
       IMPLIES 0 < fsp`length;

  % Subtype TCC generated (at line 633, column 73) for  i
      % expected type  below[length(fst2)]
  parallel_reduction_context_aux2_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], fst1, fst2: finseq[term],
            t: term[variable, symbol, arity]):
      SPP?(t)(fsp) AND fst1`length = fsp`length AND fst2`length = fsp`length
       IMPLIES (FORALL (i: below[fsp`length]): i < length(fst2));

  % Subtype TCC generated (at line 652, column 16) for
      % replace_par_pos(t, fsp, fst)
      % expected type  (app?)
  replace_par_pos_preservs_f_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            t: term[variable, symbol, arity]):
      fst`length = fsp`length AND
       SPP?(t)(fsp) AND app?(t) AND NOT fsp =  #(empty_seq)
       IMPLIES app?[variable, symbol, arity](replace_par_pos(t, fsp, fst));

  % Subtype TCC generated (at line 681, column 44) for  fst
      % expected type  {fst | fst`length = fsp`length}
  replace_par_pos_subterm2_TCC1: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            p, p1: position[variable, symbol, arity],
            s: term[variable, symbol, arity]):
           fsp`length = fst`length AND p /= p1 AND p <= p1
       AND member_seq(p1, fsp) AND SPP?(s)(fsp)
       IMPLIES
       (FORALL (fst1):
          complement_pos(p, fsp)`length = fst1`length IMPLIES
           fst`length = fsp`length);

  % Subtype TCC generated (at line 681, column 50) for  p
      % expected type  positions?
                     %     [variable, symbol, arity](replace_par_pos
                     %                               (s, fsp, fst))
  replace_par_pos_subterm2_TCC2: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            p, p1: position[variable, symbol, arity],
            s: term[variable, symbol, arity]):
           fsp`length = fst`length AND p /= p1 AND p <= p1
       AND member_seq(p1, fsp) AND SPP?(s)(fsp)
       IMPLIES
       (FORALL (fst1):
          complement_pos(p, fsp)`length = fst1`length IMPLIES
           positionsOF[variable, symbol, arity]
               (replace_par_pos(s, fsp, fst))(p));

  % Subtype TCC generated (at line 682, column 46) for  p
      % expected type  positions?[variable, symbol, arity](s)
  replace_par_pos_subterm2_TCC3: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            p, p1: position[variable, symbol, arity],
            s: term[variable, symbol, arity]):
           fsp`length = fst`length AND p /= p1 AND p <= p1
       AND member_seq(p1, fsp) AND SPP?(s)(fsp)
       IMPLIES
       (FORALL (fst1):
          complement_pos(p, fsp)`length = fst1`length IMPLIES
           positionsOF[variable, symbol, arity](s)(p));

  % Subtype TCC generated (at line 682, column 50) for  complement_pos(p, fsp)
      % expected type  SPP[variable, symbol, arity](subtermOF(s, p))
  replace_par_pos_subterm2_TCC4: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            p, p1: position[variable, symbol, arity],
            s: term[variable, symbol, arity]):
           fsp`length = fst`length AND p /= p1 AND p <= p1
       AND member_seq(p1, fsp) AND SPP?(s)(fsp)
       IMPLIES
       (FORALL (fst1):
          complement_pos(p, fsp)`length = fst1`length IMPLIES
           SPP?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity](s, p))
               (complement_pos(p, fsp)));

  % Subtype TCC generated (at line 682, column 74) for  fst1
      % expected type  {fst | fst`length = complement_pos(p, fsp)`length}
  replace_par_pos_subterm2_TCC5: OBLIGATION
    FORALL (fsp: finseq[position], fst: finseq[term],
            p, p1: position[variable, symbol, arity],
            s: term[variable, symbol, arity]):
           fsp`length = fst`length AND p /= p1 AND p <= p1
       AND member_seq(p1, fsp) AND SPP?(s)(fsp)
       IMPLIES
       (FORALL (fst1):
          complement_pos(p, fsp)`length = fst1`length IMPLIES
           fst1`length = complement_pos(p, fsp)`length);

  % Subtype TCC generated (at line 692, column 45) for  fsp`seq(i)
      % expected type  {p | positionsOF(s)(p) & positionsOF(t)(p)}
  D_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            (fsp: finseq[position]
                 | SPP?[variable, symbol, arity](s)(fsp) &
                    SPP?[variable, symbol, arity](t)(fsp)),
            E: set[rewrite_rule[variable, symbol, arity]],
            i: below[fsp`length], e: rewrite_rule[variable, symbol, arity]):
      member(e, E) IMPLIES
       (FORALL (sigma):
          positionsOF[variable, symbol, arity](s)(fsp`seq(i)) &
           positionsOF[variable, symbol, arity](t)(fsp`seq(i)));

  % Subtype TCC generated (at line 695, column 56) for  fsp`seq(i)
      % expected type  {p | positionsOF(s)(p) & positionsOF(t)(p)}
  G_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            (fsp: finseq[position]
                 | SPP?[variable, symbol, arity](s)(fsp) &
                    SPP?[variable, symbol, arity](t)(fsp)),
            E: set[rewrite_rule[variable, symbol, arity]],
            i: below[fsp`length], sigma: Sub[variable, symbol, arity],
            e: rewrite_rule[variable, symbol, arity]
                | member[rewrite_rule[variable, symbol, arity]](e, E)):
      positionsOF[variable, symbol, arity](s)(fsp`seq(i)) &
       positionsOF[variable, symbol, arity](t)(fsp`seq(i));

  % Subtype TCC generated (at line 723, column 54) for  fsp
      % expected type  SP[variable, symbol, arity](s)
  replace_par_pos_dominance_TCC1: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp, fsp1: finseq[position],
            s, t: term[variable, symbol, arity]):
      (FORALL (i: below[fsp1`length]):
         EXISTS (j: below[fsp`length]): fsp`seq(j) <= fsp1`seq(i))
       AND
       parallel_reduction_fix?(E)(t, s, fsp1) AND
        SPP?(t)(fsp1) AND SPP?(t)(fsp)
       IMPLIES SP?[variable, symbol, arity](s)(fsp);

  % Subtype TCC generated (at line 723, column 41) for  subtermsOF(s, fsp)
      % expected type  {fst | fst`length = fsp`length}
  replace_par_pos_dominance_TCC2: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp, fsp1: finseq[position],
            s, t: term[variable, symbol, arity]):
      (FORALL (i: below[fsp1`length]):
         EXISTS (j: below[fsp`length]): fsp`seq(j) <= fsp1`seq(i))
       AND
       parallel_reduction_fix?(E)(t, s, fsp1) AND
        SPP?(t)(fsp1) AND SPP?(t)(fsp)
       IMPLIES subtermsOF(s, fsp)`length = fsp`length;

  % Subtype TCC generated (at line 735, column 29) for   #(p)
      % expected type  PP[variable, symbol, arity]
  divergence_in_Pos_Over_aux_TCC1: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp2: finseq[position], p: position[variable, symbol, arity],
            t, t2: term[variable, symbol, arity]):
      SPP?(t)(fsp2) AND
       parallel_reduction_fix?(E)(t, t2, fsp2) AND positionsOF(t)(p)
       IMPLIES
       PP?[variable, symbol, arity]( #[position[variable, symbol, arity]](p));

  % Subtype TCC generated (at line 736, column 73) for  p
      % expected type  positions?[variable, symbol, arity](t2)
  divergence_in_Pos_Over_aux_TCC2: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp2: finseq[position], p: position[variable, symbol, arity],
            t, t2: term[variable, symbol, arity]):
      member_seq(p, Pos_Over( #(p), fsp2)) AND
       positionsOF(t)(p) AND
        parallel_reduction_fix?(E)(t, t2, fsp2) AND SPP?(t)(fsp2)
       IMPLIES positionsOF[variable, symbol, arity](t2)(p);

  % Subtype TCC generated (at line 736, column 77) for
      % complement_pos(p, fsp2)
      % expected type  SPP[variable, symbol, arity](subtermOF(t, p))
  divergence_in_Pos_Over_aux_TCC3: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp2: finseq[position], p: position[variable, symbol, arity],
            t, t2: term[variable, symbol, arity]):
      member_seq(p, Pos_Over( #(p), fsp2)) AND
       positionsOF(t)(p) AND
        parallel_reduction_fix?(E)(t, t2, fsp2) AND SPP?(t)(fsp2)
       IMPLIES
       SPP?[variable, symbol, arity]
           (subtermOF[variable, symbol, arity](t, p))
           (complement_pos(p, fsp2));

  % Subtype TCC generated (at line 744, column 34) for  p
      % expected type  positions?[variable, symbol, arity](t)
  divergence_in_Pos_Over_TCC1: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp1, fsp2: finseq[position],
            p: position[variable, symbol, arity],
            t, t1, t2: term[variable, symbol, arity]):
           member_seq(p, Pos_Over(fsp1, fsp2))
       AND parallel_reduction_fix?(E)(t, t2, fsp2)
       AND parallel_reduction_fix?(E)(t, t1, fsp1) AND SPP?(t)(fsp2)
       AND SPP?(t)(fsp1)
       IMPLIES
       (FORALL ((e: rewrite_rule[variable, symbol, arity]
                     | member[rewrite_rule[variable, symbol, arity]](e, E)),
                sigma: Sub[variable, symbol, arity]):
          positionsOF[variable, symbol, arity](t)(p));

  % Subtype TCC generated (at line 745, column 35) for  p
      % expected type  positions?[variable, symbol, arity](t1)
  divergence_in_Pos_Over_TCC2: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp1, fsp2: finseq[position],
            p: position[variable, symbol, arity],
            t, t1, t2: term[variable, symbol, arity]):
           member_seq(p, Pos_Over(fsp1, fsp2))
       AND parallel_reduction_fix?(E)(t, t2, fsp2)
       AND parallel_reduction_fix?(E)(t, t1, fsp1) AND SPP?(t)(fsp2)
       AND SPP?(t)(fsp1)
       IMPLIES
       (FORALL ((e: rewrite_rule[variable, symbol, arity]
                     | member[rewrite_rule[variable, symbol, arity]](e, E)),
                sigma: Sub[variable, symbol, arity]):
          subtermOF(t, p) = ext(sigma)(lhs(e)) IMPLIES
           positionsOF[variable, symbol, arity](t1)(p));

  % Subtype TCC generated (at line 746, column 73) for  p
      % expected type  positions?[variable, symbol, arity](t2)
  divergence_in_Pos_Over_TCC3: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp1, fsp2: finseq[position],
            p: position[variable, symbol, arity],
            t, t1, t2: term[variable, symbol, arity]):
           member_seq(p, Pos_Over(fsp1, fsp2))
       AND parallel_reduction_fix?(E)(t, t2, fsp2)
       AND parallel_reduction_fix?(E)(t, t1, fsp1) AND SPP?(t)(fsp2)
       AND SPP?(t)(fsp1)
       IMPLIES
       (FORALL ((e: rewrite_rule[variable, symbol, arity]
                     | member[rewrite_rule[variable, symbol, arity]](e, E)),
                sigma: Sub[variable, symbol, arity]):
          subtermOF(t1, p) = ext(sigma)(rhs(e)) AND
           subtermOF(t, p) = ext(sigma)(lhs(e))
           IMPLIES positionsOF[variable, symbol, arity](t2)(p));

  % Subtype TCC generated (at line 756, column 43) for
      % finseq_appl[position[variable, symbol, arity]](fsp)(i)
      % expected type  positions?[variable, symbol, arity](t1)
  subterm_joinability_TCC1: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp, fsp1, fsp2: finseq[position],
            t, t1, t2: term[variable, symbol, arity]):
           fsp =
            Pos_Over(fsp1, fsp2) o Pos_Over(fsp2, fsp1) o
             Pos_Equal(fsp1, fsp2)
       AND parallel_reduction_fix?(E)(t, t2, fsp2)
       AND parallel_reduction_fix?(E)(t, t1, fsp1) AND SPP?(t)(fsp2)
       AND SPP?(t)(fsp1) AND Orthogonal?(E)
       IMPLIES
       (FORALL (i: below[fsp`length]):
          positionsOF[variable, symbol, arity]
              (t1)(finseq_appl[position[variable, symbol, arity]](fsp)(i)));

  % Subtype TCC generated (at line 757, column 43) for
      % finseq_appl[position[variable, symbol, arity]](fsp)(i)
      % expected type  positions?[variable, symbol, arity](t2)
  subterm_joinability_TCC2: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp, fsp1, fsp2: finseq[position],
            t, t1, t2: term[variable, symbol, arity]):
           fsp =
            Pos_Over(fsp1, fsp2) o Pos_Over(fsp2, fsp1) o
             Pos_Equal(fsp1, fsp2)
       AND parallel_reduction_fix?(E)(t, t2, fsp2)
       AND parallel_reduction_fix?(E)(t, t1, fsp1) AND SPP?(t)(fsp2)
       AND SPP?(t)(fsp1) AND Orthogonal?(E)
       IMPLIES
       (FORALL (i: below[fsp`length], s):
          parallel_reduction?(E)
                             (subtermOF(t1,
                                        finseq_appl
                                        [position[variable, symbol, arity]]
                                        (fsp)(i)),
                              s)
           IMPLIES
           positionsOF[variable, symbol, arity]
               (t2)(finseq_appl[position[variable, symbol, arity]](fsp)(i)));

  % Subtype TCC generated (at line 767, column 56) for  i
      % expected type  below[length(fst)]
  subterms_joinability_TCC1: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp, fsp1, fsp2: finseq[position],
            t, t1, t2: term[variable, symbol, arity]):
           fsp =
            Pos_Over(fsp1, fsp2) o Pos_Over(fsp2, fsp1) o
             Pos_Equal(fsp1, fsp2)
       AND parallel_reduction_fix?(E)(t, t2, fsp2)
       AND parallel_reduction_fix?(E)(t, t1, fsp1) AND SPP?(t)(fsp2)
       AND SPP?(t)(fsp1) AND Orthogonal?(E)
       IMPLIES
       (FORALL (fst):
          fsp`length = fst`length IMPLIES
           (FORALL (i: below[fsp`length]): i < length(fst)));

  % Subtype TCC generated (at line 768, column 43) for
      % finseq_appl[position[variable, symbol, arity]](fsp)(i)
      % expected type  positions?[variable, symbol, arity](t2)
  subterms_joinability_TCC2: OBLIGATION
    FORALL (E: set[rewrite_rule[variable, symbol, arity]],
            fsp, fsp1, fsp2: finseq[position],
            t, t1, t2: term[variable, symbol, arity]):
           fsp =
            Pos_Over(fsp1, fsp2) o Pos_Over(fsp2, fsp1) o
             Pos_Equal(fsp1, fsp2)
       AND parallel_reduction_fix?(E)(t, t2, fsp2)
       AND parallel_reduction_fix?(E)(t, t1, fsp1) AND SPP?(t)(fsp2)
       AND SPP?(t)(fsp1) AND Orthogonal?(E)
       IMPLIES
       (FORALL (fst):
          fsp`length = fst`length IMPLIES
           (FORALL (i: below[fsp`length]):
              parallel_reduction?(E)
                                 (subtermOF(t1,
                                            finseq_appl
                                            [position
                                             [variable, symbol, arity]]
                                            (fsp)(i)),
                                  finseq_appl[term[variable, symbol, arity]]
                                      (fst)(i))
               IMPLIES
               positionsOF[variable, symbol, arity]
                   (t2)
                   (finseq_appl[position[variable, symbol, arity]](fsp)(i))));


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andréia Borges Avelar and
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil 
  %%
  %%                         and 
  %%
  %%                   Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil 
  %%    
  %% Last Modified On: April 27, 2011
  %%
  %%----------------------------------------------------------------------------

  robinsonunification[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY
  BEGIN

     ASSUMING

       IMPORTING variables_term[variable,symbol,arity],
                 sets_aux@countability[term],
                 sets_aux@countable_props[term]

       var_countable : ASSUMPTION is_countably_infinite(V)
        var_nonempty : ASSUMPTION nonempty?(V)
     symbol_nonempty : ASSUMPTION nonempty?({f : symbol | arity(f) = 1})
     ENDASSUMING

     IMPORTING unification[variable,symbol, arity]


                   Vs: VAR set[(V)]
               V1, V2: VAR finite_set[(V)]
                   V3: VAR finite_set[term]
              x, y, z: VAR (V)
      tau, sig, sigma, 
    delta, rho, theta: VAR Sub 
                   xx: (V)
                   ff: {f : symbol | arity(f) = 1}
                 fail: Sub = id WITH [ xx := app(ff,#(xx)) ]
              st, stp: VAR finseq[term]
      r, s, t, t1, t2: VAR term
                    n: VAR nat
         p, q, p1, p2: VAR position
                    R: VAR pred[[term, term]]

            
  %%%% Position of the first difference between %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%% two different terms %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   first_diff(s : term, (t : term | s /= t ) ):
     RECURSIVE position =
      (CASES s OF
         vars(s) : empty_seq,
         app(f, st) :
         IF length(st) = 0 THEN empty_seq
         ELSE 
          (CASES t OF
             vars(t) : empty_seq,
             app(fp, stp) : 
             IF f = fp THEN
               LET k : below[length(stp)] = 
                  min({kk : below[length(stp)] |
                            subtermOF(s,#(kk+1)) /= subtermOF(t,#(kk+1))}) IN
                  add_first(k+1,
                         first_diff(subtermOF(s,#(k+1)),subtermOF(t,#(k+1))))
             ELSE empty_seq ENDIF
           ENDCASES)
         ENDIF
       ENDCASES)
   MEASURE s BY << 


  %%%% Lemmas about first_diff %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  comutative_first_diff : LEMMA
     FORALL (s : term, t : term | s /= t, p : position) :
       p = first_diff(s, t) IMPLIES p = first_diff(t,s)

  position_s_first_diff : LEMMA 
     FORALL (s : term, t : term | s /= t, p : position) :
       p = first_diff(s, t) IMPLIES positionsOF(s)(p)

  position_t_first_diff : LEMMA
     FORALL (s : term, t : term | s /= t, p : position) :
       p = first_diff(s, t) IMPLIES positionsOF(t)(p)

  first_diff_has_diff_argument : LEMMA
     FORALL (s : term, t : term | s /= t, p : position):
       p = first_diff(s, t) IMPLIES subtermOF(s, p) /= subtermOF(t, p)

  first_diff_unifiable_vars : LEMMA
     FORALL (s : term, t : term | s /= t, p : position):
       p = first_diff(s, t) AND unifiable(s,t) IMPLIES
   	vars?(subtermOF(s, p)) OR vars?(subtermOF(t, p))
   
  fd_equal_symbol : LEMMA
      FORALL (s : term,
              t : term | s /= t) :
        LET fd = first_diff(s, t) IN
           ( FORALL (p : position | positionsOF(s)(p) AND
                                    positionsOF(t)(p)):
                    child(fd, p) =>
                      f(subtermOF(s, p)) =  f(subtermOF(t, p)) )

  %%%% Substitution to fix the %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%%%%%% first difference %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   link_of_frst_diff(s : term , (t : term | s /= t )) : Sub =
    LET k : position = first_diff(s,t) IN
       LET sp = subtermOF(s,k) , tp = subtermOF(t,k) IN 
          IF vars?(sp) 
          THEN IF NOT member(sp, Vars(tp))
               THEN (LAMBDA (x : (V)) : IF x = sp THEN tp ELSE x ENDIF)
               ELSE fail ENDIF 
          ELSE 
             IF vars?(tp) 
             THEN IF NOT member(tp, Vars(sp))
                  THEN (LAMBDA (x : (V)) : IF x = tp THEN sp ELSE x ENDIF)
                  ELSE fail ENDIF           
             ELSE fail ENDIF 
          ENDIF

  %%%% Lemmas about "link_of_frst_diff" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  dom_link_of_frst_diff_is : LEMMA
      FORALL (s : term, t : term | s /= t):
        LET sig = link_of_frst_diff(s, t) IN
          NOT sig = fail AND p = first_diff(s, t) IMPLIES
             IF vars?(subtermOF(s, p))
               THEN Dom(sig) = singleton(subtermOF(s, p))
               ELSE Dom(sig) = singleton(subtermOF(t, p))
             ENDIF

  dom_ran_link_disjoint : LEMMA
      FORALL (s : term, t : term | s /= t): 
         LET sig = link_of_frst_diff(s ,t) IN 
             NOT sig = fail IMPLIES
             FORALL ( x | member(x,Dom(sig)), r | member(r,Ran(sig) )) :
                 NOT member(x, Vars(r))

  link_remove_x : LEMMA
      FORALL (s : term, t : term | s /= t):
         LET sig = link_of_frst_diff(s, t) IN
           (NOT sig = fail AND  Dom(sig)(x)) IMPLIES  
              (NOT member(x, Vars(ext(sig)(s)))) AND
              (NOT member(x, Vars(ext(sig)(t))))

  link_of_frst_diff_s_is_subset_union : LEMMA
      FORALL (s : term, t : term |  s /= t):
          LET sig = link_of_frst_diff(s, t) IN
             NOT sig = fail IMPLIES 
             subset?(Vars(ext(sig)(s)), union( Vars(s), Vars(t)))

  comutative_link_fd : LEMMA
      FORALL (s : term, t : term |  s /= t):
          LET p = first_diff(s, t) IN
           NOT vars?(subtermOF(s,p)) IMPLIES
             link_of_frst_diff(s, t) = link_of_frst_diff(t, s)
   
  link_of_frst_diff_t_is_subset_union : LEMMA
      FORALL (s : term, t : term |  s /= t):
          LET sig = link_of_frst_diff(s, t) IN
              NOT sig = fail IMPLIES 
              subset?(Vars(ext(sig)(t)), union( Vars(s), Vars(t)))

  union_vars_ext_link : LEMMA
      FORALL (s : term, t : term | s /= t) :
          LET sig = link_of_frst_diff(s, t) IN
             NOT sig = fail IMPLIES
               union(Vars(ext(sig)(s)), Vars(ext(sig)(t)))
                = difference(union( Vars(s), Vars(t)), Dom(sig))

  termination_lemma : LEMMA
    FORALL (s : term, t : term | s /= t):
           LET sig = link_of_frst_diff(s, t) IN
             NOT sig = fail IMPLIES
               Card(union( Vars(ext(sig)(s)), Vars(ext(sig)(t))))
               < Card(union( Vars(s), Vars(t)))

  unifiable_implies_not_fail : LEMMA
    FORALL (s : term, t : term | s /= t):
           LET sig = link_of_frst_diff(s, t) IN
              unifiable(s, t) IMPLIES
              NOT sig = fail

  preserving_generality : LEMMA
      FORALL (s : term, t : term | s /= t):
          member(rho, U(s, t)) IMPLIES
             LET sig = link_of_frst_diff(s, t) IN
                EXISTS theta : rho = comp(theta, sig)

  unifiable_preserves_unifiability : LEMMA
    FORALL (s : term, t : term | s /= t):
           LET sig = link_of_frst_diff(s, t) IN
              unifiable(s, t) IMPLIES
              unifiable(ext(sig)(s),ext(sig)(t))


  %%%% Function to compute mgu's of unifiable terms %%%%%%%%%%%%%%%%%%%%%
  %%%%%%%%%% or to report failure of non unifiable terms %%%%%%%%%%%%%%%%

   robinson_unification_algorithm(s, t : term) : RECURSIVE Sub =
      IF s = t THEN identity  
      ELSE LET sig = link_of_frst_diff(s,t) IN
         IF sig = fail THEN fail
         ELSE 
         LET sigma = robinson_unification_algorithm(ext(sig)(s) , ext(sig)(t)) IN
                IF sigma = fail THEN fail ELSE comp(sigma, sig) ENDIF
         ENDIF
      ENDIF
   MEASURE Card(union(Vars(s), Vars(t)))


  %%%% Lemmas about "robinson_unification_algorithm" %%%%%%%%%%%%%%%%%%%%

   var_ext_term_exists_var_term : LEMMA
     member(x, Vars(ext(sigma)(r)))
       IMPLIES EXISTS y: member(y, Vars(r)) AND member(x, Vars(sigma(y)))

   rob_uni_alg_dom_subset_union_vars : LEMMA
      unifiable(s, t) IMPLIES 
         LET sigma = robinson_unification_algorithm(s, t) IN
            subset?( Dom(sigma), union(Vars(s), Vars(t)) )

   rob_uni_alg_vran_subset_union : LEMMA
      FORALL (s : term, t : term | s /= t):
      LET sig1 = link_of_frst_diff(s, t) IN
        LET sig2 = robinson_unification_algorithm(ext(sig1)(s), ext(sig1)(t)) IN
          unifiable(s, t) IMPLIES
            subset?(VRan(comp(sig2, sig1)), 
                    union(VRan(sig2), difference(VRan(sig1), Dom(sig2))))

   rob_uni_alg_dom_ran_disjoint : LEMMA
      unifiable(s,t) IMPLIES
            LET sigma = robinson_unification_algorithm(s, t) IN
             subset?( VRan(sigma) , 
                       difference( union(Vars(s), Vars(t)), Dom(sigma) ))

   robinson_unification_algorithm_fails_iff_non_unifiable : LEMMA
    NOT unifiable(s,t) IFF robinson_unification_algorithm(s,t) = fail

  %%%% Soundness of "robinson_unification_algorithm" %%%%%%%%%%%%%%%%%%%%

   robinson_unification_algorithm_gives_unifier : LEMMA
      unifiable(s,t) IFF member(robinson_unification_algorithm(s, t), U(s, t))
   
   robinson_unification_algorithm_gives_mg_subs : LEMMA
      member(rho, U(s, t)) IMPLIES robinson_unification_algorithm(s, t) <= rho
   
  %%%% Completeness of  "robinson_unification_algorithm" %%%%%%%%%%%%%%%%

   completeness_robinson_unification_algorithm : THEOREM
     IF unifiable(s,t) THEN  mgu(robinson_unification_algorithm(s,t))(s,t)
                       ELSE  robinson_unification_algorithm(s,t) = fail 
     ENDIF
   

  END robinsonunification

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 30, column 13) for
      % unification[variable, symbol, arity]
      % generated from assumption unification.var_countable
  IMP_unification_TCC1: OBLIGATION
    is_countably_infinite[term[variable, symbol, arity]]
        (V[variable, symbol, arity]);

  % Existence TCC generated (at line 39, column 17) for  xx: (V)
  xx_TCC1: OBLIGATION EXISTS (x: (V[variable, symbol, arity])): TRUE;

  % Existence TCC generated (at line 40, column 17) for
      % ff: {f: symbol | arity(f) = 1}
  ff_TCC1: OBLIGATION EXISTS (x: {f: symbol | arity(f) = 1}): TRUE;

  % Subtype TCC generated (at line 41, column 50) for   #(xx)
      % expected type  {args:
                     %    finite_sequence[term[variable, symbol, arity]] |
                     %          args`length = arity(ff)}
  fail_TCC1: OBLIGATION
     #[term[variable, symbol, arity]](xx)`length = arity(ff);

  % Subtype TCC generated (at line 41, column 27) for
      % id WITH [xx := app(ff,  #(xx))]
      % expected type  Sub[variable, symbol, arity]
  fail_TCC2: OBLIGATION
    Sub?[variable, symbol, arity]
        ((id[(V)]
            WITH [xx
                    := app[variable, symbol, arity]
                           (ff,  #[term[variable, symbol, arity]](xx))]));

  % Subtype TCC generated (at line 67, column 46) for   #(k + 1)
      % expected type  positions?[variable, symbol, arity](s)
  first_diff_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | s /= t), f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          f = fp AND t = app(fp, stp) IMPLIES
           (FORALL (k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               positionsOF[variable, symbol, arity](s)( #[posnat](k + 1))));

  % Subtype TCC generated (at line 67, column 66) for   #(k + 1)
      % expected type  positions?[variable, symbol, arity](t)
  first_diff_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | s /= t), f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          f = fp AND t = app(fp, stp) IMPLIES
           (FORALL (k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               positionsOF[variable, symbol, arity](t)( #[posnat](k + 1))));

  % Subtype TCC generated (at line 67, column 54) for  subtermOF(t,  #(k + 1))
      % expected type  {t: term | NOT subtermOF(s,  #(1 + k)) = t}
  first_diff_TCC3: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | s /= t), f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          f = fp AND t = app(fp, stp) IMPLIES
           (FORALL (k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               NOT subtermOF[variable, symbol, arity](s,  #[posnat](1 + k)) =
                    subtermOF[variable, symbol, arity]
                        (t,  #[posnat](k + 1))));

  % Termination TCC generated (at line 67, column 23) for
      % first_diff(subtermOF(s,  #(k + 1)), subtermOF(t,  #(k + 1)))
  first_diff_TCC4: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | s /= t), f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          f = fp AND t = app(fp, stp) IMPLIES
           (FORALL (k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               <<[variable, symbol, arity]
                   (subtermOF[variable, symbol, arity](s,  #[posnat](k + 1)),
                    s)));

  % Subtype TCC generated (at line 65, column 38) for   #(kk + 1)
      % expected type  positions?[variable, symbol, arity](s)
  first_diff_TCC5: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | s /= t), f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          f = fp AND t = app(fp, stp) IMPLIES
           (FORALL (kk: below[length(stp)], k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               positionsOF[variable, symbol, arity](s)( #[posnat](kk + 1))));

  % Subtype TCC generated (at line 65, column 62) for   #(kk + 1)
      % expected type  positions?[variable, symbol, arity](t)
  first_diff_TCC6: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | s /= t), f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          f = fp AND t = app(fp, stp) IMPLIES
           (FORALL (kk: below[length(stp)], k: below[length(stp)]):
              k =
               min({kk: below[length(stp)] |
                      subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))})
               IMPLIES
               positionsOF[variable, symbol, arity](t)( #[posnat](kk + 1))));

  % Subtype TCC generated (at line 64, column 20) for
      % {kk: below[length(stp)] |
      %    subtermOF(s,  #(kk + 1)) /= subtermOF(t,  #(kk + 1))}
      % expected type  S: (nonempty?[below[length(stp)]])
  first_diff_TCC7: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | s /= t), f: symbol,
            st:
              {args: finite_sequence[term[variable, symbol, arity]] |
                       args`length = arity(f)}):
      NOT length(st) = 0 AND s = app(f, st) IMPLIES
       (FORALL (fp: symbol,
                stp:
                  {args: finite_sequence[term[variable, symbol, arity]] |
                           args`length = arity(fp)}):
          f = fp AND t = app(fp, stp) IMPLIES
           nonempty?[below[length(stp)]]
               ({kk: below[length(stp)] |
                   subtermOF[variable, symbol, arity](s,  #[posnat](kk + 1))
                    /=
                    subtermOF[variable, symbol, arity]
                        (t,  #[posnat](kk + 1))}));

  % Subtype TCC generated (at line 79, column 51) for  s
      % expected type  {t_1: term | t /= t_1}
  comutative_first_diff_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | s /= t,
            p: position[variable, symbol, arity]):
      p = first_diff(s, t) IMPLIES t /= s;

  % Subtype TCC generated (at line 91, column 47) for  p
      % expected type  positions?[variable, symbol, arity](s)
  first_diff_has_diff_argument_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | s /= t,
            p: position[variable, symbol, arity]):
      p = first_diff(s, t) IMPLIES positionsOF[variable, symbol, arity](s)(p);

  % Subtype TCC generated (at line 91, column 66) for  p
      % expected type  positions?[variable, symbol, arity](t)
  first_diff_has_diff_argument_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | s /= t,
            p: position[variable, symbol, arity]):
      p = first_diff(s, t) IMPLIES positionsOF[variable, symbol, arity](t)(p);

  % Subtype TCC generated (at line 105, column 22) for  subtermOF(s, p)
      % expected type  (app?[variable, symbol, arity])
  fd_equal_symbol_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | s /= t,
            fd: position[variable, symbol, arity]):
      fd = first_diff(s, t) IMPLIES
       (FORALL (p: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity](s)(p) AND
                       positionsOF[variable, symbol, arity](t)(p)):
          child(fd, p) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity](s, p)));

  % Subtype TCC generated (at line 105, column 44) for  subtermOF(t, p)
      % expected type  (app?[variable, symbol, arity])
  fd_equal_symbol_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | s /= t,
            fd: position[variable, symbol, arity]):
      fd = first_diff(s, t) IMPLIES
       (FORALL (p: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity](s)(p) AND
                       positionsOF[variable, symbol, arity](t)(p)):
          child(fd, p) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity](t, p)));

  % Subtype TCC generated (at line 114, column 27) for  sp
      % expected type  (V)
  link_of_frst_diff_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | s /= t),
            k: position[variable, symbol, arity]):
      k = first_diff(s, t) IMPLIES
       (FORALL (sp: term[variable, symbol, arity]):
          sp = subtermOF(s, k) IMPLIES
           (FORALL (tp: term[variable, symbol, arity]):
              vars?(sp) AND tp = subtermOF(t, k) IMPLIES
               V[variable, symbol, arity](sp)));

  % Subtype TCC generated (at line 115, column 19) for
      % (LAMBDA (x: (V)): IF x = sp THEN tp ELSE x ENDIF)
      % expected type  Sub[variable, symbol, arity]
  link_of_frst_diff_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | s /= t),
            k: position[variable, symbol, arity]):
      k = first_diff(s, t) IMPLIES
       (FORALL (sp: term[variable, symbol, arity]):
          sp = subtermOF(s, k) IMPLIES
           (FORALL (tp: term[variable, symbol, arity]):
              NOT member(sp, Vars(tp)) AND vars?(sp) AND tp = subtermOF(t, k)
               IMPLIES
               Sub?[variable, symbol, arity]
                   (LAMBDA (x: (V[variable, symbol, arity])):
                      IF x = sp THEN tp ELSE x ENDIF)));

  % Subtype TCC generated (at line 119, column 30) for  tp
      % expected type  (V)
  link_of_frst_diff_TCC3: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | s /= t),
            k: position[variable, symbol, arity]):
      k = first_diff(s, t) IMPLIES
       (FORALL (sp: term[variable, symbol, arity]):
          sp = subtermOF(s, k) IMPLIES
           (FORALL (tp: term[variable, symbol, arity]):
              vars?(tp) AND NOT vars?(sp) AND tp = subtermOF(t, k) IMPLIES
               V[variable, symbol, arity](tp)));

  % Subtype TCC generated (at line 120, column 22) for
      % (LAMBDA (x: (V)): IF x = tp THEN sp ELSE x ENDIF)
      % expected type  Sub[variable, symbol, arity]
  link_of_frst_diff_TCC4: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            (t: term[variable, symbol, arity] | s /= t),
            k: position[variable, symbol, arity]):
      k = first_diff(s, t) IMPLIES
       (FORALL (sp: term[variable, symbol, arity]):
          sp = subtermOF(s, k) IMPLIES
           (FORALL (tp: term[variable, symbol, arity]):
              NOT member(tp, Vars(sp)) AND
               vars?(tp) AND NOT vars?(sp) AND tp = subtermOF(t, k)
               IMPLIES
               Sub?[variable, symbol, arity]
                   (LAMBDA (x: (V[variable, symbol, arity])):
                      IF x = tp THEN sp ELSE x ENDIF)));

  % Subtype TCC generated (at line 179, column 18) for
      % union(Vars(ext(sig)(s)), Vars(ext(sig)(t)))
      % expected type  finite_set[(V)]
  termination_lemma_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | s /= t,
            sig: Sub[variable, symbol, arity]):
      NOT sig = fail AND sig = link_of_frst_diff(s, t) IMPLIES
       is_finite[(V)]
           (union[(V)]
                (Vars[variable, symbol, arity]
                     (ext[variable, symbol, arity](sig)(s)),
                 Vars[variable, symbol, arity]
                     (ext[variable, symbol, arity](sig)(t))));

  % Subtype TCC generated (at line 180, column 20) for
      % union(Vars(s), Vars(t))
      % expected type  finite_set[(V)]
  termination_lemma_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | s /= t,
            sig: Sub[variable, symbol, arity]):
      NOT sig = fail AND sig = link_of_frst_diff(s, t) IMPLIES
       is_finite[(V)]
           (union[(V)]
                (Vars[variable, symbol, arity](s),
                 Vars[variable, symbol, arity](t)));

  % Subtype TCC generated (at line 213, column 14) for
      % union(Vars(s), Vars(t))
      % expected type  finite_set[(V)]
  robinson_unification_algorithm_TCC1: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity]):
      is_finite[(V)]
          (union[(V)]
               (Vars[variable, symbol, arity](s),
                Vars[variable, symbol, arity](t)));

  % Subtype TCC generated (at line 213, column 14) for
      % union(Vars(z`1), Vars(z`2))
      % expected type  finite_set[(V)]
  robinson_unification_algorithm_TCC2: OBLIGATION
    FORALL (z:
              [term[variable, symbol, arity],
               term[variable, symbol, arity]]):
      is_finite[(V)]
          (union[(V)]
               (Vars[variable, symbol, arity](z`1),
                Vars[variable, symbol, arity](z`2)));

  % Subtype TCC generated (at line 205, column 18) for  identity
      % expected type  Sub[variable, symbol, arity]
  robinson_unification_algorithm_TCC3: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity]):
      s = t IMPLIES Sub?[variable, symbol, arity](identity[(V)]);

  % Termination TCC generated (at line 209, column 19) for
      % robinson_unification_algorithm(ext(sig)(s), ext(sig)(t))
  robinson_unification_algorithm_TCC4: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity]):
      NOT s = t IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          NOT sig = fail AND sig = link_of_frst_diff(s, t) IMPLIES
           Card[(V)]
               (union[(V)]
                    (Vars[variable, symbol, arity]
                         (ext[variable, symbol, arity](sig)(s)),
                     Vars[variable, symbol, arity]
                         (ext[variable, symbol, arity](sig)(t))))
            <
            Card[(V)]
                (union[(V)]
                     (Vars[variable, symbol, arity](s),
                      Vars[variable, symbol, arity](t))));

  % Subtype TCC generated (at line 210, column 45) for  comp(sigma, sig)
      % expected type  Sub[variable, symbol, arity]
  robinson_unification_algorithm_TCC5: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            v:
              [{z:
                  [term[variable, symbol, arity],
                   term[variable, symbol, arity]] |
                        Card(union(Vars(z`1), Vars(z`2))) <
                         Card(union(Vars(s), Vars(t)))} ->
                 Sub[variable, symbol, arity]]):
      NOT s = t IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          NOT sig = fail AND sig = link_of_frst_diff(s, t) IMPLIES
           (FORALL (sigma: Sub[variable, symbol, arity]):
              NOT sigma = fail AND sigma = v(ext(sig)(s), ext(sig)(t))
               IMPLIES
               Sub?[variable, symbol, arity]
                   (comp[variable, symbol, arity](sigma, sig))));

  % Subtype TCC generated (at line 206, column 39) for  t
      % expected type  {t: term | s /= t}
  robinson_unification_algorithm_TCC6: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity]): NOT s = t IMPLIES s /= t;


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%         
  %% Authors         : Andréia Borges Avelar and
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil 
  %%
  %%                         and 
  %%
  %%                   Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil 
  %%    
  %% Last Modified On: June 15, 2011
  %%
  %%----------------------------------------------------------------------------


  robinsonunificationEF[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY
  BEGIN

     ASSUMING

       IMPORTING variables_term[variable,symbol,arity],
                 sets_aux@countability[term],
                 sets_aux@countable_props[term]

       var_countable : ASSUMPTION is_countably_infinite(V)
        var_nonempty : ASSUMPTION nonempty?(V)
     symbol_nonempty : ASSUMPTION nonempty?({f : symbol | arity(f) = 1})
     ENDASSUMING


     IMPORTING robinsonunification[variable,symbol, arity]


                   Vs: VAR set[(V)]
               V1, V2: VAR finite_set[(V)]
                   V3: VAR finite_set[term]
              x, y, z: VAR (V)
      tau, sig, sigma, 
    delta, rho, theta: VAR Sub 
              st, stp: VAR finseq[term]
      r, s, t, t1, t2: VAR term
                    n: VAR nat
     p, q, q1, p1, p2: VAR position
                    R: VAR pred[[term, term]]


  %%%%% Function to compute the set of rigth positions of a %%%%%%%%%%%%
  %%%%% given position of a given term %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   right_pos(s:term, p : position) : RECURSIVE  positions =
    IF NOT positionsOF(s)(p) THEN emptyset
     ELSE
     IF p = empty_seq THEN only_empty_seq
     ELSE 
      LET p1 = delete(p,length(p) - 1) IN 
       LET i: nat = last(p) IN
         LET n: nat = arity(f(subtermOF(s,p1))) IN
           union( union(singleton(p), right_pos(s, p1)), 
                  IUnion(LAMBDA (j : below(n - i)) :
                         {q | EXISTS q1 : positionsOF(subtermOF(s,
                                           add_last(p1, i + j + 1)))(q1)
                                 AND  q = p1 o #( i + j + 1) o q1 }))
     ENDIF
    ENDIF
   MEASURE length(p)


  %%%%% Function to compute the next position of a given position %%%%%%%%
  %%%%% where a conflict between two given terms occurs %%%%%%%%%%%%%%%%%%

   next_position(s, t : term, 
                 p : position | positionsOF(s)(p) AND positionsOF(t)(p)): 
     RECURSIVE position = 
     IF p = empty_seq THEN empty_seq 
     ELSE
       LET pi0 = delete(p,length(p) - 1) IN
        IF f(subtermOF(s,pi0)) /= f(subtermOF(t,pi0)) THEN pi0 
        ELSE     
          LET pi = add_last(delete(p, length(p) - 1), last(p) + 1) IN
          IF positionsOF(s)(pi) THEN 
              IF subtermOF(s, pi) /= subtermOF(t, pi) THEN pi 
              ELSE next_position(s,t, pi) ENDIF
          ELSE IF pi0 /= empty_seq THEN
                      next_position(s, t, pi0)
               ELSE empty_seq 
              ENDIF 
          ENDIF
        ENDIF  
     ENDIF  
    MEASURE IF p = empty_seq 
            THEN lex2(0,0)
            ELSE lex2(length(p), 
                      arity(f(subtermOF(s, 
                                     delete(p,length(p) - 1)))) - last(p))
            ENDIF


  %%%%%%% auxiliary lemmas %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   right_pos_subset : LEMMA
   FORALL (s : term, p : position | positionsOF(s)(p)):
      subset?(right_pos(s, p), positionsOF(s))

   next_position_commute : LEMMA
    FORALL (s, t : term, p : position |
      positionsOF(s)(p) AND positionsOF(t)(p)):
        next_position(s, t, p) = next_position(t, s, p)

   next_position_is_position : LEMMA
    FORALL (s, t : term, p : position |
      positionsOF(s)(p) AND positionsOF(t)(p)):
        positionsOF(s)(next_position(s, t, p))

   next_pos_length_and_last : LEMMA
    FORALL (s, t : term, p : position |
      positionsOF(s)(p) AND positionsOF(t)(p) AND p /= empty_seq):
        length(next_position(s, t, p)) < length(p) OR
        (length(next_position(s, t, p)) = length(p) AND
         last(p) < last(next_position(s, t, p)))

   next_pos_is_a_diff_pos : LEMMA
    FORALL (s, t : term, p : position |
      positionsOF(s)(p) AND positionsOF(t)(p)):
        (NOT p = empty_seq) IMPLIES
        next_position(s, t, p) /= p

   member_right_pos : LEMMA
     FORALL (s : term, p : position | positionsOF(s)(p), 
             q : position | positionsOF(s)(q)):
       (member(q, right_pos(s, p)) AND p /= q) IFF left_pos(p, q)

   next_pos_member_right_pos : LEMMA
    FORALL (s, t : term, p : position |
      positionsOF(s)(p) AND positionsOF(t)(p) AND p /= empty_seq):
        member(next_position(s, t, p), right_pos(s, p))

   equal_right_pos : LEMMA
     FORALL (s : term, p : position | positionsOF(s)(p), 
             q : position | positionsOF(s)(q)):
        right_pos(s, p) = right_pos(s, q) IMPLIES p = q


   subset_right_pos : LEMMA
    FORALL (s : term, p : position | positionsOF(s)(p), 
            q : position | positionsOF(s)(q)):
      member(q, right_pos(s, p)) AND q /= p
        IMPLIES strict_subset?(right_pos(s, q), right_pos(s, p))

   next_pos_to_the_right : LEMMA
      FORALL(s:term, t:term, p: position |
             positionsOF(s)(p) AND positionsOF(t)(p) AND p /= empty_seq ):
        Card(right_pos(s, next_position(s, t, p)))
        < Card(right_pos(s, p))

   ext_link_remove_x : LEMMA
      FORALL(s : term, t : term, p : position | positionsOF(s)(p) AND 
             positionsOF(t)(p) AND subtermOF(s,p) /= subtermOF(t,p)):
          LET sig = link_of_frst_diff(subtermOF(s,p), subtermOF(t,p)) IN
           (NOT sig = fail AND  Dom(sig)(x)) IMPLIES  
              (NOT member(x, Vars(ext(sig)(s)))) AND
              (NOT member(x, Vars(ext(sig)(t))))

   vars_ext_link_s_subset : LEMMA
      FORALL(s : term, t : term, p : position | positionsOF(s)(p) AND 
             positionsOF(t)(p) AND subtermOF(s,p) /= subtermOF(t,p)):
          LET sig = link_of_frst_diff(subtermOF(s,p), subtermOF(t,p)) IN
             NOT sig = fail IMPLIES 
             subset?(Vars(ext(sig)(s)), union( Vars(s), Vars(t)))

   vars_ext_link_t_subset : LEMMA
      FORALL(s : term, t : term, p : position | positionsOF(s)(p) AND 
             positionsOF(t)(p) AND subtermOF(s,p) /= subtermOF(t,p)):
          LET sig = link_of_frst_diff(subtermOF(s,p), subtermOF(t,p)) IN
             NOT sig = fail IMPLIES 
             subset?(Vars(ext(sig)(t)), union( Vars(s), Vars(t)))

   union_vars_ext_link_subterm : LEMMA
    FORALL (s : term, t : term, p : position | 
      positionsOF(s)(p) AND  positionsOF(t)(p) 
      AND subtermOF(s,p) /= subtermOF(t,p)):
        LET sig = link_of_frst_diff(subtermOF(s,p), subtermOF(t,p)) IN
             NOT sig = fail IMPLIES
               union(Vars(ext(sig)(s)), Vars(ext(sig)(t)))
                = difference(union( Vars(s), Vars(t)), Dom(sig))

   termination_lemma_subterm : LEMMA
    FORALL (s : term, t : term, p : position | 
      positionsOF(s)(p) AND  positionsOF(t)(p) 
      AND subtermOF(s,p) /= subtermOF(t,p)):
        LET sig = link_of_frst_diff(subtermOF(s,p), subtermOF(t,p)) IN
             NOT sig = fail IMPLIES
               Card(union( Vars(ext(sig)(s)), Vars(ext(sig)(t))))
               < Card(union( Vars(s), Vars(t)))


  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   subtermOF_next_position : LEMMA
     FORALL (s : term, 
             t : term | s /= t, 
             p : position | positionsOF(s)(p) AND  
  	       		  positionsOF(t)(p)) :
        LET q = next_position(s, t, p) IN
          subtermOF(s, q) /= subtermOF(t, q)

   np_o_fd_is_position : LEMMA
     FORALL (s : term,
     	   t : term | s /= t,
  	   p : position | positionsOF(s)(p) AND
  	       		  positionsOF(t)(p)) :
       LET q = next_position(s, t, p) IN
        LET q1 = first_diff(subtermOF(s,q), subtermOF(t,q)) IN
           positionsOF(t)(q o q1)


   child_np_child_p : LEMMA
     FORALL (s : term, 
             t : term, 
             p : position | positionsOF(s)(p) AND  
  	       		  positionsOF(t)(p)) :
       (FORALL (q: position | positionsOF(s)(q) AND
                              positionsOF(t)(q)):
          child(next_position(s, t, p), q)
           IMPLIES child(p, q))

   next_pos_empty_equal_subterm : LEMMA
     FORALL (s : term, 
             t : term, 
             p : position | positionsOF(s)(p) AND  
  	       		  positionsOF(t)(p) AND 
                            p /= empty_seq ) :
        ( next_position(s, t, p) = empty_seq AND
          FORALL (p1 : position | positionsOF(s)(p1) AND
                                  positionsOF(t)(p1) ):
           child(p, p1) => f(subtermOF(s, p1)) = f(subtermOF(t, p1)) )
        IMPLIES
        ( FORALL (q : position | positionsOF(s)(q) AND  
  	       		       positionsOF(t)(q)):
            left_without_children(p, q) => 
                subtermOF(s, q) = subtermOF(t, q) )

   next_pos_equal_subterm : LEMMA
     FORALL (s : term, 
             t : term, 
             p : position | positionsOF(s)(p) AND  
  	       		  positionsOF(t)(p) AND
                            p /= empty_seq ) :
        ( (FORALL (p1 : position | positionsOF(s)(p1) AND
                                   positionsOF(t)(p1) ):
             child(p, p1) => 
                 f(subtermOF(s, p1)) = f(subtermOF(t, p1)))
         AND 
          (FORALL (q: position | positionsOF(s)(q) AND
                                 positionsOF(t)(q)):
             left_without_children(q, p) =>
                 subtermOF(s, q) = subtermOF(t, q))
         AND
           subtermOF(s, p) = subtermOF(t, p)       
         AND
           next_position(s, t, p) /= empty_seq  )
        IMPLIES
        (  FORALL (q : position | positionsOF(s)(q) AND  
  	       		        positionsOF(t)(q)):
             left_without_children(q, next_position(s, t, p)) => 
                 subtermOF(s, q) = subtermOF(t, q) )

   fd_equal_subterm : LEMMA
    FORALL (s : term, 
            t : term | s /= t,
            p : position | positionsOF(s)(p) AND
                           positionsOF(t)(p) ):
        LET fd = first_diff(s, t) IN
            left_without_children(p, fd) 
               IMPLIES subtermOF(s,p) = subtermOF(t,p)
   
   child_p_o_fd : LEMMA
    FORALL (s : term, 
            t : term, 
            p : position | positionsOF(s)(p) AND
                           positionsOF(t)(p) AND
                           subtermOF(s,p) /= subtermOF(t,p)):
        LET fd = first_diff(subtermOF(s,p), subtermOF(t,p)) IN
             (FORALL (q : position | positionsOF(s)(q) AND
                                     positionsOF(t)(q) ):
                      child(p, q) => 
                      f(subtermOF(s, q)) = f(subtermOF(t, q)))
            IMPLIES (FORALL (q : position | positionsOF(ext(sig)(s))(q) AND
                                            positionsOF(ext(sig)(t))(q) ):
                              child(p o fd, q) => 
                              f(subtermOF(ext(sig)(s), q)) = f(subtermOF(ext(sig)(t), q)))


   separation_lwc_pos : LEMMA
      left_without_children(q, p o p1) AND NOT left_without_children(q, p)
      IMPLIES EXISTS q1: q = p o q1 AND left_without_children(q1, p1)

   lwc_o_fd_empty_seq : LEMMA
    FORALL (s : term, 
            t : term | s /= t):
        LET fd = first_diff(s, t) IN
         ( left_without_children(p, fd) AND positionsOF(s)(p)
           AND p = p1 o p2 AND positionsOF(t)(p1)
           AND vars?(subtermOF(t, p1)) )
         IMPLIES p2 = empty_seq

   lwc_p_o_fd : LEMMA
    FORALL (s : term, 
            t : term, 
            p : position | positionsOF(s)(p) AND
                           positionsOF(t)(p) AND
                           subtermOF(s,p) /= subtermOF(t,p)):
        LET fd = first_diff(subtermOF(s,p), subtermOF(t,p)) IN
             (FORALL (q : position | positionsOF(s)(q) AND
                                     positionsOF(t)(q) ):
                      left_without_children(q, p) => 
                      subtermOF(s, q) = subtermOF(t, q))
            IMPLIES (FORALL (q : position | positionsOF(ext(sig)(s))(q) AND
                                            positionsOF(ext(sig)(t))(q) ):
                              left_without_children(q, p o fd) => 
                              subtermOF(ext(sig)(s), q) = subtermOF(ext(sig)(t), q))

   np_p_o_fd_empty_unifiable_term : LEMMA
    FORALL (s : term, 
            t : term, 
            p : position | positionsOF(s)(p) AND
                           positionsOF(t)(p) AND
                           subtermOF(s,p) /= subtermOF(t,p)):
        LET fd = first_diff(subtermOF(s,p), subtermOF(t,p)) IN
          LET sig = link_of_frst_diff(subtermOF(s,p), subtermOF(t,p)) IN
            (  NOT sig = fail
             AND
               next_position(ext(sig)(s), ext(sig)(t), p o fd) = empty_seq
             AND
               (FORALL (q: position | positionsOF(s)(q) AND 
                                      positionsOF(t)(q)):
                   left_without_children(q, p) =>
                        subtermOF(s, q) = subtermOF(t, q))
             AND
               (FORALL (p1: position | positionsOF(s)(p1) AND
                                       positionsOF(t)(p1)):
                   child(p, p1) => 
                        f(subtermOF(s, p1)) = f(subtermOF(t, p1)))  )
            IMPLIES
              ext(sig)(s) = ext(sig)(t)

   np_p_o_fd_equal_subterm : LEMMA
    FORALL (s : term, 
            t : term, 
            p : position | positionsOF(s)(p) AND
                           positionsOF(t)(p) AND 
                           subtermOF(s,p) /= subtermOF(t,p)):
        LET fd = first_diff(subtermOF(s,p), subtermOF(t,p)) IN
          LET sig = link_of_frst_diff(subtermOF(s,p), subtermOF(t,p)) IN
            (  NOT sig = fail
             AND
               next_position(ext(sig)(s), ext(sig)(t), p o fd) /= empty_seq
             AND
               (FORALL (q: position | positionsOF(s)(q) AND 
                                      positionsOF(t)(q)):
                   left_without_children(q, p) =>
                        subtermOF(s, q) = subtermOF(t, q))
             AND
               (FORALL (p1: position | positionsOF(s)(p1) AND
                                       positionsOF(t)(p1)):
                   child(p, p1) => 
                        f(subtermOF(s, p1)) = f(subtermOF(t, p1)))  )
            IMPLIES
               (FORALL (q: position | positionsOF(ext(sig)(s))(q) AND
                                      positionsOF(ext(sig)(t))(q)):
                   left_without_children(q, 
                           next_position(ext(sig)(s), ext(sig)(t), p o fd)) =>
                     subtermOF(ext(sig)(s), q) = subtermOF(ext(sig)(t), q))


  %%%% Function to compute mgu's of unifiable terms %%%%%%%%%%%%%%%%%%%%%

   robinson_unification_algorithm_aux(s, t : term, p : position | 
      positionsOF(s)(p) AND  positionsOF(t)(p)) : RECURSIVE Sub = 
   IF subtermOF(s,p) = subtermOF(t,p) THEN 
     LET pi = next_position(s, t, p) IN
        IF pi = empty_seq THEN identity
        ELSE robinson_unification_algorithm_aux(s,t,pi)
        ENDIF
   ELSE
       LET sig = link_of_frst_diff(subtermOF(s,p),subtermOF(t,p)) 
       IN
          IF sig = fail THEN fail
          ELSE 
            LET pi = next_position(ext(sig)(s), ext(sig)(t), 
                           p o first_diff(subtermOF(s,p),subtermOF(t,p)))
            IN
              IF pi = empty_seq THEN  sig
              ELSE LET sigma = robinson_unification_algorithm_aux(
                                          ext(sig)(s), ext(sig)(t), pi) IN
                     IF sigma = fail THEN fail ELSE comp(sigma, sig) ENDIF
              ENDIF  
          ENDIF
   ENDIF 
    MEASURE  lex2(Card(union(Vars(s), Vars(t))),
                  Card(right_pos(s,p)))


   robinson_unification_algorithm_EF(s, t : term) : Sub =
     robinson_unification_algorithm_aux(s, t , empty_seq)


  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  unifiable_implies_not_fail1 : LEMMA
     FORALL (s : term, t : term,
              p: position | positionsOF(s)(p) AND 
                            positionsOF(t)(p) AND 
                            subtermOF(s, p) /= subtermOF(t, p)):
        LET sig = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p)) IN
              unifiable(s, t) IMPLIES
              NOT sig = fail

  preserving_generality1 : LEMMA
     FORALL (s : term, t : term,
              p: position | positionsOF(s)(p) AND 
                            positionsOF(t)(p) AND 
                            subtermOF(s, p) /= subtermOF(t, p)):
         member(rho, U(s, t)) IMPLIES
             LET sig = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p)) IN
                EXISTS theta : rho = comp(theta, sig)


   unifiable_preserves_unifiability1 : LEMMA
      FORALL (s : term, t : term,
              p: position | positionsOF(s)(p) AND 
                            positionsOF(t)(p) AND 
                            subtermOF(s, p) /= subtermOF(t, p)):
        LET sig = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p)) IN
            unifiable(s, t) IMPLIES unifiable(ext(sig)(s), (ext(sig)(t)))


   dom_ruaEF_subset_union_vars_aux : LEMMA
      FORALL (s : term, t : term,
              p: position | positionsOF(s)(p) AND positionsOF(t)(p)) :
      unifiable(s, t) IMPLIES 
         LET sigma = robinson_unification_algorithm_aux(s, t, p) IN
            subset?( Dom(sigma), union(Vars(s), Vars(t)) )


   dom_ruaEF_subset_union_vars : LEMMA
      unifiable(s, t) IMPLIES 
         LET sigma = robinson_unification_algorithm_EF(s, t) IN
            subset?( Dom(sigma), union(Vars(s), Vars(t)) )


   vran_ruaEF_subset_union_aux : LEMMA
      FORALL (s : term, t : term,
              p: position | positionsOF(s)(p) AND 
                            positionsOF(t)(p) AND 
                            subtermOF(s, p) /= subtermOF(t, p)) :
    LET pi = first_diff(subtermOF(s, p), subtermOF(t, p)) IN
     LET sig1 = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p)) IN
      LET np = next_position(ext(sig1)(s), ext(sig1)(t), p o pi) IN
       LET sig2 = robinson_unification_algorithm_aux(ext(sig1)(s), ext(sig1)(t), np) IN
          unifiable(s, t) IMPLIES
            subset?(VRan(comp(sig2, sig1)), 
                    union(VRan(sig2), difference(VRan(sig1), Dom(sig2))))


   dom_ran_ruaEF_disjoint : LEMMA
     FORALL (s : term, t : term,
              p: position | positionsOF(s)(p) AND positionsOF(t)(p)) :
      unifiable(s, t) IMPLIES 
         LET sigma = robinson_unification_algorithm_aux(s, t, p) IN
             subset?( VRan(sigma) , 
                       difference( union(Vars(s), Vars(t)), Dom(sigma) ))


   ruaEF_fails_iff_non_unifiable_aux : LEMMA
     FORALL (s : term,
     	   t : term,
             p : position | positionsOF(s)(p) AND 
  	       		  positionsOF(t)(p) ):
        ( FORALL (q : position | positionsOF(s)(q) AND
                                 positionsOF(t)(q) ): 
           left_without_children(q, p) => subtermOF(s,q) = subtermOF(t, q) ) 
       AND
        ( FORALL (p1 : position | positionsOF(s)(p1) AND
                                  positionsOF(t)(p1) ):
             child(p, p1) => f(subtermOF(s, p1)) = f(subtermOF(t, p1)) )
       IMPLIES     
        ( NOT unifiable(s,t) IFF 
          robinson_unification_algorithm_aux(s, t, p) = fail)


   ruaEF_gives_unifier_aux : LEMMA
     FORALL (s : term,
     	   t : term,
             p : position | positionsOF(s)(p) AND 
  	       		  positionsOF(t)(p) ):
        ( FORALL (q : position | positionsOF(s)(q) AND
                                 positionsOF(t)(q) ): 
           left_without_children(q, p) => subtermOF(s,q) = subtermOF(t, q) ) 
       AND
        ( FORALL (p1 : position | positionsOF(s)(p1) AND
                                  positionsOF(t)(p1) ):
             child(p, p1) => f(subtermOF(s, p1)) = f(subtermOF(t, p1)) )
       IMPLIES     
        ( unifiable(s,t) IFF
            member(robinson_unification_algorithm_aux(s, t, p), U(s, t)) )


   ruaEF_gives_mg_subs_aux : LEMMA
     FORALL (s : term,
     	   t : term,
             p : position | positionsOF(s)(p) AND 
  	       		  positionsOF(t)(p) ):
        ( FORALL (q : position | positionsOF(s)(q) AND
                                 positionsOF(t)(q) ): 
           left_without_children(q, p) => subtermOF(s,q) = subtermOF(t, q) ) 
       AND
        ( FORALL (p1 : position | positionsOF(s)(p1) AND
                                  positionsOF(t)(p1) ):
             child(p, p1) => f(subtermOF(s, p1)) = f(subtermOF(t, p1)) )
       IMPLIES     
        ( member(rho, U(s, t)) IMPLIES
            robinson_unification_algorithm_aux(s, t, p) <= rho )


   ruaEF_fails_iff_non_unifiable : LEMMA
      NOT unifiable(s,t) IFF robinson_unification_algorithm_EF(s,t) = fail

  %%%% Soundness of "robinson_unification_algorithm_EF" %%%%%%%%%%%%%%%%%%%%

   ruaEF_gives_unifier : LEMMA
      unifiable(s,t) IFF member(robinson_unification_algorithm_EF(s, t), U(s, t))
   
   ruaEF_gives_mg_subs : LEMMA
      member(rho, U(s, t)) IMPLIES robinson_unification_algorithm_EF(s, t) <= rho
   
  %%%% Completeness of "robinson_unification_algorithm_EF" %%%%%%%%%%%%%%%%%

   completeness_ruaEF : LEMMA
     IF unifiable(s,t) THEN  mgu(robinson_unification_algorithm_EF(s,t))(s,t)
                       ELSE  robinson_unification_algorithm_EF(s,t) = fail 
     ENDIF
   

  END robinsonunificationEF

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 32, column 13) for
      % robinsonunification[variable, symbol, arity]
      % generated from assumption robinsonunification.var_countable
  IMP_robinsonunification_TCC1: OBLIGATION
    is_countably_infinite[term[variable, symbol, arity]]
        (V[variable, symbol, arity]);

  % Assuming TCC generated (at line 32, column 13) for
      % robinsonunification[variable, symbol, arity]
      % generated from assumption robinsonunification.var_nonempty
  IMP_robinsonunification_TCC2: OBLIGATION
    nonempty?[term[variable, symbol, arity]](V[variable, symbol, arity]);

  % Assuming TCC generated (at line 32, column 13) for
      % robinsonunification[variable, symbol, arity]
      % generated from assumption robinsonunification.symbol_nonempty
  IMP_robinsonunification_TCC3: OBLIGATION
    nonempty?[symbol]({f: symbol | arity(f) = 1});

  % Subtype TCC generated (at line 57, column 23) for  p
      % expected type  not_empty_seq[posnat]
  right_pos_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            p: position[variable, symbol, arity]):
      NOT p = empty_seq AND positionsOF(s)(p) IMPLIES
       (FORALL (p1: position[variable, symbol, arity]):
          p1 = delete(p, length(p) - 1) IMPLIES length(p) /= 0);

  % Subtype TCC generated (at line 58, column 40) for  p1
      % expected type  positions?[variable, symbol, arity](s)
  right_pos_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            p: position[variable, symbol, arity]):
      NOT p = empty_seq AND positionsOF(s)(p) IMPLIES
       (FORALL (p1: position[variable, symbol, arity]):
          p1 = delete(p, length(p) - 1) IMPLIES
           (FORALL (i: nat):
              i = last(p) IMPLIES
               positionsOF[variable, symbol, arity](s)(p1)));

  % Subtype TCC generated (at line 58, column 28) for  subtermOF(s, p1)
      % expected type  (app?)
  right_pos_TCC3: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            p: position[variable, symbol, arity]):
      NOT p = empty_seq AND positionsOF(s)(p) IMPLIES
       (FORALL (p1: position[variable, symbol, arity]):
          p1 = delete(p, length(p) - 1) IMPLIES
           (FORALL (i: nat):
              i = last(p) IMPLIES
               app?[variable, symbol, arity]
                   (subtermOF[variable, symbol, arity](s, p1))));

  % Termination TCC generated (at line 59, column 36) for  right_pos(s, p1)
  right_pos_TCC4: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            p: position[variable, symbol, arity]):
      NOT p = empty_seq AND positionsOF(s)(p) IMPLIES
       (FORALL (p1: position[variable, symbol, arity]):
          p1 = delete(p, length(p) - 1) IMPLIES
           (FORALL (i: nat):
              i = last(p) IMPLIES
               (FORALL (n: nat):
                  n = arity(f(subtermOF(s, p1))) IMPLIES
                   length(p1) < length(p))));

  % Subtype TCC generated (at line 62, column 41) for  add_last(p1, i + j + 1)
      % expected type  positions?[variable, symbol, arity](s)
  right_pos_TCC5: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            p: position[variable, symbol, arity]):
      NOT p = empty_seq AND positionsOF(s)(p) IMPLIES
       (FORALL (p1: position[variable, symbol, arity]):
          p1 = delete(p, length(p) - 1) IMPLIES
           (FORALL (i: nat):
              i = last(p) IMPLIES
               (FORALL (n: nat):
                  n = arity(f(subtermOF(s, p1))) IMPLIES
                   (FORALL (j: below(n - i)):
                      positionsOF[variable, symbol, arity]
                          (s)(add_last[posnat](p1, i + j + 1))))));

  % Subtype TCC generated (at line 56, column 22) for  length(p) - 1
      % expected type  below[length(p)]
  right_pos_TCC6: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            p: position[variable, symbol, arity]):
      NOT p = empty_seq AND positionsOF(s)(p) IMPLIES
       length(p) - 1 >= 0 AND length(p) - 1 < length(p);

  % Subtype TCC generated (at line 95, column 44) for  length(p) - 1
      % expected type  below[length(p)]
  next_position_TCC1: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       length(p) - 1 >= 0 AND length(p) - 1 < length(p);

  % Subtype TCC generated (at line 95, column 35) for
      % delete(p, length(p) - 1)
      % expected type  positions?[variable, symbol, arity](s)
  next_position_TCC2: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       positionsOF[variable, symbol, arity]
           (s)(delete[posnat](p, length(p) - 1));

  % Subtype TCC generated (at line 94, column 28) for
      % subtermOF(s, delete(p, length(p) - 1))
      % expected type  (app?)
  next_position_TCC3: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       app?[variable, symbol, arity]
           (subtermOF[variable, symbol, arity]
                (s, delete[posnat](p, length(p) - 1)));

  % Subtype TCC generated (at line 95, column 69) for  p
      % expected type  not_empty_seq[posnat]
  next_position_TCC4: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES length(p) /= 0;

  % Subtype TCC generated (at line 94, column 20) for
      % arity(f(subtermOF(s, delete(p, length(p) - 1)))) - last(p)
      % expected type  nat
  next_position_TCC5: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       arity(f[variable, symbol, arity]
                 (subtermOF[variable, symbol, arity]
                      (s, delete[posnat](p, length(p) - 1))))
        - last[posnat](p)
        >= 0;

  % Subtype TCC generated (at line 95, column 44) for  length(z`3) - 1
      % expected type  below[length(z`3)]
  next_position_TCC6: OBLIGATION
    FORALL (z:
              [s: term, t: term,
               {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}]):
      NOT z`3 = empty_seq IMPLIES
       length(z`3) - 1 >= 0 AND length(z`3) - 1 < length(z`3);

  % Subtype TCC generated (at line 95, column 35) for
      % delete(z`3, length(z`3) - 1)
      % expected type  positions?[variable, symbol, arity](z`1)
  next_position_TCC7: OBLIGATION
    FORALL (z:
              [s: term, t: term,
               {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}]):
      NOT z`3 = empty_seq IMPLIES
       positionsOF[variable, symbol, arity]
           (z`1)(delete[posnat](z`3, length(z`3) - 1));

  % Subtype TCC generated (at line 94, column 28) for
      % subtermOF(z`1, delete(z`3, length(z`3) - 1))
      % expected type  (app?)
  next_position_TCC8: OBLIGATION
    FORALL (z:
              [s: term, t: term,
               {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}]):
      NOT z`3 = empty_seq IMPLIES
       app?[variable, symbol, arity]
           (subtermOF[variable, symbol, arity]
                (z`1, delete[posnat](z`3, length(z`3) - 1)));

  % Subtype TCC generated for  z`3
      % expected type  not_empty_seq[posnat]
  next_position_TCC9: OBLIGATION
    FORALL (z:
              [s: term, t: term,
               {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}]):
      NOT z`3 = empty_seq IMPLIES length(z`3) /= 0;

  % Subtype TCC generated (at line 94, column 20) for
      % arity(f(subtermOF(z`1, delete(z`3, length(z`3) - 1)))) - last(z`3)
      % expected type  nat
  next_position_TCC10: OBLIGATION
    FORALL (z:
              [s: term, t: term,
               {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}]):
      NOT z`3 = empty_seq IMPLIES
       arity(f[variable, symbol, arity]
                 (subtermOF[variable, symbol, arity]
                      (z`1, delete[posnat](z`3, length(z`3) - 1))))
        - last[posnat](z`3)
        >= 0;

  % Subtype TCC generated (at line 78, column 23) for  pi0
      % expected type  positions?[variable, symbol, arity](s)
  next_position_TCC11: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       (FORALL (pi0: finseq[posnat]):
          pi0 = delete(p, length(p) - 1) IMPLIES
           positionsOF[variable, symbol, arity](s)(pi0));

  % Subtype TCC generated (at line 78, column 11) for  subtermOF(s, pi0)
      % expected type  (app?)
  next_position_TCC12: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       (FORALL (pi0: finseq[posnat]):
          pi0 = delete(p, length(p) - 1) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity](s, pi0)));

  % Subtype TCC generated (at line 78, column 46) for  pi0
      % expected type  positions?[variable, symbol, arity](t)
  next_position_TCC13: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       (FORALL (pi0: finseq[posnat]):
          pi0 = delete(p, length(p) - 1) IMPLIES
           positionsOF[variable, symbol, arity](t)(pi0));

  % Subtype TCC generated (at line 78, column 34) for  subtermOF(t, pi0)
      % expected type  (app?)
  next_position_TCC14: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       (FORALL (pi0: finseq[posnat]):
          pi0 = delete(p, length(p) - 1) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity](t, pi0)));

  % Subtype TCC generated (at line 82, column 48) for  pi
      % expected type  positions?[variable, symbol, arity](t)
  next_position_TCC15: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       (FORALL (pi0: finseq[posnat]):
          NOT f(subtermOF(s, pi0)) /= f(subtermOF(t, pi0)) AND
           pi0 = delete(p, length(p) - 1)
           IMPLIES
           (FORALL (pi: finseq[posnat]):
              positionsOF(s)(pi) AND
               pi = add_last(delete(p, length(p) - 1), last(p) + 1)
               IMPLIES positionsOF[variable, symbol, arity](t)(pi)));

  % Subtype TCC generated (at line 83, column 36) for  pi
      % expected type  {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}
  next_position_TCC16: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       (FORALL (pi0: finseq[posnat]):
          NOT f(subtermOF(s, pi0)) /= f(subtermOF(t, pi0)) AND
           pi0 = delete(p, length(p) - 1)
           IMPLIES
           (FORALL (pi: finseq[posnat]):
              NOT subtermOF(s, pi) /= subtermOF(t, pi) AND
               positionsOF(s)(pi) AND
                pi = add_last(delete(p, length(p) - 1), last(p) + 1)
               IMPLIES
               positionsOF[variable, symbol, arity](s)(pi) AND
                positionsOF[variable, symbol, arity](t)(pi)));

  % Termination TCC generated (at line 83, column 17) for
      % next_position(s, t, pi)
  next_position_TCC17: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       (FORALL (pi0: finseq[posnat]):
          NOT f(subtermOF(s, pi0)) /= f(subtermOF(t, pi0)) AND
           pi0 = delete(p, length(p) - 1)
           IMPLIES
           (FORALL (pi: finseq[posnat]):
              NOT subtermOF(s, pi) /= subtermOF(t, pi) AND
               positionsOF(s)(pi) AND
                pi = add_last(delete(p, length(p) - 1), last(p) + 1)
               IMPLIES
               IF pi = empty_seq[posnat] THEN lex2(0, 0)
               ELSE lex2(length(pi),
                         arity(f[variable, symbol, arity]
                                   (subtermOF[variable, symbol, arity]
                                        (s,
                                         delete[posnat]
                                         (pi, length(pi) - 1))))
                          - last[posnat](pi))
               ENDIF
                <
                IF p = empty_seq[posnat] THEN lex2(0, 0)
                ELSE lex2(length(p),
                          arity(f[variable, symbol, arity]
                                    (subtermOF[variable, symbol, arity]
                                         (s,
                                          delete[posnat](p, length(p) - 1))))
                           - last[posnat](p))
                ENDIF));

  % Subtype TCC generated (at line 85, column 40) for  pi0
      % expected type  {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}
  next_position_TCC18: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       (FORALL (pi0: finseq[posnat]):
          NOT f(subtermOF(s, pi0)) /= f(subtermOF(t, pi0)) AND
           pi0 = delete(p, length(p) - 1)
           IMPLIES
           (FORALL (pi: finseq[posnat]):
              pi0 /= empty_seq AND
               NOT positionsOF(s)(pi) AND
                pi = add_last(delete(p, length(p) - 1), last(p) + 1)
               IMPLIES
               positionsOF[variable, symbol, arity](s)(pi0) AND
                positionsOF[variable, symbol, arity](t)(pi0)));

  % Termination TCC generated (at line 85, column 20) for
      % next_position(s, t, pi0)
  next_position_TCC19: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT p = empty_seq IMPLIES
       (FORALL (pi0: finseq[posnat]):
          NOT f(subtermOF(s, pi0)) /= f(subtermOF(t, pi0)) AND
           pi0 = delete(p, length(p) - 1)
           IMPLIES
           (FORALL (pi: finseq[posnat]):
              pi0 /= empty_seq AND
               NOT positionsOF(s)(pi) AND
                pi = add_last(delete(p, length(p) - 1), last(p) + 1)
               IMPLIES
               IF pi0 = empty_seq[posnat] THEN lex2(0, 0)
               ELSE lex2(length(pi0),
                         arity(f[variable, symbol, arity]
                                   (subtermOF[variable, symbol, arity]
                                        (s,
                                         delete[posnat]
                                         (pi0, length(pi0) - 1))))
                          - last[posnat](pi0))
               ENDIF
                <
                IF p = empty_seq[posnat] THEN lex2(0, 0)
                ELSE lex2(length(p),
                          arity(f[variable, symbol, arity]
                                    (subtermOF[variable, symbol, arity]
                                         (s,
                                          delete[posnat](p, length(p) - 1))))
                           - last[posnat](p))
                ENDIF));

  % Subtype TCC generated (at line 120, column 12) for  p
      % expected type  not_empty_seq[posnat]
  next_pos_length_and_last_TCC1: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    p /= empty_seq[posnat]):
      length(next_position(s, t, p)) = length(p) AND
       NOT length(next_position(s, t, p)) < length(p)
       IMPLIES length(p) /= 0;

  % Subtype TCC generated (at line 120, column 22) for  next_position(s, t, p)
      % expected type  not_empty_seq[posnat]
  next_pos_length_and_last_TCC2: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    p /= empty_seq[posnat]):
      length(next_position(s, t, p)) = length(p) AND
       NOT length(next_position(s, t, p)) < length(p)
       IMPLIES length(next_position(s, t, p)) /= 0;

  % Subtype TCC generated (at line 153, column 11) for
      % right_pos(s, next_position(s, t, p))
      % expected type  finite_set[position[variable, symbol, arity]]
  next_pos_to_the_right_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    p /= empty_seq[posnat]):
      is_finite[position[variable, symbol, arity]]
          (right_pos(s, next_position(s, t, p)));

  % Subtype TCC generated (at line 154, column 13) for  right_pos(s, p)
      % expected type  finite_set[position[variable, symbol, arity]]
  next_pos_to_the_right_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    p /= empty_seq[posnat]):
      is_finite[position[variable, symbol, arity]](right_pos(s, p));

  % Subtype TCC generated (at line 159, column 52) for  subtermOF(t, p)
      % expected type  {t_1: term[variable, symbol, arity] |
                     %          subtermOF(s, p) /= t_1}
  ext_link_remove_x_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    subtermOF[variable, symbol, arity](s, p) /=
                     subtermOF[variable, symbol, arity](t, p)):
      subtermOF[variable, symbol, arity](s, p) /=
       subtermOF[variable, symbol, arity](t, p);

  % Subtype TCC generated (at line 193, column 18) for
      % union(Vars(ext(sig)(s)), Vars(ext(sig)(t)))
      % expected type  finite_set[(V)]
  termination_lemma_subterm_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    subtermOF[variable, symbol, arity](s, p) /=
                     subtermOF[variable, symbol, arity](t, p),
            sig: Sub[variable, symbol, arity]):
      NOT sig = fail AND
       sig = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p))
       IMPLIES
       is_finite[(V)]
           (union[(V)]
                (Vars[variable, symbol, arity]
                     (ext[variable, symbol, arity](sig)(s)),
                 Vars[variable, symbol, arity]
                     (ext[variable, symbol, arity](sig)(t))));

  % Subtype TCC generated (at line 194, column 20) for
      % union(Vars(s), Vars(t))
      % expected type  finite_set[(V)]
  termination_lemma_subterm_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    subtermOF[variable, symbol, arity](s, p) /=
                     subtermOF[variable, symbol, arity](t, p),
            sig: Sub[variable, symbol, arity]):
      NOT sig = fail AND
       sig = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p))
       IMPLIES
       is_finite[(V)]
           (union[(V)]
                (Vars[variable, symbol, arity](s),
                 Vars[variable, symbol, arity](t)));

  % Subtype TCC generated (at line 205, column 21) for  q
      % expected type  positions?[variable, symbol, arity](s)
  subtermOF_next_position_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | s /= t,
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p),
            q: position[variable, symbol, arity]):
      q = next_position(s, t, p) IMPLIES
       positionsOF[variable, symbol, arity](s)(q);

  % Subtype TCC generated (at line 205, column 40) for  q
      % expected type  positions?[variable, symbol, arity](t)
  subtermOF_next_position_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | s /= t,
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p),
            q: position[variable, symbol, arity]):
      q = next_position(s, t, p) IMPLIES
       positionsOF[variable, symbol, arity](t)(q);

  % Subtype TCC generated (at line 213, column 42) for  subtermOF(t, q)
      % expected type  {t: term[variable, symbol, arity] |
                     %          subtermOF(s, q) /= t}
  np_o_fd_is_position_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity] | s /= t,
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p),
            q: position[variable, symbol, arity]):
      q = next_position(s, t, p) IMPLIES
       subtermOF[variable, symbol, arity](s, q) /=
        subtermOF[variable, symbol, arity](t, q);

  % Subtype TCC generated (at line 236, column 27) for  subtermOF(s, p1)
      % expected type  (app?)
  next_pos_empty_equal_subterm_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    p /= empty_seq[posnat]):
      next_position(s, t, p) = empty_seq IMPLIES
       (FORALL (p1: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity](s)(p1) AND
                       positionsOF[variable, symbol, arity](t)(p1)):
          child(p, p1) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity](s, p1)));

  % Subtype TCC generated (at line 236, column 49) for  subtermOF(t, p1)
      % expected type  (app?)
  next_pos_empty_equal_subterm_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    p /= empty_seq[posnat]):
      next_position(s, t, p) = empty_seq IMPLIES
       (FORALL (p1: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity](s)(p1) AND
                       positionsOF[variable, symbol, arity](t)(p1)):
          child(p, p1) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity](t, p1)));

  % Subtype TCC generated (at line 252, column 17) for  subtermOF(s, p1)
      % expected type  (app?)
  next_pos_equal_subterm_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    p /= empty_seq[posnat],
            p1: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p1) AND
                   positionsOF[variable, symbol, arity](t)(p1)):
      child(p, p1) IMPLIES
       app?[variable, symbol, arity]
           (subtermOF[variable, symbol, arity](s, p1));

  % Subtype TCC generated (at line 252, column 39) for  subtermOF(t, p1)
      % expected type  (app?)
  next_pos_equal_subterm_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    p /= empty_seq[posnat],
            p1: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p1) AND
                   positionsOF[variable, symbol, arity](t)(p1)):
      child(p, p1) IMPLIES
       app?[variable, symbol, arity]
           (subtermOF[variable, symbol, arity](t, p1));

  % Subtype TCC generated (at line 287, column 22) for  subtermOF(s, q)
      % expected type  (app?)
  child_p_o_fd_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    subtermOF[variable, symbol, arity](s, p) /=
                     subtermOF[variable, symbol, arity](t, p),
            fd: position[variable, symbol, arity]):
      fd = first_diff(subtermOF(s, p), subtermOF(t, p)) IMPLIES
       (FORALL (q: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity](s)(q) AND
                       positionsOF[variable, symbol, arity](t)(q)):
          child(p, q) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity](s, q)));

  % Subtype TCC generated (at line 287, column 43) for  subtermOF(t, q)
      % expected type  (app?)
  child_p_o_fd_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    subtermOF[variable, symbol, arity](s, p) /=
                     subtermOF[variable, symbol, arity](t, p),
            fd: position[variable, symbol, arity]):
      fd = first_diff(subtermOF(s, p), subtermOF(t, p)) IMPLIES
       (FORALL (q: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity](s)(q) AND
                       positionsOF[variable, symbol, arity](t)(q)):
          child(p, q) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity](t, q)));

  % Subtype TCC generated (at line 291, column 30) for
      % subtermOF(ext(sig)(s), q)
      % expected type  (app?)
  child_p_o_fd_TCC3: OBLIGATION
    FORALL (sig: Sub[variable, symbol, arity],
            s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    subtermOF[variable, symbol, arity](s, p) /=
                     subtermOF[variable, symbol, arity](t, p),
            fd: position[variable, symbol, arity]):
      (FORALL (q: position[variable, symbol, arity]
                   | positionsOF(s)(q) AND positionsOF(t)(q)):
         child(p, q) => f(subtermOF(s, q)) = f(subtermOF(t, q)))
       AND fd = first_diff(subtermOF(s, p), subtermOF(t, p))
       IMPLIES
       (FORALL (q1: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity]
                          (ext[variable, symbol, arity](sig)(s))(q)
                       AND
                       positionsOF[variable, symbol, arity]
                           (ext[variable, symbol, arity](sig)(t))(q)):
          child(p o fd, q1) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity]
                    (ext[variable, symbol, arity](sig)(s), q1)));

  % Subtype TCC generated (at line 291, column 61) for
      % subtermOF(ext(sig)(t), q)
      % expected type  (app?)
  child_p_o_fd_TCC4: OBLIGATION
    FORALL (sig: Sub[variable, symbol, arity],
            s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    subtermOF[variable, symbol, arity](s, p) /=
                     subtermOF[variable, symbol, arity](t, p),
            fd: position[variable, symbol, arity]):
      (FORALL (q: position[variable, symbol, arity]
                   | positionsOF(s)(q) AND positionsOF(t)(q)):
         child(p, q) => f(subtermOF(s, q)) = f(subtermOF(t, q)))
       AND fd = first_diff(subtermOF(s, p), subtermOF(t, p))
       IMPLIES
       (FORALL (q1: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity]
                          (ext[variable, symbol, arity](sig)(s))(q)
                       AND
                       positionsOF[variable, symbol, arity]
                           (ext[variable, symbol, arity](sig)(t))(q)):
          child(p o fd, q1) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity]
                    (ext[variable, symbol, arity](sig)(t), q1)));

  % Subtype TCC generated (at line 333, column 53) for  p o fd
      % expected type  {p: position |
                     %          positionsOF(ext(sig)(s))(p) AND
                     %           positionsOF(ext(sig)(t))(p)}
  np_p_o_fd_empty_unifiable_term_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    subtermOF[variable, symbol, arity](s, p) /=
                     subtermOF[variable, symbol, arity](t, p),
            fd: position[variable, symbol, arity]):
      fd = first_diff(subtermOF(s, p), subtermOF(t, p)) IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          NOT sig = fail AND
           sig = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p))
           IMPLIES
           positionsOF[variable, symbol, arity]
               (ext[variable, symbol, arity](sig)(s))(o[posnat](p, fd))
            AND
            positionsOF[variable, symbol, arity]
                (ext[variable, symbol, arity](sig)(t))(o[posnat](p, fd)));

  % Subtype TCC generated (at line 400, column 21) for
      % union(Vars(s), Vars(t))
      % expected type  finite_set[(V)]
  robinson_unification_algorithm_aux_TCC1: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      is_finite[(V)]
          (union[(V)]
               (Vars[variable, symbol, arity](s),
                Vars[variable, symbol, arity](t)));

  % Subtype TCC generated (at line 401, column 21) for  right_pos(s, p)
      % expected type  finite_set[position[variable, symbol, arity]]
  robinson_unification_algorithm_aux_TCC2: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      is_finite[position[variable, symbol, arity]](right_pos(s, p));

  % Subtype TCC generated (at line 400, column 21) for
      % union(Vars(z`1), Vars(z`2))
      % expected type  finite_set[(V)]
  robinson_unification_algorithm_aux_TCC3: OBLIGATION
    FORALL (z:
              [s: term, t: term,
               {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}]):
      is_finite[(V)]
          (union[(V)]
               (Vars[variable, symbol, arity](z`1),
                Vars[variable, symbol, arity](z`2)));

  % Subtype TCC generated (at line 401, column 21) for  right_pos(z`1, z`3)
      % expected type  finite_set[position[variable, symbol, arity]]
  robinson_unification_algorithm_aux_TCC4: OBLIGATION
    FORALL (z:
              [s: term, t: term,
               {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}]):
      is_finite[position[variable, symbol, arity]](right_pos(z`1, z`3));

  % Subtype TCC generated (at line 400, column 21) for
      % union(Vars(s), Vars(t))
      % expected type  finite_set[(V)]
  robinson_unification_algorithm_aux_TCC5: OBLIGATION
    FORALL (s, t: term):
      is_finite[(V)]
          (union[(V)]
               (Vars[variable, symbol, arity](s),
                Vars[variable, symbol, arity](t)));

  % Subtype TCC generated (at line 382, column 29) for  identity
      % expected type  Sub[variable, symbol, arity]
  robinson_unification_algorithm_aux_TCC6: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      subtermOF(s, p) = subtermOF(t, p) IMPLIES
       (FORALL (pi: position[variable, symbol, arity]):
          pi = empty_seq AND pi = next_position(s, t, p) IMPLIES
           Sub?[variable, symbol, arity](identity[(V)]));

  % Subtype TCC generated (at line 383, column 50) for  pi
      % expected type  {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}
  robinson_unification_algorithm_aux_TCC7: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      subtermOF(s, p) = subtermOF(t, p) IMPLIES
       (FORALL (pi: position[variable, symbol, arity]):
          NOT pi = empty_seq AND pi = next_position(s, t, p) IMPLIES
           positionsOF[variable, symbol, arity](s)(pi) AND
            positionsOF[variable, symbol, arity](t)(pi));

  % Termination TCC generated (at line 383, column 11) for
      % robinson_unification_algorithm_aux(s, t, pi)
  robinson_unification_algorithm_aux_TCC8: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      subtermOF(s, p) = subtermOF(t, p) IMPLIES
       (FORALL (pi: position[variable, symbol, arity]):
          NOT pi = empty_seq AND pi = next_position(s, t, p) IMPLIES
           lex2(Card[(V)]
                    (union[(V)]
                         (Vars[variable, symbol, arity](s),
                          Vars[variable, symbol, arity](t))),
                Card[position[variable, symbol, arity]](right_pos(s, pi)))
            <
            lex2(Card[(V)]
                     (union[(V)]
                          (Vars[variable, symbol, arity](s),
                           Vars[variable, symbol, arity](t))),
                 Card[position[variable, symbol, arity]](right_pos(s, p))));

  % Subtype TCC generated (at line 391, column 55) for  subtermOF(t, p)
      % expected type  {t_1: term[variable, symbol, arity] |
                     %          subtermOF(s, p) /= t_1}
  robinson_unification_algorithm_aux_TCC9: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT subtermOF(s, p) = subtermOF(t, p) IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          NOT sig = fail AND
           sig = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p))
           IMPLIES
           subtermOF[variable, symbol, arity](s, p) /=
            subtermOF[variable, symbol, arity](t, p));

  % Subtype TCC generated (at line 391, column 25) for
      % p o first_diff(subtermOF(s, p), subtermOF(t, p))
      % expected type  {p: position |
                     %          positionsOF(ext(sig)(s))(p) AND
                     %           positionsOF(ext(sig)(t))(p)}
  robinson_unification_algorithm_aux_TCC10: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT subtermOF(s, p) = subtermOF(t, p) IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          NOT sig = fail AND
           sig = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p))
           IMPLIES
           positionsOF[variable, symbol, arity]
               (ext[variable, symbol, arity](sig)(s))
               (o[posnat]
                    (p,
                     first_diff[variable, symbol, arity]
                         (subtermOF[variable, symbol, arity](s, p),
                          subtermOF[variable, symbol, arity](t, p))))
            AND
            positionsOF[variable, symbol, arity]
                (ext[variable, symbol, arity](sig)(t))
                (o[posnat]
                     (p,
                      first_diff[variable, symbol, arity]
                          (subtermOF[variable, symbol, arity](s, p),
                           subtermOF[variable, symbol, arity](t, p)))));

  % Subtype TCC generated (at line 395, column 66) for  pi
      % expected type  {p: position |
                     %          positionsOF(ext(sig)(s))(p) AND
                     %           positionsOF(ext(sig)(t))(p)}
  robinson_unification_algorithm_aux_TCC11: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT subtermOF(s, p) = subtermOF(t, p) IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          NOT sig = fail AND
           sig = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p))
           IMPLIES
           (FORALL (pi: position[variable, symbol, arity]):
              NOT pi = empty_seq AND
               pi =
                next_position(ext(sig)(s), ext(sig)(t),
                              p o
                               first_diff(subtermOF(s, p), subtermOF(t, p)))
               IMPLIES
               positionsOF[variable, symbol, arity]
                   (ext[variable, symbol, arity](sig)(s))(pi)
                AND
                positionsOF[variable, symbol, arity]
                    (ext[variable, symbol, arity](sig)(t))(pi)));

  % Termination TCC generated (at line 394, column 29) for
      % robinson_unification_algorithm_aux(ext(sig)(s), ext(sig)(t), pi)
  robinson_unification_algorithm_aux_TCC12: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT subtermOF(s, p) = subtermOF(t, p) IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          NOT sig = fail AND
           sig = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p))
           IMPLIES
           (FORALL (pi: position[variable, symbol, arity]):
              NOT pi = empty_seq AND
               pi =
                next_position(ext(sig)(s), ext(sig)(t),
                              p o
                               first_diff(subtermOF(s, p), subtermOF(t, p)))
               IMPLIES
               lex2(Card[(V)]
                        (union[(V)]
                             (Vars[variable, symbol, arity]
                                  (ext[variable, symbol, arity](sig)(s)),
                              Vars[variable, symbol, arity]
                                  (ext[variable, symbol, arity](sig)(t)))),
                    Card[position[variable, symbol, arity]]
                        (right_pos(ext[variable, symbol, arity](sig)(s),
                                   pi)))
                <
                lex2(Card[(V)]
                         (union[(V)]
                              (Vars[variable, symbol, arity](s),
                               Vars[variable, symbol, arity](t))),
                     Card[position[variable, symbol, arity]]
                         (right_pos(s, p)))));

  % Subtype TCC generated (at line 396, column 50) for  comp(sigma, sig)
      % expected type  Sub[variable, symbol, arity]
  robinson_unification_algorithm_aux_TCC13: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p),
            v:
              [{z:
                  [s: term, t: term,
                   {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}] |
                        lex2(Card(union(Vars(z`1), Vars(z`2))),
                             Card(right_pos(z`1, z`3)))
                         <
                         lex2(Card(union(Vars(s), Vars(t))),
                              Card(right_pos(s, p)))} ->
                 Sub[variable, symbol, arity]]):
      NOT subtermOF(s, p) = subtermOF(t, p) IMPLIES
       (FORALL (sig: Sub[variable, symbol, arity]):
          NOT sig = fail AND
           sig = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p))
           IMPLIES
           (FORALL (pi: position[variable, symbol, arity]):
              NOT pi = empty_seq AND
               pi =
                next_position(ext(sig)(s), ext(sig)(t),
                              p o
                               first_diff(subtermOF(s, p), subtermOF(t, p)))
               IMPLIES
               (FORALL (sigma: Sub[variable, symbol, arity]):
                  NOT sigma = fail AND
                   sigma = v(ext(sig)(s), ext(sig)(t), pi)
                   IMPLIES
                   Sub?[variable, symbol, arity]
                       (comp[variable, symbol, arity](sigma, sig)))));

  % Subtype TCC generated (at line 386, column 48) for  subtermOF(t, p)
      % expected type  {t_1: term[variable, symbol, arity] |
                     %          subtermOF(s, p) /= t_1}
  robinson_unification_algorithm_aux_TCC14: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      NOT subtermOF(s, p) = subtermOF(t, p) IMPLIES
       subtermOF[variable, symbol, arity](s, p) /=
        subtermOF[variable, symbol, arity](t, p);

  % Subtype TCC generated (at line 405, column 45) for  empty_seq
      % expected type  {p: position | positionsOF(s)(p) AND positionsOF(t)(p)}
  robinson_unification_algorithm_EF_TCC1: OBLIGATION
    FORALL (s, t: term[variable, symbol, arity]):
      positionsOF[variable, symbol, arity](s)(empty_seq[posnat]) AND
       positionsOF[variable, symbol, arity](t)(empty_seq[posnat]);

  % Subtype TCC generated (at line 459, column 55) for  p o pi
      % expected type  {p: position |
                     %          positionsOF(ext(sig1)(s))(p) AND
                     %           positionsOF(ext(sig1)(t))(p)}
  vran_ruaEF_subset_union_aux_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    subtermOF[variable, symbol, arity](s, p) /=
                     subtermOF[variable, symbol, arity](t, p),
            pi: position[variable, symbol, arity]):
      pi = first_diff(subtermOF(s, p), subtermOF(t, p)) IMPLIES
       (FORALL (sig1: Sub[variable, symbol, arity]):
          sig1 = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p)) IMPLIES
           positionsOF[variable, symbol, arity]
               (ext[variable, symbol, arity](sig1)(s))(o[posnat](p, pi))
            AND
            positionsOF[variable, symbol, arity]
                (ext[variable, symbol, arity](sig1)(t))(o[posnat](p, pi)));

  % Subtype TCC generated (at line 460, column 79) for  np
      % expected type  {p: position |
                     %          positionsOF(ext(sig1)(s))(p) AND
                     %           positionsOF(ext(sig1)(t))(p)}
  vran_ruaEF_subset_union_aux_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p) AND
                    subtermOF[variable, symbol, arity](s, p) /=
                     subtermOF[variable, symbol, arity](t, p),
            pi: position[variable, symbol, arity]):
      pi = first_diff(subtermOF(s, p), subtermOF(t, p)) IMPLIES
       (FORALL (sig1: Sub[variable, symbol, arity]):
          sig1 = link_of_frst_diff(subtermOF(s, p), subtermOF(t, p)) IMPLIES
           (FORALL (np: position[variable, symbol, arity]):
              np = next_position(ext(sig1)(s), ext(sig1)(t), p o pi) IMPLIES
               positionsOF[variable, symbol, arity]
                   (ext[variable, symbol, arity](sig1)(s))(np)
                AND
                positionsOF[variable, symbol, arity]
                    (ext[variable, symbol, arity](sig1)(t))(np)));

  % Subtype TCC generated (at line 486, column 29) for  subtermOF(s, p1)
      % expected type  (app?)
  ruaEF_fails_iff_non_unifiable_aux_TCC1: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      (FORALL (q: position[variable, symbol, arity]
                   | positionsOF(s)(q) AND positionsOF(t)(q)):
         left_without_children(q, p) => subtermOF(s, q) = subtermOF(t, q))
       IMPLIES
       (FORALL (p1: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity](s)(p1) AND
                       positionsOF[variable, symbol, arity](t)(p1)):
          child(p, p1) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity](s, p1)));

  % Subtype TCC generated (at line 486, column 51) for  subtermOF(t, p1)
      % expected type  (app?)
  ruaEF_fails_iff_non_unifiable_aux_TCC2: OBLIGATION
    FORALL (s: term[variable, symbol, arity],
            t: term[variable, symbol, arity],
            p: position[variable, symbol, arity]
                | positionsOF[variable, symbol, arity](s)(p) AND
                   positionsOF[variable, symbol, arity](t)(p)):
      (FORALL (q: position[variable, symbol, arity]
                   | positionsOF(s)(q) AND positionsOF(t)(q)):
         left_without_children(q, p) => subtermOF(s, q) = subtermOF(t, q))
       IMPLIES
       (FORALL (p1: position[variable, symbol, arity]
                    | positionsOF[variable, symbol, arity](s)(p1) AND
                       positionsOF[variable, symbol, arity](t)(p1)):
          child(p, p1) IMPLIES
           app?[variable, symbol, arity]
               (subtermOF[variable, symbol, arity](t, p1)));


body:
  %%-------------------** Term Rewriting System (TRS) **------------------------
  %%                                                                          
  %% Authors         : Andre Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%
  %%                         and 
  %%
  %%                   Mauricio Ayala Rincon  
  %%                   Universidade de Brasília - Brasil  
  %%                   
  %% Last Modified On: October 15, 2008                                      

  %%                                                                          
  %%----------------------------------------------------------------------------


  trs[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY

    BEGIN

      ASSUMING
   
       IMPORTING variables_term[variable,symbol,arity],
                 sets_aux@countability[term],
                 sets_aux@countable_props[term]
   
         var_countable: ASSUMPTION is_countably_infinite(V)
        
     ENDASSUMING

    IMPORTING critical_pairs[variable,symbol, arity]

    END trs

addendum:
  %%% ================ Addendum: generated declarations ================

  % Assuming TCC generated (at line 31, column 12) for
      % critical_pairs[variable, symbol, arity]
      % generated from assumption critical_pairs.var_countable
  IMP_critical_pairs_TCC1: OBLIGATION
    is_countably_infinite[term[variable, symbol, arity]]
        (V[variable, symbol, arity]);


body:
  %%% ADT file generated from term

  term_adt[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat]]: THEORY
   BEGIN
    ASSUMING
     variable_TCC1: ASSUMPTION EXISTS (x: variable): TRUE;

     symbol_TCC1: ASSUMPTION EXISTS (x: symbol): TRUE;
    ENDASSUMING

    term: TYPE

    vars?, app?: [term -> boolean]

    v: [(vars?) -> variable]

    f: [(app?) -> symbol]

    args:
          [d: (app?) ->
             {args: finite_sequence[term] | args`length = arity(f(d))}]

    vars: [variable -> (vars?)]

    app:
          [[f: symbol,
            {args: finite_sequence[term] | args`length = arity(f)}] ->
             (app?)]

    term_ord: [term -> upto(1)]

    term_ord_defaxiom: AXIOM
      (FORALL (v: variable): term_ord(vars(v)) = 0) AND
       (FORALL (f: symbol,
                args:
                  {args: finite_sequence[term] | args`length = arity(f)}):
          term_ord(app(f, args)) = 1);

    ord(x: term): [term -> upto(1)] =
        CASES x OF vars(vars1_var): 0, app(app1_var, app2_var): 1 ENDCASES

    term_vars_extensionality: AXIOM
      FORALL (vars?_var: (vars?), vars?_var2: (vars?)):
        v(vars?_var) = v(vars?_var2) IMPLIES vars?_var = vars?_var2;

    term_vars_eta: AXIOM
      FORALL (vars?_var: (vars?)): vars(v(vars?_var)) = vars?_var;

    term_app_extensionality: AXIOM
      FORALL (app?_var: (app?), app?_var2: (app?)):
        f(app?_var) = f(app?_var2) AND args(app?_var) = args(app?_var2)
         IMPLIES app?_var = app?_var2;

    term_app_eta: AXIOM
      FORALL (app?_var: (app?)): app(f(app?_var), args(app?_var)) = app?_var;

    term_v_vars: AXIOM
      FORALL (vars1_var: variable): v(vars(vars1_var)) = vars1_var;

    term_f_app: AXIOM
      FORALL (app1_var: symbol,
              app2_var:
                {args: finite_sequence[term] |
                         args`length = arity(app1_var)}):
        f(app(app1_var, app2_var)) = app1_var;

    term_args_app: AXIOM
      FORALL (app1_var: symbol,
              app2_var:
                {args: finite_sequence[term] |
                         args`length = arity(app1_var)}):
        args(app(app1_var, app2_var)) = app2_var;

    term_inclusive: AXIOM
      FORALL (term_var: term): vars?(term_var) OR app?(term_var);

    term_induction: AXIOM
      FORALL (p: [term -> boolean]):
        ((FORALL (vars1_var: variable): p(vars(vars1_var))) AND
          (FORALL (app1_var: symbol,
                   app2_var:
                     {args: finite_sequence[term] |
                              args`length = arity(app1_var)}):
             (FORALL (x: below[app2_var`length]): p(app2_var`seq(x))) IMPLIES
              p(app(app1_var, app2_var))))
         IMPLIES (FORALL (term_var: term): p(term_var));

    every(p: PRED[variable])(a: term):  boolean =
        CASES a
          OF vars(vars1_var): p(vars1_var), app(app1_var, app2_var): TRUE
          ENDCASES;

    every(p: PRED[variable], a: term):  boolean =
        CASES a
          OF vars(vars1_var): p(vars1_var), app(app1_var, app2_var): TRUE
          ENDCASES;

    some(p: PRED[variable])(a: term):  boolean =
        CASES a
          OF vars(vars1_var): p(vars1_var), app(app1_var, app2_var): FALSE
          ENDCASES;

    some(p: PRED[variable], a: term):  boolean =
        CASES a
          OF vars(vars1_var): p(vars1_var), app(app1_var, app2_var): FALSE
          ENDCASES;

    subterm(x: term, y: term):  boolean =
        x = y OR
         CASES y
           OF vars(vars1_var): FALSE,
              app(app1_var, app2_var):
                EXISTS (z: below[app2_var`length]):
                  subterm(x, seq(app2_var)(z))
           ENDCASES;

    <<:  (strict_well_founded?[term]) =
        LAMBDA (x, y: term):
          CASES y
            OF vars(vars1_var): FALSE,
               app(app1_var, app2_var):
                 EXISTS (z: below[app2_var`length]):
                   subterm(x, seq(app2_var)(z))
            ENDCASES;

    term_well_founded: AXIOM strict_well_founded?[term](<<);

    reduce_nat(vars?_fun: [variable -> nat],
               app?_fun:
                 [[app1_var: symbol,
                   {args: finite_sequence[nat] |
                            args`length = arity(app1_var)}] ->
                    nat]):
          [term -> nat] =
        LAMBDA (term_adtvar: term):
          LET red: [term -> nat] = reduce_nat(vars?_fun, app?_fun) IN
            CASES term_adtvar
              OF vars(vars1_var): vars?_fun(vars1_var),
                 app(app1_var, app2_var):
                   app?_fun(app1_var,
                            (# length := length(app2_var),
                               seq
                                 := (LAMBDA (a:
                                             [below[app2_var`length] ->
                                              term]):
                                       LAMBDA
                                       (x: below[app2_var`length]):
                                       red(a(x)))
                                        (seq(app2_var)) #))
              ENDCASES;

    REDUCE_nat(vars?_fun: [[variable, term] -> nat],
               app?_fun:
                 [[app1_var: symbol,
                   {args: finite_sequence[nat] |
                            args`length = arity(app1_var)},
                   term] ->
                    nat]):
          [term -> nat] =
        LAMBDA (term_adtvar: term):
          LET red: [term -> nat] = REDUCE_nat(vars?_fun, app?_fun) IN
            CASES term_adtvar
              OF vars(vars1_var): vars?_fun(vars1_var, term_adtvar),
                 app(app1_var, app2_var):
                   app?_fun(app1_var,
                            (# length := length(app2_var),
                               seq
                                 := (LAMBDA (a:
                                             [below[app2_var`length] ->
                                              term]):
                                       LAMBDA
                                       (x: below[app2_var`length]):
                                       red(a(x)))
                                        (seq(app2_var)) #),
                            term_adtvar)
              ENDCASES;

    reduce_ordinal(vars?_fun: [variable -> ordinal],
                   app?_fun:
                     [[app1_var: symbol,
                       {args: finite_sequence[ordinal] |
                                args`length = arity(app1_var)}] ->
                        ordinal]):
          [term -> ordinal] =
        LAMBDA (term_adtvar: term):
          LET red: [term -> ordinal] = reduce_ordinal(vars?_fun, app?_fun) IN
            CASES term_adtvar
              OF vars(vars1_var): vars?_fun(vars1_var),
                 app(app1_var, app2_var):
                   app?_fun(app1_var,
                            (# length := length(app2_var),
                               seq
                                 := (LAMBDA (a:
                                             [below[app2_var`length] ->
                                              term]):
                                       LAMBDA
                                       (x: below[app2_var`length]):
                                       red(a(x)))
                                        (seq(app2_var)) #))
              ENDCASES;

    REDUCE_ordinal(vars?_fun: [[variable, term] -> ordinal],
                   app?_fun:
                     [[app1_var: symbol,
                       {args: finite_sequence[ordinal] |
                                args`length = arity(app1_var)},
                       term] ->
                        ordinal]):
          [term -> ordinal] =
        LAMBDA (term_adtvar: term):
          LET red: [term -> ordinal] = REDUCE_ordinal(vars?_fun, app?_fun) IN
            CASES term_adtvar
              OF vars(vars1_var): vars?_fun(vars1_var, term_adtvar),
                 app(app1_var, app2_var):
                   app?_fun(app1_var,
                            (# length := length(app2_var),
                               seq
                                 := (LAMBDA (a:
                                             [below[app2_var`length] ->
                                              term]):
                                       LAMBDA
                                       (x: below[app2_var`length]):
                                       red(a(x)))
                                        (seq(app2_var)) #),
                            term_adtvar)
              ENDCASES;
   END term_adt


body:
  term_adt_map[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat],
               variable1: TYPE+]: THEORY
   BEGIN
    ASSUMING
     variable_TCC1: ASSUMPTION EXISTS (x: variable): TRUE;

     symbol_TCC1: ASSUMPTION EXISTS (x: symbol): TRUE;

     variable1_TCC1: ASSUMPTION EXISTS (x: variable1): TRUE;
    ENDASSUMING

    IMPORTING term_adt

    map(f1: [variable -> variable1])(a: term[variable, symbol, arity]):
          term[variable1, symbol, arity] =
        CASES a
          OF vars(vars1_var): vars(f1(vars1_var)),
             app(app1_var, app2_var):
               app(app1_var,
                   (# length := length(app2_var),
                      seq
                        := LAMBDA (x: below[app2_var`length]):
                             map(f1)(seq(app2_var)(x)) #))
          ENDCASES;

    map(f1: [variable -> variable1], a: term[variable, symbol, arity]):
          term[variable1, symbol, arity] =
        CASES a
          OF vars(vars1_var): vars(f1(vars1_var)),
             app(app1_var, app2_var):
               app(app1_var,
                   (# length := length(app2_var),
                      seq
                        := LAMBDA (x: below[app2_var`length]):
                             map(f1)(seq(app2_var)(x)) #))
          ENDCASES;

    every(R: [[variable, variable1] -> boolean])
         (x: term[variable, symbol, arity],
          y: term[variable1, symbol, arity]):
          boolean =
        vars?(x) AND vars?(y) AND R(v(x), v(y)) OR
              app?(x) AND app?(y) AND f(x) = f(y)
          AND args(x)`length = args(y)`length
          AND (FORALL (z:
                         {x1: nat |
                                  x1 < args(x)`length AND
                                   x1 < args(y)`length}):
                 every(R)(args(x)`seq(z), args(y)`seq(z)));
   END term_adt_map


body:
  term_adt_reduce[variable: TYPE+, symbol: TYPE+, arity: [symbol -> nat],
                  range: TYPE]: THEORY
   BEGIN
    ASSUMING
     variable_TCC1: ASSUMPTION EXISTS (x: variable): TRUE;

     symbol_TCC1: ASSUMPTION EXISTS (x: symbol): TRUE;
    ENDASSUMING

    IMPORTING term_adt[variable, symbol, arity]

    reduce(vars?_fun: [variable -> range],
           app?_fun:
             [[symbol,
               {args: finite_sequence[range] | args`length = arity(f)}] ->
                range]):
          [term[variable, symbol, arity] -> range] =
        LAMBDA (term_adtvar: term[variable, symbol, arity]):
          LET red: [term[variable, symbol, arity] -> range] =
                reduce(vars?_fun, app?_fun)
            IN
            CASES term_adtvar
              OF vars(vars1_var): vars?_fun(vars1_var),
                 app(app1_var, app2_var):
                   app?_fun(app1_var,
                            (# length := length(app2_var),
                               seq
                                 := (LAMBDA (a:
                                             [below[app2_var`length] ->
                                              term
                                              [variable, symbol, arity]]):
                                       LAMBDA
                                       (x: below[app2_var`length]):
                                       red(a(x)))
                                        (seq(app2_var)) #))
              ENDCASES;

    REDUCE(vars?_fun: [[variable, term[variable, symbol, arity]] -> range],
           app?_fun:
             [[symbol,
               {args: finite_sequence[range] | args`length = arity(f)},
               term[variable, symbol, arity]] ->
                range]):
          [term[variable, symbol, arity] -> range] =
        LAMBDA (term_adtvar: term[variable, symbol, arity]):
          LET red: [term[variable, symbol, arity] -> range] =
                REDUCE(vars?_fun, app?_fun)
            IN
            CASES term_adtvar
              OF vars(vars1_var): vars?_fun(vars1_var, term_adtvar),
                 app(app1_var, app2_var):
                   app?_fun(app1_var,
                            (# length := length(app2_var),
                               seq
                                 := (LAMBDA (a:
                                             [below[app2_var`length] ->
                                              term
                                              [variable, symbol, arity]]):
                                       LAMBDA
                                       (x: below[app2_var`length]):
                                       red(a(x)))
                                        (seq(app2_var)) #),
                            term_adtvar)
              ENDCASES;
   END term_adt_reduce


body:
  %---------------------------------------------------------------------
  % A formal theory of cooperative TU-games in PVS 4.2
  %
  % Author: Erik Martin-Dorel,
  % University Montpellier 2 & University of Perpignan
  %
  %   Version 1.0    2009/06/30    Initial version
  %
  % This work has been done at the University of Perpignan
  % within the Master's Thesis, under the supervision of
  % Marc Daumas and Annick Truffert, with the help of Michel Ventou
  %
  % Presented at the 6th conference on Modeling Decisions for 
  % Artificial Intelligence (MDAI 2009 in Awaji Island, Japan)
  % and a report appears in Volume 5861/2009 of the Lecture Notes in
  % Computer Science (Springer).
  % A Formal Theory of Cooperative TU-Games
  % DOI	 10.1007/978-3-642-04820-3_8
  % Pages	 81-91
  %
  % This library is available under GNU Lesser General Public License,
  % either version 3 of the Licence, or any later version  (cf. infra)
  %---------------------------------------------------------------------


  top: THEORY

   BEGIN

    % The first parameter of each THEORY (U:TYPE+) represents
    % the Universe of players that are likely to participate.

    IMPORTING players_set,   % (param. by [U]    ) first TYPE to be defined
              coalition_fun, % (param. by [U,N]  ) finite_sets imported here
              imputations,   % (param. by [U,N,v]) payoffs, imputations, core

              tu_game        % from tu_game TYPE to solution_concept Properties

   END top


body:
  %---------------------------------------------------------------------
  % A formal theory of cooperative TU-games in PVS 4.2 
  %
  % Author: Erik Martin-Dorel,
  % University Montpellier 2 & University of Perpignan
  %
  %   THEORIES players_set[U] and
  %            coalition_fun[U,N]
  %
  %   Version 1.0    2009/05/01    Initial version
  %   Version 1.1    2009/05/10    Identifiers renamed
  %   Version 1.2    2009/05/14    Lemmas added
  %   Version 1.3    2009/10/03    Conversion avoided in Judgement proof
  %
  % This work has been done at the University of Perpignan
  % within the Master's Thesis, under the supervision of
  % Marc Daumas and Annick Truffert, with the help of Michel Ventou
  %
  % This library is available under GNU Lesser General Public License,
  % either version 3 of the Licence, or any later version
  %---------------------------------------------------------------------


  players_set[U: TYPE+]: THEORY
   BEGIN
    elt: U
    players_set: TYPE+ = non_empty_finite_set[U] CONTAINING singleton(elt)
   END players_set


body:
  %---------------------------------------------------------------------
  % A formal theory of cooperative TU-games in PVS 4.2 
  %
  % Author: Erik Martin-Dorel,
  % University Montpellier 2 & University of Perpignan
  %
  %   THEORIES players_set[U] and
  %            coalition_fun[U,N]
  %
  %   Version 1.0    2009/05/01    Initial version
  %   Version 1.1    2009/05/10    Identifiers renamed
  %   Version 1.2    2009/05/14    Lemmas added
  %   Version 1.3    2009/10/03    Conversion avoided in Judgement proof
  %
  % This work has been done at the University of Perpignan
  % within the Master's Thesis, under the supervision of
  % Marc Daumas and Annick Truffert, with the help of Michel Ventou
  %
  % This library is available under GNU Lesser General Public License,
  % either version 3 of the Licence, or any later version
  %---------------------------------------------------------------------


  %players_set[U: TYPE+]: THEORY
  % BEGIN
  %  elt: U
  %  players_set: TYPE+ = non_empty_finite_set[U] CONTAINING singleton(elt)
  % END players_set


  coalition_fun[U: TYPE+,       (IMPORTING players_set[U])
                N: players_set]: THEORY
   BEGIN

    IMPORTING players_set[U]

    powset: TYPE = setof[(N)] % rather than (powerset[U](N))

    fullN: powset = fullset[(N)]

    v: VAR [powset -> real]
    S: VAR powset
    x, y: VAR [(N) -> real]
    i: VAR (N)
    c: VAR real
    a: VAR nzreal

    zero_fun(S): real = 0
    coalition_fun?(v): bool = v(emptyset) = 0
    coalition_fun: TYPE+ = (coalition_fun?) CONTAINING zero_fun

    subsets_are_finite: JUDGEMENT setof[(N)] SUBTYPE_OF finite_set[(N)]

    IMPORTING %finite_sets@finite_sets_sum[(N),real,0,+],
              finite_sets@finite_sets_sum_real[(N)]

    tot(S, x): real = sum(S, x)

    tot_S_0: LEMMA tot(S, LAMBDA i: 0) = 0
    tot_distrib: LEMMA tot(S, LAMBDA i: x(i) + y(i)) = tot(S, x) + tot(S, y)
    tot_mult_const:  LEMMA tot(S, LAMBDA i: c * x(i)) = c * tot(S,x)
    tot_distrib_sub: LEMMA tot(S, LAMBDA i: x(i) - y(i)) = tot(S, x) - tot(S, y)
    tot_div_const:   LEMMA tot(S, LAMBDA i: x(i) / a) = tot(S,x) / a


    set_vect: TYPE = setof[[(N) -> real]]

   END coalition_fun

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 50, column 53) for  zero_fun
      % expected type  coalition_fun
  coalition_fun_TCC1: OBLIGATION coalition_fun?(zero_fun);

  % Judgement subtype TCC generated (at line 52, column 32) for  x
      % expected type  finite_set[(N)]
  subsets_are_finite: OBLIGATION FORALL (x: setof[(N)]): is_finite[(N)](x);


body:
  %---------------------------------------------------------------------
  % A formal theory of cooperative TU-games in PVS 4.2 
  %
  % Author: Erik Martin-Dorel,
  % University Montpellier 2 & University of Perpignan
  %
  %   THEORY imputations[U,N,v]
  %
  %   Version 1.0    2009/05/05    Initial version
  %   Version 1.1    2009/05/07    subset_core_I added
  %   Version 1.2    2009/05/10    Identifiers renamed
  %
  % This work has been done at the University of Perpignan
  % within the Master's Thesis, under the supervision of
  % Marc Daumas and Annick Truffert, with the help of Michel Ventou
  %
  % This library is available under GNU Lesser General Public License,
  % either version 3 of the Licence, or any later version
  %---------------------------------------------------------------------


  imputations[U: TYPE+,     (IMPORTING players_set[U])
              N: players_set, (IMPORTING coalition_fun[U,N])
              v: coalition_fun]: THEORY
   BEGIN

    IMPORTING players_set[U],
              coalition_fun[U,N]

    % set_vect: TYPE = setof[[(N) -> real]]

    x: VAR [(N) -> real]
    i: VAR (N)
    S: VAR powset % = setof[(N)] = [(N) -> bool]

    % feasible payoffs
    setFP: set_vect = {x | tot(fullN, x) <= v(fullN)}

    % preimputations
    setPI: set_vect = {x | tot(fullN, x) = v(fullN)}

    % imputations
    setI: set_vect = {x | member(x, setPI) AND FORALL i: x(i) >= v(singleton(i))}

    % core: set_vect = {x: (setPI) | FORALL S: tot(S, x) >= v(S)}
    core: set_vect = {x | member(x, setPI) AND FORALL S: tot(S, x) >= v(S)}

    subset_core_I: LEMMA subset?(core, setI)

    subset_I_PI:   LEMMA subset?(setI, setPI)
    subset_PI_FP:  LEMMA subset?(setPI, setFP)

   END imputations


body:
  %---------------------------------------------------------------------
  % A formal theory of cooperative TU-games in PVS 4.2
  %
  % Author: Erik Martin-Dorel,
  % University Montpellier 2 & University of Perpignan
  %
  %   THEORY tu_game[U]
  %
  %   Version 1.0    2009/05/06    Initial version
  %   Version 1.1    2009/05/10    Identifiers renamed
  %   Version 1.2    2009/05/14    COV_core proved
  %   Version 1.3    2009/10/03    Universal quantifiers merged
  %
  % This work has been done at the University of Perpignan
  % within the Master's Thesis, under the supervision of
  % Marc Daumas and Annick Truffert, with the help of Michel Ventou
  %
  % This library is available under GNU Lesser General Public License,
  % either version 3 of the Licence, or any later version  (cf. infra)
  %---------------------------------------------------------------------


  tu_game[U: TYPE+]: THEORY

   BEGIN

    IMPORTING players_set[U],
              coalition_fun,
              imputations

    % cooperative Transferable-Utility game
    tu_game: TYPE = [N: players_set, v: coalition_fun[U,N]]
    % which is a dependent 2-ary tuple type

    N: VAR players_set
    powset(N): TYPE = powset[U,N]
    set_vect(N): TYPE = set_vect[U,N]

    g: VAR tu_game
    setFP(g): set_vect(g`1) = setFP[U,g`1,g`2]
    setPI(g): set_vect(g`1) = setPI[U,g`1,g`2]
    setI(g):  set_vect(g`1) =  setI[U,g`1,g`2]
    core(g):  set_vect(g`1) =  core[U,g`1,g`2]

    ss: VAR [g:tu_game -> set_vect(g`1)]
    solution_concept?(ss): bool = FORALL (g:tu_game): subset?(ss(g), setFP(g))
    solution_concept: TYPE+ = (solution_concept?) CONTAINING core
    % core_type: JUDGEMENT core HAS_TYPE solution_concept

    s: VAR solution_concept
    a_test: LEMMA subset?(s(g), setFP(g)) % and this FOR ALL game g.

    % Thanks to the equivalence between
    % [[t_1,...,t_n] -> t] and [t_1,...,t_n -> t],
    % our definition of "tu_game" as a tuple type makes
    % the functions defined on it very handy to use.
    test_param: LEMMA s(g) = s(g`1, g`2)

    %--------------------------------
    % Predicates on solution_concept:
    %--------------------------------

    % 1) Pareto optimal (PO)
    PO(s): bool = FORALL g: subset?(s(g), setPI(g))

    % 2) anonymous (AN)
    NN: VAR players_set
    tau_type(N,NN): TYPE = (bijective?[(N),(NN)])
    tau_v(g:tu_game,NN:players_set,tau:tau_type(g`1,NN)): coalition_fun[U,NN] =
      g`2 o inverse_image(tau)
    tau_x(g:tu_game,NN:players_set,tau:tau_type(g`1,NN))(
      x:[(g`1)->real]): [(NN)->real] =
      LAMBDA (i:(NN)): x(inverse(tau)(i))
    % AN(s): bool = FORALL g,NN:
    %               FORALL (tau:tau_type(g`1,NN)):
    AN(s): bool = FORALL (g:tu_game, NN:players_set,
                          tau:tau_type(g`1,NN)):
    s(NN,tau_v(g,NN,tau)) = image(tau_x(g,NN,tau),s(g))

    % 3) equal treatment property (ETP)
    interchangeable?(g)(i,j:(g`1)): bool =
      FORALL (S:setof[(g`1)]): (NOT member(i,S)) AND (NOT member(j,S)) =>
      g`2(add(i,S)) = g`2(add(j,S))
    % ETP(s): bool = FORALL g: FORALL (x:(s(g))):
    %   FORALL (i,j:(g`1)): interchangeable?(g)(i,j) =>
    %   x(i) = x(j)
    ETP(s): bool = FORALL (g:tu_game, x:(s(g)), i,j:(g`1)):
      interchangeable?(g)(i,j) => x(i) = x(j)

    % 4) desirability (DES)
    more_desirable?(g)(i,j:(g`1)): bool =
      FORALL (S:setof[(g`1)]): (NOT member(i,S)) AND (NOT member(j,S)) =>
      g`2(add(i,S)) >= g`2(add(j,S))
    % DES(s): bool = FORALL g: FORALL (x:(s(g))):
    %   FORALL (i,j:(g`1)): more_desirable?(g)(i,j) =>
    %   x(i) >= x(j)
    DES(s): bool = FORALL (g:tu_game, x:(s(g)), i,j:(g`1)):
      more_desirable?(g)(i,j) => x(i) >= x(j)

    % 5) nullplayer property (NPP)
    nullplayer?(g)(i:(g`1)): bool =
      FORALL (S:setof[(g`1)]): (NOT member(i,S)) =>
      g`2(add(i,S)) = g`2(S) + g`2(singleton(i))
    % nullplayer(g): TYPE = (nullplayer?(g)) % if needed
    NPP(s): bool = FORALL (g:tu_game, x:(s(g)), i:(g`1)):
    % FORALL (i:nullplayer(g)): x(i) = g`2(singleton(i))
    nullplayer?(g)(i) => x(i) = g`2(singleton(i))

    %   NPP(s): bool = FORALL g: FORALL (x:(s(g))):
    %   FORALL (i:(g`1)): nullplayer?(g)(i) =>
    %     x(i) = g`2(singleton(i))

    % 6) covariant under strategic equivalence (COV)
    lin(N: players_set, a:real, x: [(N) -> real])(i:(N)): real
      = a*x(i)
    affine(N: players_set, a:real, b: [(N) -> real])
      (x: [(N) -> real]): [(N) -> real] =
      LAMBDA (i:(N)): lin(N,a,x)(i) + b(i)
    dif(N: players_set, y, b: [(N) -> real])(i:(N)): real
      = y(i) - b(i)
    affineinv(N: players_set, a:nzreal, b: [(N) -> real])
      (y: [(N) -> real]): [(N) -> real] =
      LAMBDA (i:(N)): dif(N,y,b)(i) / a
    bstar(N: players_set, b: [(N) -> real]): coalition_fun[U,N] =
      LAMBDA (S:powset(N)): tot(S, b)
    affinestar(N: players_set, a:real, b: [(N) -> real])
      (v: coalition_fun[U,N]): coalition_fun[U,N] =
      LAMBDA (S:powset(N)): a*v(S) + bstar(N,b)(S)
    % COV(s): bool = FORALL (N:players_set):
    %   FORALL (a:posreal, b:[(N) -> real]):
    %   FORALL (v: coalition_fun[U,N]):
    %   s(N,affinestar(N,a,b)(v)) = image(affine(N,a,b), s(N,v))
    COV(s): bool = FORALL (N:players_set, a: posreal, b: [(N) -> real],
                           v:coalition_fun[U,N]):
      s(N,affinestar(N,a,b)(v)) = image(affine(N,a,b), s(N,v))

    % 7) single valued (SIVA)
    SIVA(s): bool = FORALL g: is_finite(s(g)) AND card(s(g)) = 1

    % 8) nonemptiness (NE)
    NE(s): bool =   FORALL g: nonempty?(s(g))

    % 9) Reasonableness, on both side (REAS)
    % REAS(s): bool = FORALL (N:players_set, v:coalition_fun[U,N]):
    %   FORALL (x:(s(N,v))): FORALL (i:(N)):
    % (EXISTS (S1:powset(N)): (NOT member(i,S1)) AND x(i) >= v(add(i,S1))-v(S1))
    % AND
    % (EXISTS (S2:powset(N)): (NOT member(i,S2)) AND x(i) <= v(add(i,S2))-v(S2))
    REAS(s): bool = FORALL (N:players_set, v:coalition_fun[U,N],
                            x:(s(N,v)), i:(N)):
      (EXISTS (S1:powset(N)): (NOT member(i,S1)) AND x(i) >= v(add(i,S1))-v(S1))
      AND
      (EXISTS (S2:powset(N)): (NOT member(i,S2)) AND x(i) <= v(add(i,S2))-v(S2))

    %--------------------------------

    % DES_ETP_lemma1: LEMMA FORALL g: FORALL (i,j:(g`1)):
    %   interchangeable?(g)(i,j) => more_desirable?(g)(i,j)
    interch_impl_desir: LEMMA FORALL (g:tu_game, i,j:(g`1)):
      interchangeable?(g)(i,j) => more_desirable?(g)(i,j)

    % DES_ETP_lemma2: LEMMA FORALL g: FORALL (i,j:(g`1)):
    %   interchangeable?(g)(i,j) => interchangeable?(g)(j,i)
    interch_is_sym: LEMMA FORALL (g:tu_game, i,j:(g`1)):
      interchangeable?(g)(i,j) => interchangeable?(g)(j,i)

    DES_implies_ETP: THEOREM DES(s) => ETP(s)

    SIVA_implies_NE: THEOREM SIVA(s) => NE(s)

    PO_core: THEOREM PO(core)

    affine_bij: LEMMA FORALL (N:players_set,
      a: posreal, b,x: [(N) -> real]):
      affine(N,a,b)(affineinv(N,a,b)(x)) = x
    COV_core: THEOREM COV(core)

   END tu_game

addendum:
  %%% ================ Addendum: generated declarations ================

  % Subtype TCC generated (at line 47, column 59) for  core
      % expected type  solution_concept
  solution_concept_TCC1: OBLIGATION solution_concept?(core);

  % Subtype TCC generated (at line 70, column 4) for  g`2 o inverse_image(tau)
      % expected type  coalition_fun[U, NN]
  tau_v_TCC1: OBLIGATION
    FORALL (g: tu_game, NN: players_set[U], tau: tau_type(g`1, NN)):
      coalition_fun?[U, NN]
          (o[set[(NN)], powset[U, g`1], real]
               (g`2, inverse_image[(g`1), (NN)](tau)));

  % Existence TCC generated (at line 73, column 23) for  inverse
  tau_x_TCC1: OBLIGATION
    FORALL (g: tu_game, NN: players_set[U], tau: tau_type(g`1, NN), i: (NN)):
      EXISTS (x1: (g`1)): TRUE;

  % Subtype TCC generated (at line 125, column 4) for
      % LAMBDA (S: powset(N)): tot(S, b)
      % expected type  coalition_fun[U, N]
  bstar_TCC1: OBLIGATION
    FORALL (N: players_set[U], b: [(N) -> real]):
      coalition_fun?[U, N](LAMBDA (S: powset(N)): tot[U, N](S, b));

  % Subtype TCC generated (at line 128, column 4) for
      % LAMBDA (S: powset(N)): a * v(S) + bstar(N, b)(S)
      % expected type  coalition_fun[U, N]
  affinestar_TCC1: OBLIGATION
    FORALL (N: players_set[U], a: real, b: [(N) -> real],
            v: coalition_fun[U, N]):
      coalition_fun?[U, N](LAMBDA (S: powset(N)): a * v(S) + bstar(N, b)(S));


