# TheoryBodies

body:
  sigma_upto[N: nat]: THEORY
  %------------------------------------------------------------------------------
  % The summations theory provides properties of the sigma 
  % function that sums an arbitrary function F: [upto[N] -> real] over a range
  % from low to high
  %
  %  		          high
  %		          ----
  %  sigma(low, high, F) =  \     F(j)
  %		          /
  %		          ----
  %		         j = low
  %
  %
  %------------------------------------------------------------------------------


  BEGIN

    IMPORTING sigma[upto[N]]

    int_upto: TYPE = {i:int | i <= N}
    int_upto_T_high: JUDGEMENT int_upto SUBTYPE_OF T_high
    nat_is_T_low: JUDGEMENT nat SUBTYPE_OF T_low


    low, high, n, m: VAR upto[N]
    F: VAR function[upto[N] -> real]


  % --------- Following Theorems Not Provable In Generic Framework -------

    sigma_first_ge : THEOREM high >= low IMPLIES
                             sigma(low, high, F) = F(low) + sigma(low+1, high, F)

    sigma_last_ge  : THEOREM high >= low IMPLIES 
                            sigma(low, high, F) = sigma(low, high-1, F) + F(high)

    sigma_split_ge : THEOREM low-1 <= m AND m <= high IMPLIES 
                              sigma(low, high, F) = 
                                       sigma(low, m, F) + sigma(m+1, high, F)



  % ---- Auto-rewrites


    nn: VAR negint
    sigma_0_neg: LEMMA sigma(0,nn,F) = 0
    AUTO_REWRITE+ sigma_0_neg


  END sigma_upto

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

  % Assuming TCC generated (at line 20, column 12) for  sigma[upto[N]]
      % generated from assumption sigma.connected_domain
  IMP_sigma_TCC1: OBLIGATION
    (FORALL (x, y: upto[N]), (z: integer):
       x <= z AND z <= y IMPLIES z >= 0 AND z <= N);

  % Judgement subtype TCC generated (at line 23, column 29) for  x
      % expected type  T_high[upto[N]]
  int_upto_T_high: OBLIGATION
    FORALL (x: int_upto): x >= 0 AND x <= N OR (EXISTS (j: upto[N]): x <= j);

  % Judgement subtype TCC generated (at line 24, column 26) for  x
      % expected type  T_low[upto[N]]
  nat_is_T_low: OBLIGATION
    FORALL (x: nat): x >= 0 AND x <= N OR (EXISTS (j: upto[N]): j <= x);

  % Subtype TCC generated (at line 34, column 38) for  high
      % expected type  T_high[upto[N]]
  sigma_first_ge_TCC1: OBLIGATION
    FORALL (high, low: upto[N]):
      high >= low IMPLIES
       high >= 0 AND high <= N OR (EXISTS (j: upto[N]): high <= j);

  % Subtype TCC generated (at line 37, column 59) for  high - 1
      % expected type  T_high[upto[N]]
  sigma_last_ge_TCC1: OBLIGATION
    FORALL (high, low: upto[N]):
      high >= low IMPLIES
       high - 1 >= 0 AND high - 1 <= N OR
        (EXISTS (j: upto[N]): high - 1 <= j);

  % Subtype TCC generated (at line 40, column 39) for  high
      % expected type  T_high[upto[N]]
  sigma_split_ge_TCC1: OBLIGATION
    FORALL (high, low, m: upto[N]):
      m <= high AND low - 1 <= m IMPLIES
       high >= 0 AND high <= N OR (EXISTS (j: upto[N]): high <= j);

  % Subtype TCC generated (at line 41, column 48) for  m
      % expected type  T_high[upto[N]]
  sigma_split_ge_TCC2: OBLIGATION
    FORALL (high, low, m: upto[N]):
      m <= high AND low - 1 <= m IMPLIES
       m >= 0 AND m <= N OR (EXISTS (j: upto[N]): m <= j);

  % Subtype TCC generated (at line 49, column 29) for  nn
      % expected type  T_high[upto[N]]
  sigma_0_neg_TCC1: OBLIGATION
    FORALL (nn: negint):
      nn >= 0 AND nn <= N OR (EXISTS (j: upto[N]): nn <= j);


body:
  factorial: THEORY
  %-------------------------------------------------------------------------------
  %
  %  factorial moved to ints library
  %
  %  This shell retained to help transition
  %
  %-------------------------------------------------------------------------------
  BEGIN

     IMPORTING ints@factorial,product
   
     n : VAR nat
     p : VAR posnat

     factorial_product : LEMMA
       factorial(n) = product(1,n,LAMBDA(i:nat):i)     

     product_factorial : LEMMA
       product(1,p,LAMBDA(i:posnat):i) = factorial(p)

  END factorial

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

  % Subtype TCC generated (at line 17, column 28) for  1
      % expected type  T_low[nat]
  factorial_product_TCC1: OBLIGATION 1 >= 0 OR (EXISTS (j: nat): j <= 1);

  % Subtype TCC generated (at line 17, column 30) for  n
      % expected type  T_high[nat]
  factorial_product_TCC2: OBLIGATION
    FORALL (n: nat): n >= 0 OR (EXISTS (j: nat): n <= j);

  % Assuming TCC generated (at line 11, column 28) for  product[nat]
      % generated from assumption product.connected_domain
  factorial_product_TCC3: OBLIGATION
    (FORALL (x, y: nat), (z: integer): x <= z AND z <= y IMPLIES z >= 0);

  % Subtype TCC generated (at line 20, column 13) for  1
      % expected type  T_low[posnat]
  product_factorial_TCC1: OBLIGATION
    1 >= 0 AND 1 > 0 OR (EXISTS (j: posnat): j <= 1);

  % Subtype TCC generated (at line 20, column 15) for  p
      % expected type  T_high[posnat]
  product_factorial_TCC2: OBLIGATION
    FORALL (p: posnat): p >= 0 AND p > 0 OR (EXISTS (j: posnat): p <= j);

  % Assuming TCC generated (at line 11, column 28) for  product[posnat]
      % generated from assumption product.connected_domain
  product_factorial_TCC3: OBLIGATION
    (FORALL (x, y: posnat), (z: integer):
       x <= z AND z <= y IMPLIES z >= 0 AND z > 0);


body:
  binomial: THEORY
  %------------------------------------------------------------------------------
  %
  % Binomial coefficient
  %
  % Author: David Lester              Manchester University
  %
  %------------------------------------------------------------------------------

    BEGIN

    IMPORTING factorial, sigma_upto, product[posnat]

    n:    VAR nat
    pn:   VAR posnat
    nge2: VAR {k:posnat| k>=2}

    C(n:nat,k:{i:nat| i<=n}):posnat = factorial(n)/(factorial(k)*factorial(n-k))

    C_0:     LEMMA C(n,0)     = 1
    C_n:     LEMMA C(n,n)     = 1
    C_1:     LEMMA C(pn,1)    = pn
    C_n_1:   LEMMA C(pn,pn-1) = pn

    C_symmetry:  LEMMA FORALL (k:{i:nat| i<=n}): C(n,k) = C(n,n-k)

    C_n_plus_1:  LEMMA FORALL (k:{i:posnat| i<=n}): C(n+1,k) = C(n,k)+C(n,k-1)
    C_k_plus_1:  LEMMA FORALL (k:{i:nat| i<n}): C(n,k)*(n-k) = C(n,k+1)*(k+1)
    C_k_minus_1: LEMMA FORALL (k:{i:nat| i<n}): C(n,k+1) = C(n,k)*((n-k)/(k+1))

    C_2:         LEMMA C(nge2,2)      = (nge2*(nge2-1))/2
    C_n_2:       LEMMA C(nge2,nge2-2) = (nge2*(nge2-1))/2

    sigma_C:     LEMMA sigma(0,n,LAMBDA (i:{i:nat| i<=n}): C(n,i)) = 2^n

    % An iterative version of C(n,k) =  product(1,k,(n-(k-i))/i) 

    C_it(n:nat,k:{i:nat| i<=n}):rat =
      product_it(1,k,LAMBDA(i:posnat):(n-(k-i))/i)

    C_it_C : LEMMA
        C_it = C

    C_it_posnat : JUDGEMENT
      C_it(n:nat,k:{i:nat| i<=n}) HAS_TYPE posnat

    END binomial

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

  % Assuming TCC generated (at line 12, column 35) for  product[posnat]
      % generated from assumption product.connected_domain
  IMP_product_TCC1: OBLIGATION
    (FORALL (x, y: posnat), (z: integer):
       x <= z AND z <= y IMPLIES z >= 0 AND z > 0);

  % Subtype TCC generated (at line 18, column 73) for  n - k
      % expected type  nat
  C_TCC1: OBLIGATION FORALL (n: nat, k: {i: nat | i <= n}): n - k >= 0;

  % Subtype TCC generated (at line 18, column 36) for
      % factorial(n) / (factorial(k) * factorial(n - k))
      % expected type  posnat
  C_TCC2: OBLIGATION
    FORALL (n: nat, k: {i: nat | i <= n}):
      integer_pred(factorial(n) / (factorial(k) * factorial(n - k))) AND
       factorial(n) / (factorial(k) * factorial(n - k)) >= 0 AND
        factorial(n) / (factorial(k) * factorial(n - k)) > 0;

  % Subtype TCC generated (at line 20, column 21) for  0
      % expected type  {i: nat | i <= n}
  C_0_TCC1: OBLIGATION FORALL (n: nat): 0 <= n;

  % Subtype TCC generated (at line 21, column 21) for  n
      % expected type  {i: nat | i <= n}
  C_n_TCC1: OBLIGATION FORALL (n: nat): n <= n;

  % Subtype TCC generated (at line 22, column 22) for  1
      % expected type  {i: nat | i <= pn}
  C_1_TCC1: OBLIGATION FORALL (pn: posnat): 1 <= pn;

  % Subtype TCC generated (at line 23, column 22) for  pn - 1
      % expected type  {i: nat | i <= pn}
  C_n_1_TCC1: OBLIGATION FORALL (pn: posnat): pn - 1 >= 0 AND pn - 1 <= pn;

  % Subtype TCC generated (at line 25, column 60) for  n - k
      % expected type  {i: nat | i <= n}
  C_symmetry_TCC1: OBLIGATION
    FORALL (n: nat, k: {i: nat | i <= n}): n - k >= 0 AND n - k <= n;

  % Subtype TCC generated (at line 27, column 56) for  k
      % expected type  {i: nat | i <= 1 + n}
  C_n_plus_1_TCC1: OBLIGATION
    FORALL (n: nat, k: {i: posnat | i <= n}): k <= 1 + n;

  % Subtype TCC generated (at line 27, column 72) for  k - 1
      % expected type  {i: nat | i <= n}
  C_n_plus_1_TCC2: OBLIGATION
    FORALL (n: nat, k: {i: posnat | i <= n}): k - 1 >= 0 AND k - 1 <= n;

  % Subtype TCC generated (at line 28, column 50) for  k
      % expected type  {i: nat | i <= n}
  C_k_plus_1_TCC1: OBLIGATION FORALL (n: nat, k: {i: nat | i < n}): k <= n;

  % Subtype TCC generated (at line 28, column 65) for  k + 1
      % expected type  {i: nat | i <= n}
  C_k_plus_1_TCC2: OBLIGATION
    FORALL (n: nat, k: {i: nat | i < n}): k + 1 <= n;

  % Subtype TCC generated (at line 31, column 28) for  2
      % expected type  {i: nat | i <= nge2}
  C_2_TCC1: OBLIGATION FORALL (nge2: {k: posnat | k >= 2}): 2 <= nge2;

  % Subtype TCC generated (at line 32, column 28) for  nge2 - 2
      % expected type  {i: nat | i <= nge2}
  C_n_2_TCC1: OBLIGATION
    FORALL (nge2: {k: posnat | k >= 2}): nge2 - 2 >= 0 AND nge2 - 2 <= nge2;

  % Subtype TCC generated (at line 34, column 27) for  0
      % expected type  T_low[{i: nat | i <= n}]
  sigma_C_TCC1: OBLIGATION
    FORALL (n: nat):
      0 >= 0 AND 0 <= n OR (EXISTS (j: {i: nat | i <= n}): j <= 0);

  % Subtype TCC generated (at line 34, column 29) for  n
      % expected type  T_high[{i: nat | i <= n}]
  sigma_C_TCC2: OBLIGATION
    FORALL (n: nat):
      n >= 0 AND n <= n OR (EXISTS (j: {i: nat | i <= n}): n <= j);

  % Assuming TCC generated (at line 20, column 12) for
      % sigma[{i: nat | i <= n}]
      % generated from assumption sigma.connected_domain
  sigma_C_TCC3: OBLIGATION
    FORALL (n: nat, x, y: {i: nat | i <= n}, z: integer):
      x <= z AND z <= y IMPLIES z >= 0 AND z <= n;

  % Subtype TCC generated (at line 39, column 15) for  1
      % expected type  T_low[posnat]
  C_it_TCC1: OBLIGATION
    FORALL (n: nat, k: {i: nat | i <= n}):
      1 >= 0 AND 1 > 0 OR (EXISTS (j: posnat): j <= 1);

  % Subtype TCC generated (at line 39, column 17) for  k
      % expected type  T_high[posnat]
  C_it_TCC2: OBLIGATION
    FORALL (n: nat, k: {i: nat | i <= n}):
      k >= 0 AND k > 0 OR (EXISTS (j: posnat): k <= j);

  % Subtype TCC generated (at line 39, column 4) for
      % product_it(1, k, LAMBDA (i: posnat): (n - (k - i)) / i)
      % expected type  rat
  C_it_TCC3: OBLIGATION
    FORALL (n: nat, k: {i: nat | i <= n}):
      rational_pred(product_it[posnat]
                        (1, k, LAMBDA (i: posnat): (n - (k - i)) / i));

  % Judgement subtype TCC generated (at line 45, column 4) for  C_it(n, k)
      % expected type  posnat
  C_it_posnat: OBLIGATION
    FORALL (n: nat, k: {i: nat | i <= n}):
      integer_pred(C_it(n, k)) AND C_it(n, k) >= 0 AND C_it(n, k) > 0;


body:
  sigma_swap[T: TYPE FROM int]: THEORY
  %------------------------------------------------------------------------------
  % A theory on swapping summation signs
  %  
  %  AUTHOR:
  %
  %    Anthony Narkawicz     NASA Langley Research Center           
  %------------------------------------------------------------------------------

  BEGIN

    ASSUMING

       connected_domain: ASSUMPTION (FORALL (x, y: T), (z: integer):
                                         x <= z AND z <= y IMPLIES T_pred(z))
    ENDASSUMING

    IMPORTING sigma[T]

    low,low1,
    low2		: VAR T_low
    high,high1,
    high2		: VAR T_high 
    l,h,n,m,i,j 	: VAR T
    rng, nn   	: VAR nat
    pn        	: VAR posnat
    z        	: VAR int
    a,x,B     	: VAR real

    F		: VAR [[T,T]->real]

    sigma_swap: LEMMA
      sigma(low1,high1,LAMBDA (i:T): sigma(low2,high2,LAMBDA (j:T): F(i,j)))
      = sigma(low2,high2,LAMBDA (j:T): sigma(low1,high1,LAMBDA (i:T): F(i,j)))

    sigma_swap_triangle: LEMMA
      high1 >= high2 IMPLIES
      sigma(low1,high1,LAMBDA (i:T): sigma(i,high2,LAMBDA (j:T): F(i,j)))
      = sigma(low1,high2,LAMBDA (j:T): sigma(low1,j,LAMBDA (i:T): F(i,j)))

  END sigma_swap

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

  % Assuming TCC generated (at line 18, column 12) for  sigma[T]
      % generated from assumption sigma.connected_domain
  IMP_sigma_TCC1: OBLIGATION
    (FORALL (x, y: T), (z: integer): x <= z AND z <= y IMPLIES T_pred(z));


body:
  sigma_nat: THEORY
  %------------------------------------------------------------------------------
  % The summations theory provides properties of the sigma 
  % function that sums an arbitrary function F: [T -> real] over a range
  % from low to high
  %
  %  		          high
  %		          ----
  %  sigma(low, high, F) =  \     F(j)
  %		          /
  %		          ----
  %		         j = low
  %
  %
  % NOTE. Older versions of the library used a slightly more general
  %       version of "sigma_first", namely for high >= low rather
  %       than just high > low.  The lemma "sigma_first_ge" has been 
  %       added here to facilitate the upgrade to the new library.
  %
  %------------------------------------------------------------------------------


  BEGIN

    IMPORTING sigma[nat]

    int_is_T_high: JUDGEMENT int SUBTYPE_OF T_high
    nat_is_T_low : JUDGEMENT nat SUBTYPE_OF T_low

    high, high1, high2, i: VAR int
    low,low1,low2, n, m: VAR nat
    F,G: VAR function[nat -> real]


  % --------- Following Theorems Not Provable In Generic Framework -------


    sigma_shift:  THEOREM sigma(low+m,high+m,F) = 
                                sigma(low,high, (LAMBDA (n: nat): F(n+m)))

    sigma_shift_neg:  THEOREM low - m >= 0 IMPLIES 
                           sigma(low-m,high-m,F) = 
                               sigma(low,high, (LAMBDA n: IF n-m < 0 THEN 0 
                                                          ELSE F(n-m) 
                                                          ENDIF))

    sigma_shift_ng2:  THEOREM low - m >= 0 IMPLIES 
                           sigma(low-m,high-m,F) = 
                               sigma(low,high, (LAMBDA n: F(n~m)))


    sigma_shift_i:  THEOREM 0 <= low + i IMPLIES
                                sigma(low+i,high+i,F) = 
                                sigma(low,high, (LAMBDA (n: nat): IF n < low THEN 0
                                                                    ELSE F(n+i) ENDIF))

    sigma_shift_to_zero: LEMMA n<=m IMPLIES
      sigma(n,m,F) = sigma(0,m-n, (LAMBDA (i:nat): F(i+n)))

  % These next two are now trivial instatiations of the updated framework.

    sigma_first_ge : THEOREM high >= low IMPLIES  % slightly more general
                             sigma(low, high, F) = F(low) + sigma(low+1, high, F)


    sigma_split_ge : THEOREM low-1 <= i AND i <= high IMPLIES 
                              sigma(low, high, F) = 
                                       sigma(low, i, F) + sigma(i+1, high, F)

  % Summation in the opposite direction

    sigma_reverse : THEOREM sigma(low,high,F) = 
           sigma(low,high,(LAMBDA (n:nat): IF n > high+low THEN 0 ELSE F(high+low-n) ENDIF))


    sigma_product    : THEOREM sigma(low1,high1,F)*sigma(low2,high2,G) =
    		             sigma(low1+low2,high1+high2,LAMBDA (k:nat):
  			         sigma(low1,high1, 
  				   LAMBDA (i:nat): IF (i<k-high2 OR i>k-low2) THEN 0
  				                 ELSE F(i)*G(k-i) ENDIF))

    sigma_tolambda: LEMMA sigma(low,high,F) =
      sigma(low,high,LAMBDA (i:nat): F(i))

    sigma_bij: LEMMA FORALL (sig:[nat->nat]):
      (FORALL (i:subrange(low,high)): low<=sig(i) AND sig(i)<=high) AND
      (FORALL (i:subrange(low,high)): EXISTS (j:subrange(low,high)): sig(j)=i) AND
      (FORALL (i,j:subrange(low,high)): i/=j IMPLIES sig(i)/=sig(j))
      IMPLIES
      sigma(low,high,F) = sigma(low,high,F o sig)

    sigma_inj: LEMMA FORALL (sig:[nat->nat]):
      (FORALL (i:subrange(low1,high1)): low2<=sig(i) AND sig(i)<=high2) AND
      (FORALL (i,j:subrange(low1,high1)): i/=j IMPLIES sig(i)/=sig(j)) AND
      (FORALL (i:subrange(low2,high2)): (EXISTS (j:subrange(low1,high1)): sig(j)=i) OR
        G(i)=0) AND
      (FORALL (i:subrange(low1,high1)): F(i) = G(sig(i)))
      IMPLIES
      sigma(low1,high1,F) = sigma(low2,high2,G)
      

   
  % ---- Auto-rewrites


    nn: VAR negint
    sigma_0_neg: LEMMA sigma(0,nn,F) = 0
    AUTO_REWRITE+ sigma_0_neg


    sigma_product2   : THEOREM FORALL(M: posnat, N: posnat): 
    		     	     sigma(0,M-1,F)*sigma(0,N-1,G) = 
    		     	     sigma(0, M*N-1, LAMBDA(k:nat): F( (k-mod(k,N))/N)*G(mod(k,N)))	       	  


    sigma_geometric: LEMMA FORALL (r:real):
      r/=1 AND n<=m IMPLIES
      sigma(n,m,LAMBDA (k:nat): r^k) = (r^n-r^(m+1))/(1-r)

                                                        
  END sigma_nat

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

  % Assuming TCC generated (at line 25, column 12) for  sigma[nat]
      % generated from assumption sigma.connected_domain
  IMP_sigma_TCC1: OBLIGATION
    (FORALL (x, y: nat), (z: integer): x <= z AND z <= y IMPLIES z >= 0);

  % Judgement subtype TCC generated (at line 27, column 27) for  x
      % expected type  T_high[nat]
  int_is_T_high: OBLIGATION
    FORALL (x: int): x >= 0 OR (EXISTS (j: nat): x <= j);

  % Judgement subtype TCC generated (at line 28, column 27) for  x
      % expected type  T_low[nat]
  nat_is_T_low: OBLIGATION
    FORALL (x: nat): x >= 0 OR (EXISTS (j: nat): j <= x);

  % Subtype TCC generated (at line 38, column 36) for  high + m
      % expected type  T_high[nat]
  sigma_shift_TCC1: OBLIGATION
    FORALL (high: int, m: nat):
      high + m >= 0 OR (EXISTS (j: nat): high + m <= j);

  % Subtype TCC generated (at line 42, column 31) for  low - m
      % expected type  T_low[nat]
  sigma_shift_neg_TCC1: OBLIGATION
    FORALL (low, m: nat):
      low - m >= 0 IMPLIES low - m >= 0 OR (EXISTS (j: nat): j <= low - m);

  % Subtype TCC generated (at line 42, column 37) for  high - m
      % expected type  T_high[nat]
  sigma_shift_neg_TCC2: OBLIGATION
    FORALL (high: int, low, m: nat):
      low - m >= 0 IMPLIES high - m >= 0 OR (EXISTS (j: nat): high - m <= j);

  % Subtype TCC generated (at line 44, column 63) for  n - m
      % expected type  nat
  sigma_shift_neg_TCC3: OBLIGATION
    FORALL (low, m: nat):
      low - m >= 0 IMPLIES (FORALL (n): NOT n - m < 0 IMPLIES n - m >= 0);

  % Subtype TCC generated (at line 53, column 36) for  low + i
      % expected type  T_low[nat]
  sigma_shift_i_TCC1: OBLIGATION
    FORALL (i: int, low: nat):
      0 <= low + i IMPLIES low + i >= 0 OR (EXISTS (j: nat): j <= low + i);

  % Subtype TCC generated (at line 53, column 42) for  high + i
      % expected type  T_high[nat]
  sigma_shift_i_TCC2: OBLIGATION
    FORALL (high, i: int, low: nat):
      0 <= low + i IMPLIES high + i >= 0 OR (EXISTS (j: nat): high + i <= j);

  % Subtype TCC generated (at line 55, column 73) for  n + i
      % expected type  nat
  sigma_shift_i_TCC3: OBLIGATION
    FORALL (i: int, low: nat):
      0 <= low + i IMPLIES (FORALL (n: nat): NOT n < low IMPLIES n + i >= 0);

  % Subtype TCC generated (at line 58, column 12) for  m
      % expected type  T_high[nat]
  sigma_shift_to_zero_TCC1: OBLIGATION
    FORALL (m, n: nat): n <= m IMPLIES m >= 0 OR (EXISTS (j: nat): m <= j);

  % Subtype TCC generated (at line 58, column 27) for  m - n
      % expected type  T_high[nat]
  sigma_shift_to_zero_TCC2: OBLIGATION
    FORALL (m, n: nat):
      n <= m IMPLIES m - n >= 0 OR (EXISTS (j: nat): m - n <= j);

  % Subtype TCC generated (at line 68, column 48) for  i
      % expected type  T_high[nat]
  sigma_split_ge_TCC1: OBLIGATION
    FORALL (high, i: int, low: nat):
      i <= high AND low - 1 <= i IMPLIES i >= 0 OR (EXISTS (j: nat): i <= j);

  % Subtype TCC generated (at line 68, column 62) for  i + 1
      % expected type  T_low[nat]
  sigma_split_ge_TCC2: OBLIGATION
    FORALL (high, i: int, low: nat):
      i <= high AND low - 1 <= i IMPLIES
       i + 1 >= 0 OR (EXISTS (j: nat): j <= i + 1);

  % Subtype TCC generated (at line 73, column 71) for  high + low - n
      % expected type  nat
  sigma_reverse_TCC1: OBLIGATION
    FORALL (high: int, low, n: nat):
      NOT n > high + low IMPLIES high + low - n >= 0;

  % Subtype TCC generated (at line 77, column 33) for  high1 + high2
      % expected type  T_high[nat]
  sigma_product_TCC1: OBLIGATION
    FORALL (high1, high2: int):
      high1 + high2 >= 0 OR (EXISTS (j: nat): high1 + high2 <= j);

  % Subtype TCC generated (at line 80, column 33) for  k - i
      % expected type  nat
  sigma_product_TCC2: OBLIGATION
    FORALL (high2: int, low2, k: nat, i: nat):
      NOT i < k - high2 AND NOT i > k - low2 IMPLIES k - i >= 0;

  % Subtype TCC generated (at line 86, column 45) for  i
      % expected type  nat
  sigma_bij_TCC1: OBLIGATION
    FORALL (high: int, low: nat, i: subrange(low, high)): i >= 0;

  % Subtype TCC generated (at line 87, column 71) for  j
      % expected type  nat
  sigma_bij_TCC2: OBLIGATION
    FORALL (high: int, low: nat, sig: [nat -> nat]):
      (FORALL (i: subrange(low, high)): low <= sig(i) AND sig(i) <= high)
       IMPLIES
       (FORALL (i1: subrange(low, high), j: subrange(low, high)): j >= 0);

  % Subtype TCC generated (at line 94, column 65) for  j
      % expected type  nat
  sigma_inj_TCC1: OBLIGATION
    FORALL (high1, high2: int, low1, low2: nat, sig: [nat -> nat]):
      (FORALL (i: subrange(low1, high1)): low2 <= sig(i) AND sig(i) <= high2)
       IMPLIES
       (FORALL (i1, j: subrange(low1, high1)): i1 /= j IMPLIES j >= 0);

  % Subtype TCC generated (at line 96, column 8) for  i
      % expected type  nat
  sigma_inj_TCC2: OBLIGATION
    FORALL (high1, high2: int, low1, low2: nat, sig: [nat -> nat]):
      ((FORALL (i, j: subrange(low1, high1)):
          i /= j IMPLIES sig(i) /= sig(j))
        AND
        (FORALL (i: subrange(low1, high1)):
           low2 <= sig(i) AND sig(i) <= high2))
       IMPLIES
       (FORALL (i1: subrange(low2, high2)):
          NOT (EXISTS (j: subrange(low1, high1)): sig(j) = i1) IMPLIES
           i1 >= 0);

  % Subtype TCC generated (at line 99, column 37) for  high2
      % expected type  T_high[nat]
  sigma_inj_TCC3: OBLIGATION
    FORALL (F, G: [nat -> real], high1, high2: int, low1, low2: nat,
            sig: [nat -> nat]):
      ((FORALL (i: subrange(low1, high1)):
          low2 <= sig(i) AND sig(i) <= high2)
        AND
        (FORALL (i, j: subrange(low1, high1)):
           i /= j IMPLIES sig(i) /= sig(j))
         AND
         (FORALL (i: subrange(low2, high2)):
            (EXISTS (j: subrange(low1, high1)): sig(j) = i) OR G(i) = 0)
          AND (FORALL (i: subrange(low1, high1)): F(i) = G(sig(i))))
       IMPLIES high2 >= 0 OR (EXISTS (j: nat): high2 <= j);

  % Subtype TCC generated (at line 107, column 29) for  nn
      % expected type  T_high[nat]
  sigma_0_neg_TCC1: OBLIGATION
    FORALL (nn: negint): nn >= 0 OR (EXISTS (j: nat): nn <= j);

  % Subtype TCC generated (at line 112, column 23) for  M - 1
      % expected type  T_high[nat]
  sigma_product2_TCC1: OBLIGATION
    FORALL (M: posnat): M - 1 >= 0 OR (EXISTS (j: nat): M - 1 <= j);

  % Subtype TCC generated (at line 113, column 24) for  M * N - 1
      % expected type  T_high[nat]
  sigma_product2_TCC2: OBLIGATION
    FORALL (M: posnat, N: posnat):
      M * N - 1 >= 0 OR (EXISTS (j: nat): M * N - 1 <= j);

  % Subtype TCC generated (at line 113, column 49) for  (k - mod(k, N)) / N
      % expected type  nat
  sigma_product2_TCC3: OBLIGATION
    FORALL (N: posnat, k: nat):
      integer_pred((k - mod(k, N)) / N) AND (k - mod(k, N)) / N >= 0;

  % Subtype TCC generated (at line 118, column 32) for  k
      % expected type  {i: int | r /= 0 OR i >= 0}
  sigma_geometric_TCC1: OBLIGATION
    FORALL (m, n: nat, r: real):
      r /= 1 AND n <= m IMPLIES (FORALL (k: nat): r /= 0 OR k >= 0);

  % Subtype TCC generated (at line 118, column 40) for  n
      % expected type  {i: int | r /= 0 OR i >= 0}
  sigma_geometric_TCC2: OBLIGATION
    FORALL (m, n: nat, r: real): r /= 1 AND n <= m IMPLIES r /= 0 OR n >= 0;

  % Subtype TCC generated (at line 118, column 45) for  (m + 1)
      % expected type  {i: int | r /= 0 OR i >= 0}
  sigma_geometric_TCC3: OBLIGATION
    FORALL (m, n: nat, r: real):
      r /= 1 AND n <= m IMPLIES r /= 0 OR (m + 1) >= 0;

  % Subtype TCC generated (at line 118, column 52) for  (1 - r)
      % expected type  nznum
  sigma_geometric_TCC4: OBLIGATION
    FORALL (m, n: nat, r: real): r /= 1 AND n <= m IMPLIES (1 - r) /= 0;


body:
  polynomials: THEORY
  %------------------------------------------------------------------------------
  %
  %          Anthony Narkawicz		   NASA
  %
  %          David Lester                    Manchester University
  %
  %------------------------------------------------------------------------------
  BEGIN

    IMPORTING sigma_nat
    IMPORTING factorial, % series@nth_derivatives, 
              binomial,
  	    sigma_swap[nat]

    IMPORTING real_fun_ops

    x,y,c,r,MM,A,B: VAR real
    n,m,i,j: VAR nat
    pn:  VAR posnat
    a,b: VAR sequence[real]
    lb,ub: VAR bool

    expt_plus2: LEMMA x^(i+j) = x^i*x^j

    polynomial(a,n): [real->real] = LAMBDA (x:real): 
               sigma(0,n, LAMBDA (i:nat): a(i)*(IF i = 0 THEN 1 ELSE x^i ENDIF))

    polynomial_n0: LEMMA polynomial(a,0)    = LAMBDA (x:real): a(0)
    polynomial_x0: LEMMA polynomial(a,n)(0) = a(0)
    polynomial_x1: LEMMA polynomial(a,n)(1) = sigma(0,n,a)

    polynomial_eq_a0_plus: LEMMA n>0 IMPLIES polynomial(a,n)(x) = a(0) + x*polynomial(LAMBDA (i:nat): a(i+1),n-1)(x)

    polynomial_rec: LEMMA n>0 IMPLIES polynomial(a,n)(x) = polynomial(a,n-1)(x) + a(n)*x^n


  % derivable_polynomial: LEMMA derivable(polynomial(a,n))

  % deriv_polynomial    : LEMMA deriv(polynomial(a,n))
  %                       = IF n = 0 THEN (LAMBDA (x:real): 0)
  %                         ELSE polynomial((LAMBDA (i:nat): (i+1)*a(i+1)),n-1) 
  %                         ENDIF

  % derivable_n_times_polynomial: LEMMA derivable_n_times(polynomial(b,m),n)

  % nderiv_polynomial  : LEMMA nderiv(n,polynomial(b,m))
  %           = IF n > m THEN (LAMBDA (x:real): 0)
  %             ELSE polynomial(LAMBDA (i:nat): C(i+n,n)*factorial(n)*b(i+n),m-n)
  %             ENDIF


    extend_polynomial  : LEMMA (FORALL (i:posnat): a(n+i) = 0) IMPLIES
                                     polynomial(a,n) = polynomial(a,n+m)

    sum_polynomial     : LEMMA (FORALL (i:posnat): a(n+i) = 0) AND
                               (FORALL (i:posnat): b(m+i) = 0)
           IMPLIES polynomial(a,n) + polynomial(b,m) = polynomial(a+b,max(n,m))

    sum_polynomial_eq_degree     : LEMMA 
      polynomial(a,n) + polynomial(b,n) = polynomial(a+b,n)

    sum_polynomial_eq_degree_eval: LEMMA
      polynomial(a,n)(x) + polynomial(b,n)(x) = polynomial(a+b,n)(x)

    neg_polynomial     : LEMMA - polynomial(a,n) = polynomial(-a,n)

    diff_polynomial    : LEMMA (FORALL (i:posnat): a(n+i) = 0) AND
                        (FORALL (i:posnat): b(m+i) = 0)
          IMPLIES polynomial(a,n) - polynomial(b,m) = polynomial(a-b,max(n,m))

    polynomial_sub: LEMMA polynomial(a-b,n) = polynomial(a,n)-polynomial(b,n)

    mul_x_to_n_polynomial: LEMMA   polynomial(a,n) * (LAMBDA (x:real): x^pn)
         = polynomial(LAMBDA (i:nat): IF i < pn THEN 0 ELSE a(i-pn) ENDIF,n+pn)

    first_polynomial   : LEMMA polynomial(a,pn)(x) = 
                           a(0) + x*polynomial(LAMBDA (i:nat): a(i+1),pn-1)(x)

    scal_polynomial    : LEMMA const_fun(y) * polynomial(a,n) 
                                 = polynomial(const_fun(y)*a,n)

    scal_polynomial2   : LEMMA polynomial(c*a,n)(x) = c*polynomial(a,n)(x)

    even_fs?(a:sequence[real]):bool = (FORALL (i:nat): odd?(i) => a(i) = 0)

    even_polynomial    : LEMMA even_fs?(a) IMPLIES
           polynomial(a,2*n)(x) = polynomial(LAMBDA (i:nat): a(2*i),n)(x^2)

    odd_fs?(a:sequence[real]):bool = (FORALL (i:nat): even?(i) => a(i) = 0)

    odd_polynomial: LEMMA odd_fs?(a) IMPLIES
      polynomial(a,2*n+1)(x) = x*polynomial(LAMBDA (i:nat): a(2*i+1),n)(x^2)

    alternating_fs?(a:sequence[real],n:nat):bool
       = FORALL (i:nat): 0 <= i AND i < n IMPLIES a(i)*a(i+1) < 0

    neg_even_polynomial: LEMMA even_fs?(a) IMPLIES
      polynomial(a,n)(-x) = polynomial(a,n)(x)

    abs_polynomial_le: LEMMA
      abs(polynomial(a,n)(x)) <= polynomial(LAMBDA (i:nat): abs(a(i)),n)(abs(x))

    nn_le_polynomial : LEMMA
      (FORALL (i:nat): a(i) >= 0) AND (FORALL (i:nat): b(i) >= a(i)) AND
       x >= 0 AND n <= m IMPLIES polynomial(a,n)(x) <= polynomial(b,m)(x)

    power_fs(n:nat): [nat->nat] =
      (LAMBDA (i:nat): IF i > n THEN 0 ELSE C(n,i) ENDIF)

    power_polynomial : LEMMA (LAMBDA (x:real): (1+x)^pn) 
                            = polynomial(power_fs(pn),pn)

    neg_power_fs(n:nat):[nat->int] = 
      (LAMBDA (i:nat): IF i > n THEN 0 ELSE (-1)^i * C(n,i) ENDIF)

    neg_power_polynomial: LEMMA
      (LAMBDA (x:real): (1-x)^pn) = polynomial(neg_power_fs(pn),pn)

    binomial_theorem: LEMMA
      (x+y)^n = sigma(0,n,(LAMBDA (i:nat): IF i > n THEN 0 ELSE C(n,i)*x^i*y^(n-i) ENDIF))

    power_linear(c,r,n)(i:nat): real =
      IF i > n THEN 0 ELSE r^i*c^(n-i)*C(n,i) ENDIF

    power_linear_polynomial: LEMMA FORALL (k:nat): k>=n IMPLIES
      (c+r*x)^n = polynomial(power_linear(c,r,n),k)(x)

    polynomial_prod(a,n,b,m)(i:nat): real = sigma(max(i-m,0),n,LAMBDA (k:nat): IF k<=i THEN a(k)*b(i-k) ELSE 0 ENDIF)

    polynomial_prod_def: LEMMA
      polynomial(a,n)(x)*polynomial(b,m)(x) = polynomial(polynomial_prod(a,n,b,m),n+m)(x)

    % Added May 2010

    poly_shift(a,n)(c): sequence[real] =
      (LAMBDA (j:nat): sigma(j,n,(LAMBDA (i:nat): If (i<j OR i>n) THEN 0 ELSE a(i)*C(i,j)*c^(i-j) ENDIF)))

    poly_shift_id: LEMMA
      polynomial(a,n)(x+c) = polynomial(poly_shift(a,n)(c),n)(x)

    % Added March 2012

    poly_scal(a,n,c): sequence[real] =
      (LAMBDA (j:nat): c^j*a(j))

    poly_scal_def: LEMMA
      polynomial(a,n)(c*x) = polynomial(poly_scal(a,n,c),n)(x)

    % Added Dec 2012

    poly_eq_le_degree: LEMMA
      (FORALL (ii:nat): ii<=n IMPLIES a(ii) = b(ii))
      IMPLIES
      polynomial(a,n)(x) = polynomial(b,n)(x)

    poly_reduce_degree: LEMMA
      m<=n AND
      (FORALL (ii:nat): ii>m AND ii<=n IMPLIES a(ii)=0)
      IMPLIES
      polynomial(a,n)(x) = polynomial(a,m)(x)

    poly_eq: LEMMA
      (FORALL (ii:nat): ii>min(n,m) IMPLIES 
        (ii<=n IMPLIES a(ii)=0) AND (ii<=m IMPLIES b(ii)=0)) AND
      (FORALL (ii:nat): ii<=min(n,m) IMPLIES a(ii)=b(ii))
      IMPLIES
      polynomial(a,n)(x) = polynomial(b,m)(x)

    %poly_translate_rat(a,n)(A,B,C,D:real): =

    prop_extends_monomial: LEMMA
      LET eventzero = (LAMBDA (ab:sequence[real]): EXISTS (kk:nat): FORALL (mm:nat):
                            mm>kk IMPLIES ab(mm) = 0)
      IN
      FORALL (P:[sequence[real]->bool]):
      (FORALL (j:nat,ar:real): P(LAMBDA (i:nat): IF i = j THEN ar ELSE 0 ENDIF))
      AND
      (FORALL (a,b): P(a) AND P(b) IMPLIES P(a+b))
      IMPLIES
      (FORALL (a): eventzero(a) IMPLIES P(a))
    

    % The next function turns a polynomial on [A,B] into a polynomial on [0,1]

    poly_translate(a,n)(A:real,B:real): sequence[real] =
      (LAMBDA (j:nat): (B-A)^j*sigma(j,n,(LAMBDA (i:nat): If (i<j OR i>n) THEN 0 ELSE a(i)*C(i,j)*A^(i-j) ENDIF)))

    poly_translate_id: LEMMA FORALL (A:real,(B:real|A/=B)):polynomial(a,n)(x) = polynomial(poly_translate(a,n)(A,B),n)((x-A)/(B-A))

    polynomial_zero_factor: LEMMA
      polynomial(a,pn)(y) = 0 IMPLIES
      EXISTS (g:sequence[real]):
      (FORALL (x:real): polynomial(a,pn)(x) = (x-y)*polynomial(g,pn-1)(x))

    polynomial_zero_factor2: LEMMA
      polynomial(a,pn)(y)=0 IMPLIES
        LET g = poly_shift(LAMBDA (i): poly_shift(a,pn)(y)(i+1),pn-1)(-y) IN
          (FORALL (x:real): polynomial(a,pn)(x) = (x-y)*polynomial(g,pn-1)(x))

    polynomial_linear_divisor: LEMMA
      EXISTS (g:sequence[real]): FORALL (x:real): polynomial(a,pn)(x) = (x-y)*polynomial(g,pn-1)(x)+polynomial(a,pn)(y)
    
    polynomial_eq_coeff: LEMMA
      polynomial(a,n) = polynomial(b,n)
      IFF
      (FORALL (jj: upto(n)): a(jj) = b(jj))

    poly_eq_0_le_degree: LEMMA
      (FORALL (ii:nat): ii<=n IMPLIES a(ii)=0)
      IFF
      (FORALL (x:real): polynomial(a,n)(x)=0)

    poly_image_size: LEMMA n>0 AND
      (EXISTS (fp:[below(n+1)->real]): FORALL (i,j:below(n+1)):
        (i/=j IMPLIES fp(i)/=fp(j)) AND polynomial(a,n)(fp(i))=polynomial(a,n)(fp(j)))
      IMPLIES FORALL (k:subrange(1,n)): a(k)=0

    poly_constant_on_interval: LEMMA
      x<y AND (FORALL (r1,r2:real): x<r1 AND r1<=r2 AND r2<y IMPLIES polynomial(a,n)(r1)=polynomial(a,n)(r2))
      IMPLIES FORALL (k:subrange(1,n)): a(k)=0
        

    polynomial_div_id: LEMMA LET idf = (LAMBDA (x:real): x) IN
      idf*polynomial(a,n) = idf*polynomial(b,n) IMPLIES
      polynomial(a,n) = polynomial(b,n)

    % The next function gives the translation of a polynomial on x when x is translated
    % by the fractional linear transformation x -> (A*x + B)/(C*x + D)

    poly_translate_rat(A,B,C,D:real)(a,n)(d:nat): real =
      sigma(0,n,LAMBDA (i:nat): a(i)*sigma(0, n - i, LAMBDA (k: nat): IF (k < d - i OR k > d OR k > n - i) THEN 0
                              ELSE (C(n - i, k) * D ^ (-1 * k - i + n)) * C ^ k * ((C(i, d - k) * B ^ (k - d + i)) * A ^ (d - k)) ENDIF))

    poly_translate_rat_def: LEMMA FORALL (A,B,C,D,x:real): C*x+D/=0 IMPLIES
      (C*x+D)^n*polynomial(a,n)((A*x+B)/(C*x+D)) = polynomial(poly_translate_rat(A,B,C,D)(a,n),n)(x)

    poly_translate_rat_bounded_left: LEMMA
      x/=A IMPLIES (x-A)^n*polynomial(a,n)(((B+1)*x-B*(A+1))/(x-A)) =
        polynomial(poly_translate_rat(B+1,-B*(A+1),1,-A)(a,n),n)(x)

    poly_translate_rat_bounded_right: LEMMA
      x/=B IMPLIES (B-x)^n*polynomial(a,n)(((1-A)*x + A*(B-1))/(B-x)) =
        polynomial(poly_translate_rat(1-A,A*(B-1),-1,B)(a,n),n)(x)

    poly_translate_rat2(A,B,C,D,E,F:real)(a,n)(q:nat): real=
      sigma(0,n,LAMBDA (k:nat): a(k)*sigma(0, n, LAMBDA (i: nat): sigma(0,k,LAMBDA (j: nat):
    	       IF (q > 2 * n-k OR i < n - q OR i > -1 * q - k + 2 * n 
    	           OR j < i - n + k OR j > i OR j > k OR k>n) THEN 0
    	       ELSE C(k,j)*B^j*A^(k-j)*C(n-k,i-j)*D^(i-j)*C^(j-i-k+n)*
    		    C(n-k,-1*i-q-k+2*n)*F^(-1*i-q-k+2*n)*E^(i+q-n)
                 ENDIF)))

    poly_translate_rat2_def: LEMMA FORALL (A,B,C,D,E,F,x:real): (C*x+D)/=0 AND (E*x+F)/=0 IMPLIES
      (C*x+D)^n*(E*x+F)^n*polynomial(a,n)((A*x+B)/((C*x+D)*(E*x+F))) =
      polynomial(poly_translate_rat2(A,B,C,D,E,F)(a,n),2*n)(x)

    poly_translate_inf_pos(a,n)(A:real) : sequence[real] = 
      (LAMBDA (j:nat): IF j>n THEN 0 ELSE sigma(n-j,n,LAMBDA (i:nat): IF (i<n-j OR i>n) THEN 0 ELSE
      	    	     	    	   			   a(i)*C(i,i-n+j)*(A-1)^(i-n+j) ENDIF) ENDIF)

    poly_translate_inf_neg(a,n)(A:real) : sequence[real] = 
      (LAMBDA (j:nat): IF j>n THEN 0 ELSE sigma(n-j,n,LAMBDA (i:nat): IF (i<n-j OR i>n) THEN 0 ELSE
      	    	     	    	   			   (-1)^i*a(i)*C(i,i-n+j)*(-A-1)^(i-n+j) ENDIF) ENDIF)

    poly_translate_inf_pos_def: LEMMA x/=0 IMPLIES x^n*polynomial(a,n)((1+x*(A-1))/x) = polynomial(poly_translate_inf_pos(a,n)(A),n)(x)

    poly_translate_inf_pos_def_rev: LEMMA x/=A-1 IMPLIES polynomial(a,n)(x) = (x-A+1)^n*polynomial(poly_translate_inf_pos(a,n)(A),n)(1/(x-A+1))

    poly_translate_inf_neg_def: LEMMA x/=0 IMPLIES x^n*polynomial(a,n)((-1-x*(-A-1))/x) = polynomial(poly_translate_inf_neg(a,n)(A),n)(x)



    poly_translate_inf_neg_def_rev: LEMMA x/=A+1 IMPLIES polynomial(a,n)(x) = (A+1-x)^n*polynomial(poly_translate_inf_neg(a,n)(A),n)(1/(A+1-x))

    rel : VAR [[real,real]->bool]

    poly_translate_inf_pos_rel: LEMMA ((rel = (<=)) OR (rel = (<)) OR (rel = (>=)) OR (rel = (>)))
    			      IMPLIES
  			      ((FORALL (x:real): x>=A IMPLIES rel(polynomial(a,n)(x),0))
  			       IFF
  			       (FORALL (x:real): 0<x AND x<=1 IMPLIES rel(polynomial(poly_translate_inf_pos(a,n)(A),n)(x),0)))

    poly_translate_inf_neg_rel: LEMMA ((rel = (<=)) OR (rel = (<)) OR (rel = (>=)) OR (rel = (>)))
    			      IMPLIES
  			      ((FORALL (x:real): x<=A IMPLIES rel(polynomial(a,n)(x),0))
  			       IFF
  			       (FORALL (x:real): 0<x AND x<=1 IMPLIES rel(polynomial(poly_translate_inf_neg(a,n)(A),n)(x),0)))

    %%% Special Derivatives: Derivatives of Polynomials. This does not import analysis. %%%

    poly_deriv(a)(n): real = (n+1)*a(n+1)

    poly_deriv_plus: LEMMA
      poly_deriv(a+b)(n) = poly_deriv(a)(n) + poly_deriv(b)(n)

    poly_deriv_scal: LEMMA FORALL (cc:real):
      poly_deriv(cc*a) = cc*poly_deriv(a)

    poly_deriv_minus: LEMMA
      poly_deriv(a-b)(n) = poly_deriv(a)(n) - poly_deriv(b)(n)

    poly_deriv_sub: LEMMA
      poly_deriv(a-b) = poly_deriv(a) - poly_deriv(b)

    poly_deriv_plus_eval: LEMMA
      polynomial(poly_deriv(a+b),n) = polynomial(poly_deriv(a),n) + polynomial(poly_deriv(b),n)

    poly_eq_deriv_plus: LEMMA
      n > 0 IMPLIES
      EXISTS (nseq:[nat->nat],pseq:[nat->sequence[real]]):
          FORALL (h:real,x): polynomial(a,n)(x+h) = polynomial(a,n)(x)+ h*polynomial(poly_deriv(a),n-1)(x) + h^2*polynomial(LAMBDA (ii:nat): polynomial(pseq(ii),nseq(ii))(h),n-1)(x)

    poly_deriv_const: LEMMA
      poly_deriv(c*a) = c*poly_deriv(a)

    %%% deriv properties

    poly_product_rule: LEMMA n>0 AND m>0 IMPLIES
      polynomial(poly_deriv(polynomial_prod(a,n,b,m)),n+m-1)(x) =
      polynomial(a,n)(x)*polynomial(poly_deriv(b),m-1)(x) +
      polynomial(poly_deriv(a),n-1)(x)*polynomial(b,m)(x)

    deriv_power_linear: LEMMA
      poly_deriv(power_linear(c,r,n)) =
      r*n*power_linear(c,r,max(n-1,0))

    %%% n derivatives

    poly_n_deriv(a,n)(i): real = C(n+i,n)*factorial(n)*a(n+i)

    poly_n_deriv_def: LEMMA
      poly_n_deriv(a,0) = a AND
      poly_n_deriv(a,1) = poly_deriv(a) AND
      FORALL (n): poly_deriv(poly_n_deriv(a,n)) = poly_n_deriv(a,n+1)

    poly_n_deriv_0: LEMMA m>=n IMPLIES
      polynomial(poly_n_deriv(a,n),m)(0) = factorial(n)*a(n)


    %%% Polynomials are continuous

    poly_continuous: LEMMA FORALL (x:real,epsil:posreal): EXISTS (delta:posreal):
      FORALL (y:real): abs(x-y)<=delta IMPLIES abs(polynomial(a,n)(x)-polynomial(a,n)(y)) < epsil

    %%% Polys attain maximum

    poly_attains_maximum: LEMMA
      x<=y IMPLIES EXISTS (c:real): x<=c AND c<=y AND
      FORALL (cc:real): x<=cc AND cc<=y IMPLIES polynomial(a,n)(cc)<=polynomial(a,n)(c)

    poly_attains_minimum: LEMMA
      x<=y IMPLIES EXISTS (c:real): x<=c AND c<=y AND
      FORALL (cc:real): x<=cc AND cc<=y IMPLIES polynomial(a,n)(cc)>=polynomial(a,n)(c)

    %%% increasing from derivative

    poly_strictly_increasing: LEMMA
      n > 0 AND x < y AND
      (FORALL (c): x <= c AND c <= y IMPLIES polynomial(poly_deriv(a),n-1)(c) > 0)
      IMPLIES
      polynomial(a,n)(x) < polynomial(a,n)(y)

    poly_increasing: LEMMA
      x <= y AND n > 0 AND
      (FORALL (c): x <= c AND c <= y IMPLIES polynomial(poly_deriv(a),n-1)(c) >= 0)
      IMPLIES
      polynomial(a,n)(x) <= polynomial(a,n)(y)

    poly_strictly_decreasing: LEMMA
      n > 0 AND x < y AND
      (FORALL (c): x <= c AND c <= y IMPLIES polynomial(poly_deriv(a),n-1)(c) < 0)
      IMPLIES
      polynomial(a,n)(x) > polynomial(a,n)(y)

    poly_decreasing: LEMMA
      x <= y AND n > 0 AND
      (FORALL (c): x <= c AND c <= y IMPLIES polynomial(poly_deriv(a),n-1)(c) <= 0)
      IMPLIES
      polynomial(a,n)(x) >= polynomial(a,n)(y)

    poly_intermediate_value_increasing_0: LEMMA
      x<=y AND polynomial(a,n)(x) <= 0 AND polynomial(a,n)(y)>=0 IMPLIES
      EXISTS (cc:real): x<=cc AND cc<=y AND polynomial(a,n)(cc) = 0

    poly_intermediate_value_inc: LEMMA
      x<=y AND polynomial(a,n)(x) <= c AND polynomial(a,n)(y)>=c IMPLIES
      EXISTS (cc:real): x<=cc AND cc<=y AND polynomial(a,n)(cc) = c

    poly_intermediate_value_dec: LEMMA
      x<=y AND polynomial(a,n)(x) >=c AND polynomial(a,n)(y)<=c IMPLIES
      EXISTS (cc:real): x<=cc AND cc<=y AND polynomial(a,n)(cc) = c

    %%% Polynomial mean value

    poly_Rolle: LEMMA
      x<y AND n>0 AND polynomial(a,n)(x) = polynomial(a,n)(y) IMPLIES
      EXISTS (c:real): x<c AND c<y AND polynomial(poly_deriv(a),n-1)(c)=0

    poly_mean_value: LEMMA x < y AND n > 0 IMPLIES
      EXISTS (cc:real): x<=cc AND cc<=y AND
        polynomial(poly_deriv(a),n-1)(cc) = (polynomial(a,n)(y)-polynomial(a,n)(x))/(y-x)

    %%% Integration of polynomials

    poly_integral(a,c)(n): real = IF n = 0 THEN c ELSE a(n-1)/n ENDIF

    polynomial_int(a,n,x,y): real = polynomial(poly_integral(a,0),n+1)(y)-
    			   	  polynomial(poly_integral(a,0),n+1)(x)

    polynomial_int_sum: LEMMA polynomial_int(a,n,x,y) + polynomial_int(b,n,x,y) = polynomial_int(a+b,n,x,y)

    polynomial_ftc: THEOREM n>0 IMPLIES polynomial_int(poly_deriv(a),n-1,x,y) =
    		  	  polynomial(a,n)(y) - polynomial(a,n)(x)

    antideriv_power_linear: LEMMA r/=0 IMPLIES
      poly_deriv(1/r*1/(n+1)*power_linear(c,r,n+1)) =
      power_linear(c,r,n)

    poly_local_max_deriv: LEMMA FORALL (epsil:posreal):
      n>0 AND (FORALL (y): abs(x-y)<epsil IMPLIES
        polynomial(a,n)(y)<=polynomial(a,n)(x))
      IMPLIES polynomial(poly_deriv(a),n-1)(x)=0

    poly_local_min_deriv: LEMMA FORALL (epsil:posreal):
      n>0 AND (FORALL (y): abs(x-y)<epsil IMPLIES
        polynomial(a,n)(y)>=polynomial(a,n)(x))
      IMPLIES polynomial(poly_deriv(a),n-1)(x)=0

    %%% Integration by Parts

    polynomial_integration_by_parts: LEMMA % int u*dv = u*v - int du*v
      n>0 AND m>0 IMPLIES
      polynomial_int(polynomial_prod(a,n,poly_deriv(b),m-1),n+m-1,x,y) =
      (polynomial(a,n)(y)*polynomial(b,m)(y) - polynomial(a,n)(x)*polynomial(b,m)(x)) - polynomial_int(polynomial_prod(poly_deriv(a),n-1,b,m),n+m-1,x,y)


    %%% Taylor Series

    poly_maclaurin: LEMMA FORALL (k:nat,br:real): k>=n AND n>0 AND br>0 AND
      (FORALL (ii:nat): ii>k IMPLIES a(ii) = 0)
      IMPLIES
      EXISTS (c:real): 0<=c AND c<=br AND
      LET fk = polynomial(a,k),
      	fn1 = polynomial(a,n-1) IN
        fk(br) = fn1(br) + (1/factorial(n))*polynomial(poly_n_deriv(a,n),k-n)(c)*br^n

    % Expansion point is y

    % n is the power to go to in the expansion and k is the actual degree of the polynomial

    taylor_poly(a,(k:nat),n,(rr:real))(i:nat): real = 
    	sigma(i,n,LAMBDA (d:nat): 
  		IF i<=d AND d<=k THEN 
  		  (polynomial(poly_n_deriv(a,d),k-d)(rr)/factorial(d))*C(d,i)*(-rr)^(d-i) 
  		ELSE 0 ENDIF)

    taylor_poly_def: LEMMA FORALL (k:nat,rr:real): polynomial(taylor_poly(a,k,0,rr),k)(x) = polynomial(a,k)(rr) AND
    		     FORALL (n): n<k IMPLIES polynomial(taylor_poly(a,k,n+1,rr),k)(x) = 
  		     	    	 polynomial(taylor_poly(a,k,n,rr),k)(x)+
  				 (polynomial(poly_n_deriv(a,n+1),k-n-1)(rr)/factorial(n+1))*(x-rr)^(n+1)

    poly_taylor: LEMMA FORALL (k:nat): k>=n AND n>0 IMPLIES
      EXISTS (c:real): ((y<=c AND c<=x) OR (x<=c AND c<=y)) AND
      LET fk = polynomial(a,k),
      	fn1 = polynomial(taylor_poly(a,k,n-1,y),n-1) IN
        fk(x) = fn1(x) + (1/factorial(n))*polynomial(poly_n_deriv(a,n),k-n)(c)*(x-y)^n




  END polynomials

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

  % Assuming TCC generated (at line 14, column 5) for  sigma_swap[nat]
      % generated from assumption sigma_swap.connected_domain
  IMP_sigma_swap_TCC1: OBLIGATION
    (FORALL (x, y: nat), (z: integer): x <= z AND z <= y IMPLIES z >= 0);

  % Subtype TCC generated (at line 24, column 23) for  (i + j)
      % expected type  {i: int | x /= 0 OR i >= 0}
  expt_plus2_TCC1: OBLIGATION
    FORALL (i, j: nat, x: real): x /= 0 OR (i + j) >= 0;

  % Subtype TCC generated (at line 24, column 32) for  i
      % expected type  {i: int | x /= 0 OR i >= 0}
  expt_plus2_TCC2: OBLIGATION FORALL (i: nat, x: real): x /= 0 OR i >= 0;

  % Subtype TCC generated (at line 27, column 21) for  n
      % expected type  T_high[nat]
  polynomial_TCC1: OBLIGATION
    FORALL (n: nat): n >= 0 OR (EXISTS (j: nat): n <= j);

  % Subtype TCC generated (at line 33, column 107) for  n - 1
      % expected type  nat
  polynomial_eq_a0_plus_TCC1: OBLIGATION
    FORALL (n: nat): n > 0 IMPLIES n - 1 >= 0;

  % Subtype TCC generated (at line 74, column 71) for  pn
      % expected type  {i: int | x /= 0 OR i >= 0}
  mul_x_to_n_polynomial_TCC1: OBLIGATION
    FORALL (pn: posnat, x: real): x /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 75, column 60) for  i - pn
      % expected type  nat
  mul_x_to_n_polynomial_TCC2: OBLIGATION
    FORALL (pn: posnat, i: nat): NOT i < pn IMPLIES i - pn >= 0;

  % Subtype TCC generated (at line 78, column 68) for  pn - 1
      % expected type  nat
  first_polynomial_TCC1: OBLIGATION FORALL (pn: posnat): pn - 1 >= 0;

  % Subtype TCC generated (at line 88, column 71) for  2
      % expected type  {i: int | x /= 0 OR i >= 0}
  even_polynomial_TCC1: OBLIGATION
    FORALL (a: sequence[real], x: real): even_fs?(a) IMPLIES x /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 93, column 72) for  2
      % expected type  {i: int | x /= 0 OR i >= 0}
  odd_polynomial_TCC1: OBLIGATION
    FORALL (a: sequence[real], x: real): odd_fs?(a) IMPLIES x /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 109, column 46) for  i
      % expected type  {i: nat | i <= n}
  power_fs_TCC1: OBLIGATION FORALL (n, i: nat): NOT i > n IMPLIES i <= n;

  % Subtype TCC generated (at line 111, column 51) for  pn
      % expected type  {i: int | (1 + x) /= 0 OR i >= 0}
  power_polynomial_TCC1: OBLIGATION
    FORALL (pn: posnat, x: real): (1 + x) /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 118, column 28) for  pn
      % expected type  {i: int | (1 - x) /= 0 OR i >= 0}
  neg_power_polynomial_TCC1: OBLIGATION
    FORALL (pn: posnat, x: real): (1 - x) /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 121, column 10) for  n
      % expected type  {i: int | (x + y) /= 0 OR i >= 0}
  binomial_theorem_TCC1: OBLIGATION
    FORALL (n: nat, x, y: real): (x + y) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 121, column 76) for  (n - i)
      % expected type  {i: int | y /= 0 OR i >= 0}
  binomial_theorem_TCC2: OBLIGATION
    FORALL (n: nat, y: real, i: nat):
      NOT i > n IMPLIES y /= 0 OR (n - i) >= 0;

  % Subtype TCC generated (at line 127, column 12) for  n
      % expected type  {i: int | (c + r * x) /= 0 OR i >= 0}
  power_linear_polynomial_TCC1: OBLIGATION
    FORALL (c: real, n: nat, r, x: real, k: nat):
      k >= n IMPLIES (c + r * x) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 129, column 48) for  max(i - m, 0)
      % expected type  T_low[nat]
  polynomial_prod_TCC1: OBLIGATION
    FORALL (m: nat, i: nat):
      max(i - m, 0) >= 0 OR (EXISTS (j: nat): j <= max(i - m, 0));

  % Subtype TCC generated (at line 129, column 97) for  i - k
      % expected type  nat
  polynomial_prod_TCC2: OBLIGATION
    FORALL (i: nat, k: nat): k <= i IMPLIES i - k >= 0;

  % Subtype TCC generated (at line 137, column 85) for  j
      % expected type  {i_1: nat | i_1 <= i}
  poly_shift_TCC1: OBLIGATION
    FORALL (n: nat, j: nat, i: nat): NOT i < j AND NOT i > n IMPLIES j <= i;

  % Subtype TCC generated (at line 137, column 91) for  (i - j)
      % expected type  {i: int | c /= 0 OR i >= 0}
  poly_shift_TCC2: OBLIGATION
    FORALL (n: nat, c: real, j: nat, i: nat):
      NOT i < j AND NOT i > n IMPLIES c /= 0 OR (i - j) >= 0;

  % Subtype TCC generated (at line 187, column 27) for  j
      % expected type  {i: int | (B - A) /= 0 OR i >= 0}
  poly_translate_TCC1: OBLIGATION
    FORALL (A, B: real, j: nat): (B - A) /= 0 OR j >= 0;

  % Subtype TCC generated (at line 189, column 124) for  (B - A)
      % expected type  nznum
  poly_translate_id_TCC1: OBLIGATION
    FORALL (A: real, (B: real | A /= B)): (B - A) /= 0;

  % Subtype TCC generated (at line 232, column 44) for  n - i
      % expected type  T_high[nat]
  poly_translate_rat_TCC1: OBLIGATION
    FORALL (n: nat, i: nat): n - i >= 0 OR (EXISTS (j: nat): n - i <= j);

  % Subtype TCC generated (at line 233, column 36) for  n - i
      % expected type  nat
  poly_translate_rat_TCC2: OBLIGATION
    FORALL (n: nat, d: nat, i: nat, k: nat):
      NOT k < d - i AND NOT k > d AND NOT k > n - i IMPLIES n - i >= 0;

  % Subtype TCC generated (at line 233, column 43) for  k
      % expected type  {i_1: nat | i_1 <= n - i}
  poly_translate_rat_TCC3: OBLIGATION
    FORALL (n: nat, d: nat, i: nat, k: nat):
      NOT k < d - i AND NOT k > d AND NOT k > n - i IMPLIES k <= n - i;

  % Subtype TCC generated (at line 233, column 53) for  (-1 * k - i + n)
      % expected type  {i: int | D /= 0 OR i >= 0}
  poly_translate_rat_TCC4: OBLIGATION
    FORALL (D: real, n: nat, d: nat, i: nat, k: nat):
      NOT k < d - i AND NOT k > d AND NOT k > n - i IMPLIES
       D /= 0 OR (-1 * k - i + n) >= 0;

  % Subtype TCC generated (at line 233, column 76) for  k
      % expected type  {i: int | C /= 0 OR i >= 0}
  poly_translate_rat_TCC5: OBLIGATION
    FORALL (C: real, n: nat, d: nat, i: nat, k: nat):
      NOT k < d - i AND NOT k > d AND NOT k > n - i IMPLIES C /= 0 OR k >= 0;

  % Subtype TCC generated (at line 233, column 87) for  d - k
      % expected type  {i_1: nat | i_1 <= i}
  poly_translate_rat_TCC6: OBLIGATION
    FORALL (n: nat, d: nat, i: nat, k: nat):
      NOT k < d - i AND NOT k > d AND NOT k > n - i IMPLIES
       d - k >= 0 AND d - k <= i;

  % Subtype TCC generated (at line 233, column 101) for  (k - d + i)
      % expected type  {i: int | B /= 0 OR i >= 0}
  poly_translate_rat_TCC7: OBLIGATION
    FORALL (B: real, n: nat, d: nat, i: nat, k: nat):
      NOT k < d - i AND NOT k > d AND NOT k > n - i IMPLIES
       B /= 0 OR (k - d + i) >= 0;

  % Subtype TCC generated (at line 233, column 120) for  (d - k)
      % expected type  {i: int | A /= 0 OR i >= 0}
  poly_translate_rat_TCC8: OBLIGATION
    FORALL (A: real, n: nat, d: nat, i: nat, k: nat):
      NOT k < d - i AND NOT k > d AND NOT k > n - i IMPLIES
       A /= 0 OR (d - k) >= 0;

  % Subtype TCC generated (at line 236, column 12) for  n
      % expected type  {i: int | NOT D + C * x = 0 OR i >= 0}
  poly_translate_rat_def_TCC1: OBLIGATION
    FORALL (n: nat, C, D, x: real):
      C * x + D /= 0 IMPLIES NOT D + C * x = 0 OR n >= 0;

  % Subtype TCC generated (at line 239, column 60) for  (x - A)
      % expected type  nznum
  poly_translate_rat_bounded_left_TCC1: OBLIGATION
    FORALL (A, x: real): x /= A IMPLIES (x - A) /= 0;

  % Subtype TCC generated (at line 243, column 23) for  n
      % expected type  {i: int | (B - x) /= 0 OR i >= 0}
  poly_translate_rat_bounded_right_TCC1: OBLIGATION
    FORALL (B: real, n: nat, x: real): x /= B IMPLIES (B - x) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 243, column 62) for  (B - x)
      % expected type  nznum
  poly_translate_rat_bounded_right_TCC2: OBLIGATION
    FORALL (B, x: real): x /= B IMPLIES (B - x) /= 0;

  % Subtype TCC generated (at line 250, column 19) for  j
      % expected type  {i: nat | i <= k}
  poly_translate_rat2_TCC1: OBLIGATION
    FORALL (n: nat, q: nat, k: nat, i: nat, j: nat):
           NOT q > 2 * n - k AND NOT i < n - q AND NOT i > -1 * q - k + 2 * n
       AND NOT j < i - n + k AND NOT j > i AND NOT j > k AND NOT k > n
       IMPLIES j <= k;

  % Subtype TCC generated (at line 250, column 24) for  j
      % expected type  {i: int | B /= 0 OR i >= 0}
  poly_translate_rat2_TCC2: OBLIGATION
    FORALL (B: real, n: nat, q: nat, k: nat, i: nat, j: nat):
           NOT q > 2 * n - k AND NOT i < n - q AND NOT i > -1 * q - k + 2 * n
       AND NOT j < i - n + k AND NOT j > i AND NOT j > k AND NOT k > n
       IMPLIES B /= 0 OR j >= 0;

  % Subtype TCC generated (at line 250, column 29) for  (k - j)
      % expected type  {i: int | A /= 0 OR i >= 0}
  poly_translate_rat2_TCC3: OBLIGATION
    FORALL (A: real, n: nat, q: nat, k: nat, i: nat, j: nat):
           NOT q > 2 * n - k AND NOT i < n - q AND NOT i > -1 * q - k + 2 * n
       AND NOT j < i - n + k AND NOT j > i AND NOT j > k AND NOT k > n
       IMPLIES A /= 0 OR (k - j) >= 0;

  % Subtype TCC generated (at line 250, column 36) for  n - k
      % expected type  nat
  poly_translate_rat2_TCC4: OBLIGATION
    FORALL (n: nat, q: nat, k: nat, i: nat, j: nat):
           NOT q > 2 * n - k AND NOT i < n - q AND NOT i > -1 * q - k + 2 * n
       AND NOT j < i - n + k AND NOT j > i AND NOT j > k AND NOT k > n
       IMPLIES n - k >= 0;

  % Subtype TCC generated (at line 250, column 40) for  i - j
      % expected type  {i: nat | i <= n - k}
  poly_translate_rat2_TCC5: OBLIGATION
    FORALL (n: nat, q: nat, k: nat, i: nat, j: nat):
           NOT q > 2 * n - k AND NOT i < n - q AND NOT i > -1 * q - k + 2 * n
       AND NOT j < i - n + k AND NOT j > i AND NOT j > k AND NOT k > n
       IMPLIES i - j >= 0 AND i - j <= n - k;

  % Subtype TCC generated (at line 250, column 48) for  (i - j)
      % expected type  {i: int | D /= 0 OR i >= 0}
  poly_translate_rat2_TCC6: OBLIGATION
    FORALL (D: real, n: nat, q: nat, k: nat, i: nat, j: nat):
           NOT q > 2 * n - k AND NOT i < n - q AND NOT i > -1 * q - k + 2 * n
       AND NOT j < i - n + k AND NOT j > i AND NOT j > k AND NOT k > n
       IMPLIES D /= 0 OR (i - j) >= 0;

  % Subtype TCC generated (at line 250, column 56) for  (j - i - k + n)
      % expected type  {i: int | C /= 0 OR i >= 0}
  poly_translate_rat2_TCC7: OBLIGATION
    FORALL (C: real, n: nat, q: nat, k: nat, i: nat, j: nat):
           NOT q > 2 * n - k AND NOT i < n - q AND NOT i > -1 * q - k + 2 * n
       AND NOT j < i - n + k AND NOT j > i AND NOT j > k AND NOT k > n
       IMPLIES C /= 0 OR (j - i - k + n) >= 0;

  % Subtype TCC generated (at line 251, column 14) for  -1 * i - q - k + 2 * n
      % expected type  {i: nat | i <= n - k}
  poly_translate_rat2_TCC8: OBLIGATION
    FORALL (n: nat, q: nat, k: nat, i: nat, j: nat):
           NOT q > 2 * n - k AND NOT i < n - q AND NOT i > -1 * q - k + 2 * n
       AND NOT j < i - n + k AND NOT j > i AND NOT j > k AND NOT k > n
       IMPLIES
       -1 * i - q - k + 2 * n >= 0 AND -1 * i - q - k + 2 * n <= n - k;

  % Subtype TCC generated (at line 251, column 31) for
      % (-1 * i - q - k + 2 * n)
      % expected type  {i: int | F /= 0 OR i >= 0}
  poly_translate_rat2_TCC9: OBLIGATION
    FORALL (F: real, n: nat, q: nat, k: nat, i: nat, j: nat):
           NOT q > 2 * n - k AND NOT i < n - q AND NOT i > -1 * q - k + 2 * n
       AND NOT j < i - n + k AND NOT j > i AND NOT j > k AND NOT k > n
       IMPLIES F /= 0 OR (-1 * i - q - k + 2 * n) >= 0;

  % Subtype TCC generated (at line 251, column 48) for  (i + q - n)
      % expected type  {i: int | E /= 0 OR i >= 0}
  poly_translate_rat2_TCC10: OBLIGATION
    FORALL (E: real, n: nat, q: nat, k: nat, i: nat, j: nat):
           NOT q > 2 * n - k AND NOT i < n - q AND NOT i > -1 * q - k + 2 * n
       AND NOT j < i - n + k AND NOT j > i AND NOT j > k AND NOT k > n
       IMPLIES E /= 0 OR (i + q - n) >= 0;

  % Subtype TCC generated (at line 255, column 22) for  n
      % expected type  {i: int | NOT F + E * x = 0 OR i >= 0}
  poly_translate_rat2_def_TCC1: OBLIGATION
    FORALL (n: nat, C, D, E, F, x: real):
      (C * x + D) /= 0 AND (E * x + F) /= 0 IMPLIES
       NOT F + E * x = 0 OR n >= 0;

  % Subtype TCC generated (at line 255, column 49) for
      % ((C * x + D) * (E * x + F))
      % expected type  nznum
  poly_translate_rat2_def_TCC2: OBLIGATION
    FORALL (C, D, E, F, x: real):
      (C * x + D) /= 0 AND (E * x + F) /= 0 IMPLIES
       ((C * x + D) * (E * x + F)) /= 0;

  % Subtype TCC generated (at line 259, column 46) for  n - j
      % expected type  T_low[nat]
  poly_translate_inf_pos_TCC1: OBLIGATION
    FORALL (n: nat, j: nat):
      NOT j > n IMPLIES n - j >= 0 OR (EXISTS (j_1: nat): j_1 <= n - j);

  % Subtype TCC generated (at line 260, column 39) for  i - n + j
      % expected type  {i_1: nat | i_1 <= i}
  poly_translate_inf_pos_TCC2: OBLIGATION
    FORALL (n: nat, j: nat):
      NOT j > n IMPLIES
       (FORALL (i: nat):
          NOT i < n - j AND NOT i > n IMPLIES
           i - n + j >= 0 AND i - n + j <= i);

  % Subtype TCC generated (at line 260, column 53) for  (i - n + j)
      % expected type  {i: int | (A - 1) /= 0 OR i >= 0}
  poly_translate_inf_pos_TCC3: OBLIGATION
    FORALL (n: nat, A: real, j: nat):
      NOT j > n IMPLIES
       (FORALL (i: nat):
          NOT i < n - j AND NOT i > n IMPLIES
           (A - 1) /= 0 OR (i - n + j) >= 0);

  % Subtype TCC generated (at line 264, column 61) for  (i - n + j)
      % expected type  {i: int | (-A - 1) /= 0 OR i >= 0}
  poly_translate_inf_neg_TCC1: OBLIGATION
    FORALL (n: nat, A: real, j: nat):
      NOT j > n IMPLIES
       (FORALL (i: nat):
          NOT i < n - j AND NOT i > n IMPLIES
           (-A - 1) /= 0 OR (i - n + j) >= 0);

  % Subtype TCC generated (at line 268, column 84) for  n
      % expected type  {i: int | NOT 1 + x - A = 0 OR i >= 0}
  poly_translate_inf_pos_def_rev_TCC1: OBLIGATION
    FORALL (A: real, n: nat, x: real):
      x /= A - 1 IMPLIES NOT 1 + x - A = 0 OR n >= 0;

  % Subtype TCC generated (at line 268, column 134) for  (x - A + 1)
      % expected type  nznum
  poly_translate_inf_pos_def_rev_TCC2: OBLIGATION
    FORALL (A, x: real): x /= A - 1 IMPLIES (x - A + 1) /= 0;

  % Subtype TCC generated (at line 274, column 84) for  n
      % expected type  {i: int | NOT (1 + A - x) = 0 OR i >= 0}
  poly_translate_inf_neg_def_rev_TCC1: OBLIGATION
    FORALL (A: real, n: nat, x: real):
      x /= A + 1 IMPLIES NOT (1 + A - x) = 0 OR n >= 0;

  % Subtype TCC generated (at line 274, column 134) for  (A + 1 - x)
      % expected type  nznum
  poly_translate_inf_neg_def_rev_TCC2: OBLIGATION
    FORALL (A, x: real): x /= A + 1 IMPLIES (A + 1 - x) /= 0;

  % Subtype TCC generated (at line 312, column 109) for  2
      % expected type  {i: int | h /= 0 OR i >= 0}
  poly_eq_deriv_plus_TCC1: OBLIGATION
    FORALL (n: nat): n > 0 IMPLIES (FORALL (h: real): h /= 0 OR 2 >= 0);

  % Subtype TCC generated (at line 320, column 52) for  n + m - 1
      % expected type  nat
  poly_product_rule_TCC1: OBLIGATION
    FORALL (m, n: nat): m > 0 AND n > 0 IMPLIES n + m - 1 >= 0;

  % Subtype TCC generated (at line 321, column 48) for  m - 1
      % expected type  nat
  poly_product_rule_TCC2: OBLIGATION
    FORALL (m, n: nat): m > 0 AND n > 0 IMPLIES m - 1 >= 0;

  % Subtype TCC generated (at line 326, column 25) for  max(n - 1, 0)
      % expected type  nat
  deriv_power_linear_TCC1: OBLIGATION FORALL (n: nat): max(n - 1, 0) >= 0;

  % Subtype TCC generated (at line 330, column 37) for  n
      % expected type  {i_1: nat | i_1 <= i + n}
  poly_n_deriv_TCC1: OBLIGATION FORALL (n: nat, i: nat): n <= i + n;

  % Subtype TCC generated (at line 402, column 83) for  (y - x)
      % expected type  nznum
  poly_mean_value_TCC1: OBLIGATION
    FORALL (n: nat, x, y: real):
      n > 0 AND x < y IMPLIES
       (FORALL (cc: real): cc <= y AND x <= cc IMPLIES (y - x) /= 0);

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

  % Subtype TCC generated (at line 406, column 60) for  n
      % expected type  nznum
  poly_integral_TCC2: OBLIGATION FORALL (n: nat): NOT n = 0 IMPLIES n /= 0;

  % Subtype TCC generated (at line 446, column 71) for  k - n
      % expected type  nat
  poly_maclaurin_TCC1: OBLIGATION
    FORALL (a: sequence[real], n, k: nat, br: real):
      (k >= n AND
        n > 0 AND br > 0 AND (FORALL (ii: nat): ii > k IMPLIES a(ii) = 0))
       IMPLIES
       (FORALL (c: real):
          c <= br AND 0 <= c IMPLIES
           (FORALL (fk: [real -> real]):
              fk = polynomial(a, k) IMPLIES
               (FORALL (fn1: [real -> real]):
                  fn1 = polynomial(a, n - 1) IMPLIES k - n >= 0)));

  % Subtype TCC generated (at line 455, column 34) for  k - d
      % expected type  nat
  taylor_poly_TCC1: OBLIGATION
    FORALL ((k, i: nat), d: nat): i <= d AND d <= k IMPLIES k - d >= 0;

  % Subtype TCC generated (at line 455, column 71) for  (d - i)
      % expected type  {i: int | (-rr) /= 0 OR i >= 0}
  taylor_poly_TCC2: OBLIGATION
    FORALL ((k: nat), (rr: real), i: nat, d: nat):
      i <= d AND d <= k IMPLIES (-rr) /= 0 OR (d - i) >= 0;

  % Subtype TCC generated (at line 461, column 37) for  k - n - 1
      % expected type  nat
  taylor_poly_def_TCC1: OBLIGATION
    FORALL (a: sequence[real], x: real, k: nat, rr: real):
      polynomial(taylor_poly(a, k, 0, rr), k)(x) = polynomial(a, k)(rr)
       IMPLIES (FORALL (n: nat): n < k IMPLIES k - n - 1 >= 0);

  % Subtype TCC generated (at line 461, column 72) for  (n + 1)
      % expected type  {i: int | (x - rr) /= 0 OR i >= 0}
  taylor_poly_def_TCC2: OBLIGATION
    FORALL (a: sequence[real], x: real, k: nat, rr: real):
      polynomial(taylor_poly(a, k, 0, rr), k)(x) = polynomial(a, k)(rr)
       IMPLIES (FORALL (n: nat): n < k IMPLIES (x - rr) /= 0 OR (n + 1) >= 0);

  % Subtype TCC generated (at line 467, column 69) for  k - n
      % expected type  nat
  poly_taylor_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat, x, y: real, k: nat):
      k >= n AND n > 0 IMPLIES
       (FORALL (c: real):
          ((y <= c AND c <= x) OR (x <= c AND c <= y)) IMPLIES
           (FORALL (fk: [real -> real]):
              fk = polynomial(a, k) IMPLIES
               (FORALL (fn1: [real -> real]):
                  fn1 = polynomial(taylor_poly(a, k, n - 1, y), n - 1)
                   IMPLIES k - n >= 0)));

  % Subtype TCC generated (at line 467, column 83) for  n
      % expected type  {i: int | (x - y) /= 0 OR i >= 0}
  poly_taylor_TCC2: OBLIGATION
    FORALL (a: sequence[real], n: nat, x, y: real, k: nat):
      k >= n AND n > 0 IMPLIES
       (FORALL (c: real):
          ((y <= c AND c <= x) OR (x <= c AND c <= y)) IMPLIES
           (FORALL (fk: [real -> real]):
              fk = polynomial(a, k) IMPLIES
               (FORALL (fn1: [real -> real]):
                  fn1 = polynomial(taylor_poly(a, k, n - 1, y), n - 1)
                   IMPLIES (x - y) /= 0 OR n >= 0)));


body:
  binomial_identities: THEORY
  %------------------------------------------------------------------------------
  %
  % Author: Anthony Narkawicz		NASA Langley
  % 
  %------------------------------------------------------------------------------
  BEGIN

    IMPORTING polynomials,
    	    binomial

    x,y: VAR real
    n,m,i,j,r,k,s,N,p: VAR nat
    pn:  VAR posnat
    a,b: VAR sequence[real]
    nge2: VAR {k:posnat| k>=2}

    % Many of these identities are taken from Concrete Mathematics, by Graham,
    % Knuth, and Patashnik (Section 5.2) and from Combinatorial Identities by Riordan

    binom_trinomial_revision: LEMMA r>=m AND m>=k IMPLIES 
      C(r,m)*C(m,k) = C(r,k)*C(r-k,m-k)

    binom_absorption: LEMMA r>=k AND k>=1 IMPLIES 
      C(r,k) = (r/k)*C(r-1,k-1)

    binom_upper_summation: LEMMA n>=m IMPLIES 
      sigma(m,n,LAMBDA (k:nat): IF k<m OR k>n THEN 0 ELSE C(k,m) ENDIF) = C(n+1,m+1)

    binom_parallel_summation: LEMMA 
      sigma(0,n,LAMBDA (k:nat): IF k>n THEN 0 ELSE C(r+k,k) ENDIF) = C(r+n+1,n)

    binom_vandermonde_convolution: LEMMA n>=m AND n>=p IMPLIES 
      sigma(0,m,LAMBDA (k:nat): IF k>p OR k>m or m+p-n> k THEN 0 ELSE C(n-p,m-k)*C(p,k) ENDIF) = C(n,m)

    binom_vandermonde_convolution_2: LEMMA n+p>=m IMPLIES 
      sigma(0,m,LAMBDA (k:nat): IF k>p OR k>m OR m-n>k THEN 0 ELSE C(n,m-k)*C(p,k) ENDIF) = C(n+p,m)

    binom_vandermonde_convolution_3: LEMMA n+p>=m IMPLIES 
      sigma(0,m,LAMBDA (k:nat): IF k>m OR m-k>p OR k>n THEN 0 ELSE C(n,k)*C(p,m-k) ENDIF) = C(n+p,m)

    % The next lemmas are helpful in proving theorems about Bernstein polynomials.

    binom_cross_sum: LEMMA k>=i IMPLIES 
      sigma(i,k,LAMBDA (j:nat):IF j<i OR j>k THEN 0 ELSE C(k,j)*C(j,i)*x^j*y^(k-j) ENDIF) = x^i*C(k,i)*(x+y)^(k-i)

    binom_sum_cross_sum_half: LEMMA k>=i IMPLIES 
      sigma(i,k,LAMBDA (j:nat):IF j<i OR j>k THEN 0 ELSE C(k,j)*C(j,i)*(-1)^(k-j)*(1/2^j) ENDIF) =
      (1/2^k)*C(k,i)*(-1)^(k-i)

    binom_pr1: LEMMA m>=N AND m>=i AND m<=8 IMPLIES
      sigma(max(N,i),m,LAMBDA (k:nat): IF k<max(N,i) OR k>m THEN 0 ELSE C(m-N,k-N)*C(k,i)*(-1)^(k-i)*1/2^k ENDIF) =
      sigma(0,min(N,i),LAMBDA (j:nat): IF j > min(N,i) THEN 0 ELSE C(m-j,i-j)*C(N,j)*(-1)^(N-j)*1/2^(m-j) ENDIF)

    binomial_triple_cancel: LEMMA m>=N AND m>=i AND m<=8  IMPLIES
      sigma(max(N,i),m,LAMBDA (k:nat): IF k<max(N,i) OR k>m THEN 0 ELSE C(k,N)*C(m,k)*C(k,i)*(-1)^(k-i)*1/2^k ENDIF) =
      sigma(0,min(N,i),LAMBDA (j:nat): IF j > min(N,i) THEN 0 ELSE C(m-j,i-j)*C(N,j)*C(m,N)*(-1)^(N-j)*1/2^(m-j) ENDIF)

  END binomial_identities

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

  % Subtype TCC generated (at line 22, column 8) for  m
      % expected type  {i: nat | i <= r}
  binom_trinomial_revision_TCC1: OBLIGATION
    FORALL (k, m, r: nat): m >= k AND r >= m IMPLIES m <= r;

  % Subtype TCC generated (at line 22, column 15) for  k
      % expected type  {i: nat | i <= m}
  binom_trinomial_revision_TCC2: OBLIGATION
    FORALL (k, m, r: nat): m >= k AND r >= m IMPLIES k <= m;

  % Subtype TCC generated (at line 22, column 24) for  k
      % expected type  {i: nat | i <= r}
  binom_trinomial_revision_TCC3: OBLIGATION
    FORALL (k, m, r: nat): m >= k AND r >= m IMPLIES k <= r;

  % Subtype TCC generated (at line 22, column 29) for  r - k
      % expected type  nat
  binom_trinomial_revision_TCC4: OBLIGATION
    FORALL (k, m, r: nat): m >= k AND r >= m IMPLIES r - k >= 0;

  % Subtype TCC generated (at line 22, column 33) for  m - k
      % expected type  {i: nat | i <= r - k}
  binom_trinomial_revision_TCC5: OBLIGATION
    FORALL (k, m, r: nat):
      m >= k AND r >= m IMPLIES m - k >= 0 AND m - k <= r - k;

  % Subtype TCC generated (at line 25, column 8) for  k
      % expected type  {i: nat | i <= r}
  binom_absorption_TCC1: OBLIGATION
    FORALL (k, r: nat): k >= 1 AND r >= k IMPLIES k <= r;

  % Subtype TCC generated (at line 25, column 16) for  k
      % expected type  nznum
  binom_absorption_TCC2: OBLIGATION
    FORALL (k, r: nat): k >= 1 AND r >= k IMPLIES k /= 0;

  % Subtype TCC generated (at line 25, column 21) for  r - 1
      % expected type  nat
  binom_absorption_TCC3: OBLIGATION
    FORALL (k, r: nat): k >= 1 AND r >= k IMPLIES r - 1 >= 0;

  % Subtype TCC generated (at line 25, column 25) for  k - 1
      % expected type  {i: nat | i <= r - 1}
  binom_absorption_TCC4: OBLIGATION
    FORALL (k, r: nat):
      k >= 1 AND r >= k IMPLIES k - 1 >= 0 AND k - 1 <= r - 1;

  % Subtype TCC generated (at line 28, column 12) for  n
      % expected type  T_high[nat]
  binom_upper_summation_TCC1: OBLIGATION
    FORALL (m, n: nat): n >= m IMPLIES n >= 0 OR (EXISTS (j: nat): n <= j);

  % Subtype TCC generated (at line 28, column 60) for  m
      % expected type  {i: nat | i <= k}
  binom_upper_summation_TCC2: OBLIGATION
    FORALL (m, n: nat):
      n >= m IMPLIES
       (FORALL (k: nat): NOT k < m AND NOT k > n IMPLIES m <= k);

  % Subtype TCC generated (at line 28, column 78) for  m + 1
      % expected type  {i: nat | i <= 1 + n}
  binom_upper_summation_TCC3: OBLIGATION
    FORALL (m, n: nat): n >= m IMPLIES m + 1 <= 1 + n;

  % Subtype TCC generated (at line 31, column 12) for  n
      % expected type  T_high[nat]
  binom_parallel_summation_TCC1: OBLIGATION
    FORALL (n: nat): n >= 0 OR (EXISTS (j: nat): n <= j);

  % Subtype TCC generated (at line 31, column 55) for  k
      % expected type  {i: nat | i <= k + r}
  binom_parallel_summation_TCC2: OBLIGATION
    FORALL (n, r, k: nat): NOT k > n IMPLIES k <= k + r;

  % Subtype TCC generated (at line 31, column 75) for  n
      % expected type  {i: nat | i <= 1 + n + r}
  binom_parallel_summation_TCC3: OBLIGATION
    FORALL (n, r: nat): n <= 1 + n + r;

  % Subtype TCC generated (at line 34, column 12) for  m
      % expected type  T_high[nat]
  binom_vandermonde_convolution_TCC1: OBLIGATION
    FORALL (m, n, p: nat):
      n >= p AND n >= m IMPLIES m >= 0 OR (EXISTS (j: nat): m <= j);

  % Subtype TCC generated (at line 34, column 70) for  n - p
      % expected type  nat
  binom_vandermonde_convolution_TCC2: OBLIGATION
    FORALL (m, n, p: nat):
      n >= p AND n >= m IMPLIES
       (FORALL (k: nat):
          NOT k > p AND NOT k > m AND NOT m + p - n > k IMPLIES n - p >= 0);

  % Subtype TCC generated (at line 34, column 74) for  m - k
      % expected type  {i: nat | i <= n - p}
  binom_vandermonde_convolution_TCC3: OBLIGATION
    FORALL (m, n, p: nat):
      n >= p AND n >= m IMPLIES
       (FORALL (k: nat):
          NOT k > p AND NOT k > m AND NOT m + p - n > k IMPLIES
           m - k >= 0 AND m - k <= n - p);

  % Subtype TCC generated (at line 34, column 83) for  k
      % expected type  {i: nat | i <= p}
  binom_vandermonde_convolution_TCC4: OBLIGATION
    FORALL (m, n, p: nat):
      n >= p AND n >= m IMPLIES
       (FORALL (k: nat):
          NOT k > p AND NOT k > m AND NOT m + p - n > k IMPLIES k <= p);

  % Subtype TCC generated (at line 34, column 99) for  m
      % expected type  {i: nat | i <= n}
  binom_vandermonde_convolution_TCC5: OBLIGATION
    FORALL (m, n, p: nat): n >= p AND n >= m IMPLIES m <= n;

  % Subtype TCC generated (at line 37, column 12) for  m
      % expected type  T_high[nat]
  binom_vandermonde_convolution_2_TCC1: OBLIGATION
    FORALL (m, n, p: nat):
      n + p >= m IMPLIES m >= 0 OR (EXISTS (j: nat): m <= j);

  % Subtype TCC generated (at line 37, column 69) for  m - k
      % expected type  {i: nat | i <= n}
  binom_vandermonde_convolution_2_TCC2: OBLIGATION
    FORALL (m, n, p: nat):
      n + p >= m IMPLIES
       (FORALL (k: nat):
          NOT k > p AND NOT k > m AND NOT m - n > k IMPLIES
           m - k >= 0 AND m - k <= n);

  % Subtype TCC generated (at line 37, column 78) for  k
      % expected type  {i: nat | i <= p}
  binom_vandermonde_convolution_2_TCC3: OBLIGATION
    FORALL (m, n, p: nat):
      n + p >= m IMPLIES
       (FORALL (k: nat):
          NOT k > p AND NOT k > m AND NOT m - n > k IMPLIES k <= p);

  % Subtype TCC generated (at line 37, column 96) for  m
      % expected type  {i: nat | i <= n + p}
  binom_vandermonde_convolution_2_TCC4: OBLIGATION
    FORALL (m, n, p: nat): n + p >= m IMPLIES m <= n + p;

  % Subtype TCC generated (at line 40, column 69) for  k
      % expected type  {i: nat | i <= n}
  binom_vandermonde_convolution_3_TCC1: OBLIGATION
    FORALL (m, n, p: nat):
      n + p >= m IMPLIES
       (FORALL (k: nat):
          NOT k > m AND NOT m - k > p AND NOT k > n IMPLIES k <= n);

  % Subtype TCC generated (at line 40, column 76) for  m - k
      % expected type  {i: nat | i <= p}
  binom_vandermonde_convolution_3_TCC2: OBLIGATION
    FORALL (m, n, p: nat):
      n + p >= m IMPLIES
       (FORALL (k: nat):
          NOT k > m AND NOT m - k > p AND NOT k > n IMPLIES
           m - k >= 0 AND m - k <= p);

  % Subtype TCC generated (at line 45, column 59) for  j
      % expected type  {i: nat | i <= k}
  binom_cross_sum_TCC1: OBLIGATION
    FORALL (i, k: nat):
      k >= i IMPLIES
       (FORALL (j: nat): NOT j < i AND NOT j > k IMPLIES j <= k);

  % Subtype TCC generated (at line 45, column 71) for  j
      % expected type  {i: int | x /= 0 OR i >= 0}
  binom_cross_sum_TCC2: OBLIGATION
    FORALL (i, k: nat, x: real):
      k >= i IMPLIES
       (FORALL (j: nat): NOT j < i AND NOT j > k IMPLIES x /= 0 OR j >= 0);

  % Subtype TCC generated (at line 45, column 76) for  (k - j)
      % expected type  {i: int | y /= 0 OR i >= 0}
  binom_cross_sum_TCC3: OBLIGATION
    FORALL (i, k: nat, y: real):
      k >= i IMPLIES
       (FORALL (j: nat):
          NOT j < i AND NOT j > k IMPLIES y /= 0 OR (k - j) >= 0);

  % Subtype TCC generated (at line 45, column 92) for  i
      % expected type  {i: int | x /= 0 OR i >= 0}
  binom_cross_sum_TCC4: OBLIGATION
    FORALL (i, k: nat, x: real): k >= i IMPLIES x /= 0 OR i >= 0;

  % Subtype TCC generated (at line 45, column 98) for  i
      % expected type  {i: nat | i <= k}
  binom_cross_sum_TCC5: OBLIGATION FORALL (i, k: nat): k >= i IMPLIES i <= k;

  % Subtype TCC generated (at line 45, column 108) for  (k - i)
      % expected type  {i: int | (x + y) /= 0 OR i >= 0}
  binom_cross_sum_TCC6: OBLIGATION
    FORALL (i, k: nat, x, y: real):
      k >= i IMPLIES (x + y) /= 0 OR (k - i) >= 0;

  % Subtype TCC generated (at line 52, column 19) for  m
      % expected type  T_high[nat]
  binom_pr1_TCC1: OBLIGATION
    FORALL (N, i, m: nat):
      m <= 8 AND m >= i AND m >= N IMPLIES
       m >= 0 OR (EXISTS (j: nat): m <= j);

  % Subtype TCC generated (at line 52, column 72) for  m - N
      % expected type  nat
  binom_pr1_TCC2: OBLIGATION
    FORALL (N, i, m: nat):
      m <= 8 AND m >= i AND m >= N IMPLIES
       (FORALL (k: nat): NOT k < max(N, i) AND NOT k > m IMPLIES m - N >= 0);

  % Subtype TCC generated (at line 52, column 76) for  k - N
      % expected type  {i: nat | i <= m - N}
  binom_pr1_TCC3: OBLIGATION
    FORALL (N, i, m: nat):
      m <= 8 AND m >= i AND m >= N IMPLIES
       (FORALL (k: nat):
          NOT k < max(N, i) AND NOT k > m IMPLIES
           k - N >= 0 AND k - N <= m - N);

  % Subtype TCC generated (at line 52, column 85) for  i
      % expected type  {i: nat | i <= k}
  binom_pr1_TCC4: OBLIGATION
    FORALL (N, i, m: nat):
      m <= 8 AND m >= i AND m >= N IMPLIES
       (FORALL (k: nat): NOT k < max(N, i) AND NOT k > m IMPLIES i <= k);

  % Subtype TCC generated (at line 53, column 12) for  min(N, i)
      % expected type  T_high[nat]
  binom_pr1_TCC5: OBLIGATION
    FORALL (N, i, m: nat):
      m <= 8 AND m >= i AND m >= N IMPLIES
       min(N, i) >= 0 OR (EXISTS (j: nat): min(N, i) <= j);

  % Subtype TCC generated (at line 53, column 67) for  m - j
      % expected type  nat
  binom_pr1_TCC6: OBLIGATION
    FORALL (N, i, m: nat):
      m <= 8 AND m >= i AND m >= N IMPLIES
       (FORALL (j: nat): NOT j > min(N, i) IMPLIES m - j >= 0);

  % Subtype TCC generated (at line 53, column 71) for  i - j
      % expected type  {i: nat | i <= m - j}
  binom_pr1_TCC7: OBLIGATION
    FORALL (N, i, m: nat):
      m <= 8 AND m >= i AND m >= N IMPLIES
       (FORALL (j: nat):
          NOT j > min(N, i) IMPLIES i - j >= 0 AND i - j <= m - j);

  % Subtype TCC generated (at line 53, column 80) for  j
      % expected type  {i: nat | i <= N}
  binom_pr1_TCC8: OBLIGATION
    FORALL (N, i, m: nat):
      m <= 8 AND m >= i AND m >= N IMPLIES
       (FORALL (j: nat): NOT j > min(N, i) IMPLIES j <= N);

  % Subtype TCC generated (at line 56, column 74) for  N
      % expected type  {i: nat | i <= k}
  binomial_triple_cancel_TCC1: OBLIGATION
    FORALL (N, i, m: nat):
      m <= 8 AND m >= i AND m >= N IMPLIES
       (FORALL (k: nat): NOT k < max(N, i) AND NOT k > m IMPLIES N <= k);

  % Subtype TCC generated (at line 56, column 81) for  k
      % expected type  {i: nat | i <= m}
  binomial_triple_cancel_TCC2: OBLIGATION
    FORALL (N, i, m: nat):
      m <= 8 AND m >= i AND m >= N IMPLIES
       (FORALL (k: nat): NOT k < max(N, i) AND NOT k > m IMPLIES k <= m);

  % Subtype TCC generated (at line 57, column 87) for  N
      % expected type  {i: nat | i <= m}
  binomial_triple_cancel_TCC3: OBLIGATION
    FORALL (N, i, m: nat):
      m <= 8 AND m >= i AND m >= N IMPLIES
       (FORALL (j: nat): NOT j > min(N, i) IMPLIES N <= m);


body:
  bernstein_polynomials: THEORY

  %--------------------------------------------------------------------------
  % Bernstein Polynomials
  % 
  % Version 1      April 2010
  %
  % Anthony Narkawicz       NASA
  %--------------------------------------------------------------------------

  BEGIN

    IMPORTING polynomials,
              sigma_swap[nat],
              binomial_identities

    x,y,t,Ma   : VAR real
    i,j,m,p,bi,n : VAR nat
    k,r	     : VAR posnat

    Bernstein_Polynomial: TYPE = [# index: nat, bern_seq: [upto(index) -> real] #]

    b,b1,b2 : VAR Bernstein_Polynomial
    a,a1,a2 : VAR sequence[real] %---- An ordinary polynomial ----%


    Bern(i:nat,n:above(i-1))(x) : real = C(n,i)*x^i*(1-x)^(n-i)

    Bern_top: LEMMA Bern(p,p)(x) = x^p

    Bern_bottom: LEMMA Bern(0,k)(x) = (1-x)^k

    Bern_middle_zero: LEMMA FORALL (i:nat,nn:above(i-1)): i/=0 IMPLIES Bern(i,nn)(0) = 0

    Bern_middle_one: LEMMA FORALL (i:nat,nn:above(i-1)): i/=nn IMPLIES Bern(i,nn)(1) = 0

    Bern_Polynomial: LEMMA 
    	     FORALL (i:nat, nn:above(i-1)):
    	     Bern(i,nn) = 
  	       polynomial((LAMBDA (j:nat): IF j<i OR j>nn THEN 0 ELSE (-1)^(j-i)*C(nn,j)*C(j,i) ENDIF),nn)

    Bernstein_Recursion: LEMMA k>r IMPLIES Bern(r,k)(x) = (1-x)*Bern(r,k-1)(x) + x*Bern(r-1,k-1)(x)

    Bern_nonnegative: LEMMA 
    		    0<=x AND x<=1 IMPLIES FORALL (i:nat, nn:above(i-1)): Bern(i,nn)(x) >= 0

    Bern_positive: LEMMA
      		 0<x AND x<1 IMPLIES FORALL (i:nat, nn:above(i-1)): Bern(i,nn)(x) > 0

    % Degree raising for Bernstein polynomials

    Bernstein_degree_raise: LEMMA
      k>p IMPLIES Bern(p,k-1)(x) = ((k-p)/k)*Bern(p,k)(x) + ((p+1)/k)*Bern(p+1,k)(x)

    degree_raise(b): Bernstein_Polynomial =
      LET
        m = b`index,
        bseq = b`bern_seq
      IN
        (# index := m+1,
        bern_seq := (LAMBDA (i:upto(m+1)):
          IF i = 0 THEN bseq(0)
  	ELSIF i = m+1 THEN bseq(m)
  	ELSE
  	  (bseq(i)*(m+1-i) + bseq(i-1)*i)/(m+1)
  	ENDIF) #)

    degree_raise_power(b,j): RECURSIVE Bernstein_Polynomial =
      IF j=0 THEN b
      ELSE degree_raise(degree_raise_power(b,j-1))
      ENDIF 
      MEASURE j

    Bernstein_index_degree_raise: LEMMA k>=p IMPLIES x*Bern(p,k)(x) = ((p+1)/(k+1))*Bern(p+1,k+1)(x)

    % The Bernstein polynomials form a partition of unity

    Bernstein_partition_of_unity: LEMMA
      sigma(0,p,(LAMBDA (i:nat): IF i>p THEN 0 ELSE Bern(i,p)(x) ENDIF)) = 1

    Bern_le_1: LEMMA 0<=x AND x<=1 IMPLIES FORALL (i:nat, nn:above(i-1)): Bern(i,nn)(x) <= 1

    Bernstein_conversion: LEMMA 
      k>=p IMPLIES
      x^p = sigma(p,k,(LAMBDA (i:nat): IF i<p OR i>k THEN 0 ELSE (C(i,p)/C(k,p))*Bern(i,k)(x) ENDIF))

    Bernstein_conversion_2: LEMMA
      k>=p IMPLIES
      x^p = sigma(0,k,(LAMBDA (i:nat): IF i<p OR i>k THEN 0 ELSE (C(i,p)/C(k,p))*Bern(i,k)(x) ENDIF))

    % Bernstein polynomials - linear combinations of the basic Bernstein polynomials B_ik

    Bern_poly(b): [real -> real] = LAMBDA (x:real):
      sigma(0,b`index,(LAMBDA (i:nat): IF i > b`index THEN 0 ELSE b`bern_seq(i)*Bern(i,b`index)(x) ENDIF))

    degree_raise_id: LEMMA Bern_poly(b) = Bern_poly(degree_raise(b))

    degree_raise_power_id: LEMMA Bern_poly(b) = Bern_poly(degree_raise_power(b,j))

    Bern_poly_reverse(b): Bernstein_Polynomial = 
      (# index:=b`index, bern_seq := (LAMBDA (i:upto(b`index)): b`bern_seq(b`index-i)) #)

    Bern_poly_reverse_sym_half: LEMMA Bern_poly(b)(1/2 + x) = Bern_poly(Bern_poly_reverse(b))(1/2-x)

    Bern_poly_reverse_sym: LEMMA Bern_poly(b)(x) = Bern_poly(Bern_poly_reverse(b))(1-x)

    Bern_poly_inverse(b): sequence[real] = LAMBDA (j:nat): 
          IF j>b`index THEN 
  	  0
  	ELSE
  	  sigma(0,j,(LAMBDA (i:nat): IF i > j THEN 0 ELSE b`bern_seq(i)*(-1)^(j-i)*(C(b`index,j)*C(j,i)) ENDIF))
  	ENDIF

    % Structural Property Decomposition For Bernstein Polynomials

    P: VAR [Bernstein_Polynomial -> bool]
    
    Bern_structural_decomp: LEMMA
      ((FORALL (b1,b2: Bernstein_Polynomial): b1`index = b2`index AND P(b1) AND P(b2) 
        IMPLIES P((# index:= b1`index,bern_seq := (LAMBDA (i:upto(b1`index)): b1`bern_seq(i) + b2`bern_seq(i)) #)))
      AND
      (FORALL (i,m:nat,x:real): i<=m IMPLIES 
       P((# index := m, bern_seq := (LAMBDA (j:upto(m)): IF j = i THEN x ELSE 0 ENDIF) #))))
      IMPLIES
      (FORALL (b:Bernstein_Polynomial): P(b))

    % The function that takes a sequence corresponing to a polynomial in the monomial
    % basis and returns the sequence corresponing to the polynomial in the Bernstein basis. The number p
    % is the "degree" of the polynomial in the monomial basis, and m is the Bernstein degree.

    Bernstein_polynomial(a,p,m): Bernstein_Polynomial =
     (# index := m,
     bern_seq := LAMBDA (s: upto(m)): sigma(0,s,LAMBDA(i:nat):IF i>s OR i>p THEN 0 ELSE a(i)*(C(s,i)/C(m,i)) ENDIF) #)

    Bernstein_equivalence: LEMMA
      m>=p IMPLIES polynomial(a,p) = Bern_poly(Bernstein_polynomial(a,p,m))

    Bern_poly_inverse_def: LEMMA
      polynomial(Bern_poly_inverse(b),b`index) = Bern_poly(b)

    % Splitting the Interval

    Bern_subdiv_left(b): Bernstein_Polynomial =
      (# index := b`index,
         bern_seq := LAMBDA (i:upto(b`index)): (1/2^i)*sigma(0,i,
                     LAMBDA (j:nat): IF j > i THEN 0 ELSE C(i,j)*b`bern_seq(j) ENDIF) #)

    Bern_subdiv_right(b): Bernstein_Polynomial =
      (# index := b`index,
      bern_seq := LAMBDA (i:upto(b`index)): (1/2^(b`index-i))*sigma(0,b`index-i,
                  LAMBDA (j:nat): IF j > b`index-i THEN 0 ELSE C(b`index-i,j)*b`bern_seq(b`index-j) ENDIF) #)

    Bern_subdiv_left_id: LEMMA Bern_poly(Bern_subdiv_left(b)) = Bern_poly(b) o (LAMBDA (x:real): (1/2)*x)

    Bern_subdiv_left_reverse: LEMMA Bern_poly(Bern_poly_reverse(Bern_subdiv_left(Bern_poly_reverse(b)))) = 
      Bern_poly(b) o (LAMBDA (x:real): (1/2)*(x+1)) 

    Bern_subdiv_right_id: LEMMA Bern_poly(Bern_subdiv_right(b)) = Bern_poly(b) o (LAMBDA (x:real): (1/2)*(x+1))

    Bern_subdiv_ge: LEMMA 
    		  (FORALL (y:real): 0<=y AND y<=1 IMPLIES Bern_poly(Bern_subdiv_right(b))(y) >= Ma) 
  		  AND 
  		  (FORALL (y:real): 0<=y AND y<=1 IMPLIES Bern_poly(Bern_subdiv_left(b))(y) >= Ma)
  		  IMPLIES 
  		  (0<=x AND x<=1 IMPLIES Bern_poly(b)(x) >= Ma)

    %-------------------------------------------------------%
    %-------------------------------------------------------%
    % Splitting the interval another way
    %-------------------------------------------------------%
    %-------------------------------------------------------%

    Bern_sweep(b)(p:upto(b`index)): RECURSIVE {bp: Bernstein_Polynomial | bp`index = b`index}
      = (# index := b`index,
        bern_seq :=
        IF p = 0 THEN b`bern_seq
        ELSE
          (LAMBDA (i:upto(b`index)):
  	IF i<p THEN Bern_sweep(b)(p-1)`bern_seq(i)
  	ELSE (1/2)*(Bern_sweep(b)(p-1)`bern_seq(i-1) + Bern_sweep(b)(p-1)`bern_seq(i))
  	ENDIF)
        ENDIF #) MEASURE p

    Bern_sweep_expand: LEMMA
      p<=b`index IMPLIES
      Bern_sweep(b)(p) =
        (# index := b`index,
        bern_seq :=
        (LAMBDA (i:upto(b`index)):
  	IF i<=p THEN
  	  (1/(2^i))*sigma(0,i,(LAMBDA (j:nat): IF j > i THEN 0 ELSE b`bern_seq(j)*C(i,j) ENDIF))
  	ELSE
  	  (1/(2^p))*sigma(0,p,(LAMBDA (j:nat): IF j > p THEN 0 ELSE b`bern_seq(j+(i-p))*C(p,j) ENDIF))
  	ENDIF) #)

    Bern_subdiv_l(b): Bernstein_Polynomial = Bern_sweep(b)(b`index)

    Bern_subdiv_r(b): Bernstein_Polynomial = 
    		    (# index := b`index,
  		    bern_seq := (LAMBDA (i:upto(b`index)): Bern_sweep(b)(b`index - i)`bern_seq(b`index)) #)

    Bern_subdiv_l_id: LEMMA Bern_poly(Bern_subdiv_l(b)) = Bern_poly(b) o (LAMBDA (x:real): (1/2)*x)

    Bern_subdiv_r_id: LEMMA Bern_poly(Bern_subdiv_r(b)) = Bern_poly(b) o (LAMBDA (x:real): (1/2)*(x+1))

    %-------------------------------------------------------%
    %-------------------------------------------------------%
    % End of splitting the interval another way
    %-------------------------------------------------------%
    %-------------------------------------------------------%

    % Bernstein Coefficients

    Bern_coeff(a,p,m)(s: upto(m)): real = 
      LET msp = min(s,p) IN sigma(0,msp,LAMBDA(i:nat):IF i>msp THEN 0 ELSE a(i)*(C(s,i)/C(m,i)) ENDIF)

    Bernstein_le: LEMMA 
      (FORALL (s:upto(m)): Bern_coeff(a,p,m)(s) <= Ma) AND 0<=x AND x<=1 AND m>=p IMPLIES polynomial(a,p)(x) <= Ma

    Bernstein_lt: LEMMA 
      (FORALL (s:upto(m)): Bern_coeff(a,p,m)(s) < Ma) AND 0<=x AND x<=1 AND m>=p IMPLIES polynomial(a,p)(x) < Ma

    Bernstein_ge: LEMMA 
      (FORALL (s:upto(m)): Bern_coeff(a,p,m)(s) >= Ma) AND 0<=x AND x<=1 AND m>=p IMPLIES polynomial(a,p)(x) >= Ma

    Bernstein_gt: LEMMA 
      (FORALL (s:upto(m)): Bern_coeff(a,p,m)(s) > Ma) AND 0<=x AND x<=1 AND m>=p IMPLIES polynomial(a,p)(x) > Ma

    % For Bernstein Polynomials

    Bern_poly_le: LEMMA 
      (FORALL (s:upto(b`index)): b`bern_seq(s) <= Ma) AND 0<=x AND x<=1 IMPLIES Bern_poly(b)(x) <= Ma

    Bern_poly_lt: LEMMA 
      (FORALL (s:upto(b`index)): b`bern_seq(s) < Ma) AND 0<=x AND x<=1 IMPLIES Bern_poly(b)(x) < Ma

    Bern_poly_ge: LEMMA 
      (FORALL (s:upto(b`index)): b`bern_seq(s) >= Ma) AND 0<=x AND x<=1 IMPLIES Bern_poly(b)(x) >= Ma

    Bern_poly_gt: LEMMA 
      (FORALL (s:upto(b`index)): b`bern_seq(s) > Ma) AND 0<=x AND x<=1 IMPLIES Bern_poly(b)(x) > Ma

    % Quotients

    Bern_poly_quotient_le: LEMMA
      b1`index = b2`index AND
      (FORALL (s:upto(b2`index)): b2`bern_seq(s) > 0) AND
      (FORALL (s:upto(b1`index)): b1`bern_seq(s)/b2`bern_seq(s) <= Ma)
      AND 0<=x AND x<=1 IMPLIES
      (Bern_poly(b2)(x) > 0 AND
      Bern_poly(b1)(x)/Bern_poly(b2)(x) <= Ma)

    % Splitting

    Bern_poly_split_le: LEMMA
       LET bsl = Bern_subdiv_l(b),bsr = Bern_subdiv_r(b) IN
          (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(bsr)(x)<=Ma) AND 
          (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(bsl)(x)<=Ma)
          IMPLIES (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(b)(x)<=Ma)

    Bern_poly_split_lt: LEMMA
       LET bsl = Bern_subdiv_l(b),bsr = Bern_subdiv_r(b) IN
          (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(bsr)(x)<Ma) AND 
          (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(bsl)(x)<Ma)
          IMPLIES (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(b)(x)<Ma)

    Bern_poly_split_ge: LEMMA
       LET bsl = Bern_subdiv_l(b),bsr = Bern_subdiv_r(b) IN
          (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(bsr)(x)>=Ma) AND 
          (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(bsl)(x)>=Ma)
          IMPLIES (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(b)(x)>=Ma)

    Bern_poly_split_gt: LEMMA
       LET bsl = Bern_subdiv_l(b),bsr = Bern_subdiv_r(b) IN
          (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(bsr)(x)>Ma) AND 
          (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(bsl)(x)>Ma)
          IMPLIES (FORALL (x:real): 0<=x AND x<=1 IMPLIES Bern_poly(b)(x)>Ma)

    % COLLECTIONS OF BERNSTEIN POLYNOMIALS

    % Next are recursive definitions of min and max for bernstein polynomials

    Bern_min_rec(b)(q:upto(b`index)): RECURSIVE 
      {r:real | (EXISTS (iq:upto(q)): r = b`bern_seq(iq)) AND (FORALL (iq:upto(q)): r <= b`bern_seq(iq))} =
      LET y = b`bern_seq(q),
          x = IF q = 0 THEN y ELSE Bern_min_rec(b)(q-1) ENDIF
      IN	min(y,x)
      MEASURE q

    Bern_max_rec(b)(q:upto(b`index)): RECURSIVE 
     {r:real | (EXISTS (iq:upto(q)): r = b`bern_seq(iq)) AND (FORALL (iq:upto(q)): r >= b`bern_seq(iq))} =
     LET y = b`bern_seq(q),
         x = IF q = 0 THEN y ELSE Bern_max_rec(b)(q-1) ENDIF
     IN	max(y,x)
     MEASURE q

    Bern_min(b) : 
     {r : real | (EXISTS (ib:upto(b`index)): r = b`bern_seq(ib)) AND 
                 (FORALL (ib:upto(b`index)): r<=b`bern_seq(ib))} = 
     Bern_min_rec(b)(b`index)

    Bern_max(b) : 
     {r : real | (EXISTS (ib:upto(b`index)): r = b`bern_seq(ib)) AND 
                 (FORALL (ib:upto(b`index)): r>=b`bern_seq(ib))} = 
      Bern_max_rec(b)(b`index)

    Bern_min_bound : LEMMA 0<=x AND x<=1 IMPLIES Bern_poly(b)(x)>=Bern_min(b)

    Bern_max_bound : LEMMA 0<=x AND x<=1 IMPLIES Bern_poly(b)(x)<=Bern_max(b)

    % A function to compute the current min and max estimates follows. One should note that if b_0,...,b_n are 
    % Bernstein coefficients for a polynomial, then the polynomial attains the values of b_0 and b_n at t = 0 
    % and t = 1.

    Bern_min_est(b): real = min(b`bern_seq(0),b`bern_seq(b`index))

    Bern_max_est(b): real = max(b`bern_seq(0),b`bern_seq(b`index))

    % The next construction, Bernstein_Collection is a type. An element of this type is a collection of 
    % Bernstein Polynomials, and associated to each one is a pair consisting of its minimum and maximum entries

    Bernstein_MinMax: TYPE = [# bernpoly: Bernstein_Polynomial, bernmin:real, bernmax:real #]

    Bern_minmax(b) : Bernstein_MinMax = (# bernpoly := b, bernmin := Bern_min(b), bernmax := Bern_max(b) #)

    Bernstein_MinMax_Collection: TYPE = [# number_polys : posnat, 
                                         bern_poly_number : [below(number_polys) -> Bernstein_MinMax] #]

    BC, BC1, BC2: VAR Bernstein_MinMax_Collection
   
    Bern_concat(BC1,BC2): Bernstein_MinMax_Collection = 
      LET NN = BC1`number_polys + BC2`number_polys IN
      (# number_polys := NN, 
         bern_poly_number := LAMBDA (i:below(NN)): IF i<=BC1`number_polys-1 THEN BC1`bern_poly_number(i) 
                                                   ELSE BC2`bern_poly_number(i-BC1`number_polys) ENDIF #)

    Bern_collection_min_est_rec(BC)(np:below(BC`number_polys)) : RECURSIVE real = 
      IF np = 0 THEN Bern_min_est(BC`bern_poly_number(0)`bernpoly)
      ELSE min(Bern_min_est(BC`bern_poly_number(0)`bernpoly),Bern_collection_min_est_rec(BC)(np-1)) ENDIF
    MEASURE np

    Bern_collection_min_est(BC): real = 
      IF BC`number_polys /= 0 THEN Bern_collection_min_est_rec(BC)(BC`number_polys-1) ELSE 0 ENDIF

    Bern_collection_reduce_min_rec(BC)(np:below(BC`number_polys)): RECURSIVE Bernstein_MinMax_Collection = 
      LET minest = Bern_collection_min_est(BC),
          thispoly:Bernstein_MinMax_Collection = (# number_polys := 1, 
                                                    bern_poly_number := LAMBDA (i:below(1)): BC`bern_poly_number(np) #)
      IN
      IF np = 0 THEN thispoly
      ELSIF BC`bern_poly_number(np)`bernmin > minest THEN Bern_collection_reduce_min_rec(BC)(np-1)
      ELSE  Bern_concat(Bern_collection_reduce_min_rec(BC)(np-1),thispoly) ENDIF
    MEASURE np

    Bern_collection_reduce_min(BC) : Bernstein_MinMax_Collection = 
      Bern_collection_reduce_min_rec(BC)(BC`number_polys-1)

    % The minimum coefficient

    Bern_min_coeff_rec(BC)(np:below(BC`number_polys)) : RECURSIVE real =
      LET current_poly_min = BC`bern_poly_number(np)`bernmin
      IN
      IF np = 0 THEN current_poly_min
      ELSE min(current_poly_min,Bern_min_coeff_rec(BC)(np-1)) ENDIF 
    MEASURE np

    Bern_min_coeff(BC): real = Bern_min_coeff_rec(BC)(BC`number_polys-1)
    			       
    % Next, we subdivide each bernstein polynomial in the collection.

    Bern_coll_subdiv_total_left(BC) : Bernstein_MinMax_Collection =
      (# number_polys := BC`number_polys, 
         bern_poly_number := LAMBDA (np: below(BC`number_polys)): 
                             Bern_minmax(Bern_subdiv_left(BC`bern_poly_number(np)`bernpoly)) #)

    Bern_coll_subdiv_total_right(BC) : Bernstein_MinMax_Collection =
      (# number_polys := BC`number_polys, 
         bern_poly_number := LAMBDA (np: below(BC`number_polys)): 
                             Bern_minmax(Bern_subdiv_right(BC`bern_poly_number(np)`bernpoly)) #)

    Bern_coll_subdiv_total(BC) : Bernstein_MinMax_Collection = 
     Bern_concat(Bern_coll_subdiv_total_left(BC),Bern_coll_subdiv_total_right(BC))

    Bern_coll_subdiv_reduced(BC) : Bernstein_MinMax_Collection = 
      Bern_collection_reduce_min(Bern_coll_subdiv_total(BC))

    Bern_split(b)(n :nat) : recursive Bernstein_MinMax_Collection =
      IF n=0 THEN (# number_polys := 1, bern_poly_number := (LAMBDA (i:below(1)): Bern_minmax(b)) #)
      ELSE
      Bern_coll_subdiv_reduced(Bern_split(b)(n-1))
      ENDIF
      MEASURE n

    Bern_split_min_coeff(a,p,m)(n:nat) : real =
      LET b = Bernstein_polynomial(a,p,m)
      IN Bern_min_coeff(Bern_split(b)(n))

  END bernstein_polynomials

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

  % Subtype TCC generated (at line 27, column 41) for  n
      % expected type  nat
  Bern_TCC1: OBLIGATION FORALL (i: nat, n: above(i - 1)): n >= 0;

  % Subtype TCC generated (at line 27, column 43) for  i
      % expected type  {i_1: nat | i_1 <= n}
  Bern_TCC2: OBLIGATION FORALL (i: nat, n: above(i - 1)): i <= n;

  % Subtype TCC generated (at line 27, column 48) for  i
      % expected type  {i: int | x /= 0 OR i >= 0}
  Bern_TCC3: OBLIGATION FORALL (i: nat, x: real): x /= 0 OR i >= 0;

  % Subtype TCC generated (at line 27, column 57) for  (n - i)
      % expected type  {i: int | (1 - x) /= 0 OR i >= 0}
  Bern_TCC4: OBLIGATION
    FORALL (i: nat, n: above(i - 1), x: real): (1 - x) /= 0 OR (n - i) >= 0;

  % Subtype TCC generated (at line 29, column 25) for  p
      % expected type  above(p - 1)
  Bern_top_TCC1: OBLIGATION FORALL (p: nat): p > p - 1;

  % Subtype TCC generated (at line 31, column 28) for  k
      % expected type  above(-1)
  Bern_bottom_TCC1: OBLIGATION FORALL (k: posnat): k > -1;

  % Subtype TCC generated (at line 31, column 42) for  k
      % expected type  {i: int | (1 - x) /= 0 OR i >= 0}
  Bern_bottom_TCC2: OBLIGATION
    FORALL (k: posnat, x: real): (1 - x) /= 0 OR k >= 0;

  % Subtype TCC generated (at line 40, column 79) for  j
      % expected type  {i_1: nat | i_1 <= nn}
  Bern_Polynomial_TCC1: OBLIGATION
    FORALL (i: nat, nn: above(i - 1), j: nat):
      NOT j < i AND NOT j > nn IMPLIES j <= nn;

  % Subtype TCC generated (at line 40, column 86) for  i
      % expected type  {i: nat | i <= j}
  Bern_Polynomial_TCC2: OBLIGATION
    FORALL (i: nat, nn: above(i - 1), j: nat):
      NOT j < i AND NOT j > nn IMPLIES i <= j;

  % Subtype TCC generated (at line 42, column 48) for  k
      % expected type  above(r - 1)
  Bernstein_Recursion_TCC1: OBLIGATION
    FORALL (k, r: posnat): k > r IMPLIES k > r - 1;

  % Subtype TCC generated (at line 42, column 69) for  k - 1
      % expected type  above(r - 1)
  Bernstein_Recursion_TCC2: OBLIGATION
    FORALL (k, r: posnat): k > r IMPLIES k - 1 > r - 1;

  % Subtype TCC generated (at line 42, column 86) for  r - 1
      % expected type  nat
  Bernstein_Recursion_TCC3: OBLIGATION
    FORALL (k, r: posnat): k > r IMPLIES r - 1 >= 0;

  % Subtype TCC generated (at line 42, column 90) for  k - 1
      % expected type  above(r - 2)
  Bernstein_Recursion_TCC4: OBLIGATION
    FORALL (k, r: posnat): k > r IMPLIES k - 1 > r - 2;

  % Subtype TCC generated (at line 53, column 23) for  k - 1
      % expected type  above(p - 1)
  Bernstein_degree_raise_TCC1: OBLIGATION
    FORALL (k: posnat, p: nat): k > p IMPLIES k - 1 > p - 1;

  % Subtype TCC generated (at line 53, column 50) for  k
      % expected type  above(p - 1)
  Bernstein_degree_raise_TCC2: OBLIGATION
    FORALL (k: posnat, p: nat): k > p IMPLIES k > p - 1;

  % Subtype TCC generated (at line 62, column 27) for  0
      % expected type  upto(b`index)
  degree_raise_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial, m: nat):
      m = b`index IMPLIES
       (FORALL (bseq: [upto(b`index) -> real]):
          bseq = b`bern_seq IMPLIES
           (FORALL (i: upto(m + 1)): i = 0 IMPLIES 0 <= b`index));

  % Subtype TCC generated (at line 63, column 25) for  m
      % expected type  upto(b`index)
  degree_raise_TCC2: OBLIGATION
    FORALL (b: Bernstein_Polynomial, m: nat):
      m = b`index IMPLIES
       (FORALL (bseq: [upto(b`index) -> real]):
          bseq = b`bern_seq IMPLIES
           (FORALL (i: upto(m + 1)):
              i = m + 1 AND NOT i = 0 IMPLIES m <= b`index));

  % Subtype TCC generated (at line 65, column 9) for  i
      % expected type  upto(b`index)
  degree_raise_TCC3: OBLIGATION
    FORALL (b: Bernstein_Polynomial, m: nat):
      m = b`index IMPLIES
       (FORALL (bseq: [upto(b`index) -> real]):
          bseq = b`bern_seq IMPLIES
           (FORALL (i: upto(m + 1)):
              NOT i = m + 1 AND NOT i = 0 IMPLIES i <= b`index));

  % Subtype TCC generated (at line 65, column 27) for  i - 1
      % expected type  upto(b`index)
  degree_raise_TCC4: OBLIGATION
    FORALL (b: Bernstein_Polynomial, m: nat):
      m = b`index IMPLIES
       (FORALL (bseq: [upto(b`index) -> real]):
          bseq = b`bern_seq IMPLIES
           (FORALL (i: upto(m + 1)):
              NOT i = m + 1 AND NOT i = 0 IMPLIES
               i - 1 >= 0 AND i - 1 <= b`index));

  % Subtype TCC generated (at line 70, column 43) for  j - 1
      % expected type  nat
  degree_raise_power_TCC1: OBLIGATION
    FORALL (j: nat): NOT j = 0 IMPLIES j - 1 >= 0;

  % Termination TCC generated (at line 70, column 22) for
      % degree_raise_power(b, j - 1)
  degree_raise_power_TCC2: OBLIGATION
    FORALL (j: nat): NOT j = 0 IMPLIES j - 1 < j;

  % Subtype TCC generated (at line 74, column 60) for  k
      % expected type  above(p - 1)
  Bernstein_index_degree_raise_TCC1: OBLIGATION
    FORALL (k: posnat, p: nat): k >= p IMPLIES k > p - 1;

  % Subtype TCC generated (at line 74, column 91) for  k + 1
      % expected type  above(p)
  Bernstein_index_degree_raise_TCC2: OBLIGATION
    FORALL (k: posnat, p: nat): k >= p IMPLIES k + 1 > p;

  % Subtype TCC generated (at line 79, column 12) for  p
      % expected type  T_high[nat]
  Bernstein_partition_of_unity_TCC1: OBLIGATION
    FORALL (p: nat): p >= 0 OR (EXISTS (j: nat): p <= j);

  % Subtype TCC generated (at line 79, column 57) for  p
      % expected type  above(i - 1)
  Bernstein_partition_of_unity_TCC2: OBLIGATION
    FORALL (p, i: nat): NOT i > p IMPLIES p > i - 1;

  % Subtype TCC generated (at line 85, column 18) for  k
      % expected type  T_high[nat]
  Bernstein_conversion_TCC1: OBLIGATION
    FORALL (k: posnat, p: nat):
      k >= p IMPLIES k >= 0 OR (EXISTS (j: nat): k <= j);

  % Subtype TCC generated (at line 85, column 68) for  p
      % expected type  {i_1: nat | i_1 <= i}
  Bernstein_conversion_TCC2: OBLIGATION
    FORALL (k: posnat, p: nat):
      k >= p IMPLIES
       (FORALL (i: nat): NOT i < p AND NOT i > k IMPLIES p <= i);

  % Subtype TCC generated (at line 85, column 75) for  p
      % expected type  {i: nat | i <= k}
  Bernstein_conversion_TCC3: OBLIGATION
    FORALL (k: posnat, p: nat):
      k >= p IMPLIES
       (FORALL (i: nat): NOT i < p AND NOT i > k IMPLIES p <= k);

  % Subtype TCC generated (at line 85, column 86) for  k
      % expected type  above(i - 1)
  Bernstein_conversion_TCC4: OBLIGATION
    FORALL (k: posnat, p: nat):
      k >= p IMPLIES
       (FORALL (i: nat): NOT i < p AND NOT i > k IMPLIES k > i - 1);

  % Subtype TCC generated (at line 94, column 12) for  b`index
      % expected type  T_high[nat]
  Bern_poly_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial):
      b`index >= 0 OR (EXISTS (j: nat): b`index <= j);

  % Subtype TCC generated (at line 94, column 75) for  i
      % expected type  upto(b`index)
  Bern_poly_TCC2: OBLIGATION
    FORALL (b: Bernstein_Polynomial, i: nat):
      NOT i > b`index IMPLIES i <= b`index;

  % Subtype TCC generated (at line 94, column 85) for  b`index
      % expected type  above(i - 1)
  Bern_poly_TCC3: OBLIGATION
    FORALL (b: Bernstein_Polynomial, i: nat):
      NOT i > b`index IMPLIES b`index > i - 1;

  % Subtype TCC generated (at line 101, column 73) for  b`index - i
      % expected type  upto(b`index)
  Bern_poly_reverse_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial, i: upto(b`index)):
      b`index - i >= 0 AND b`index - i <= b`index;

  % Subtype TCC generated (at line 111, column 62) for  i
      % expected type  upto(b`index)
  Bern_poly_inverse_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial, j: nat):
      NOT j > b`index IMPLIES
       (FORALL (i: nat): NOT i > j IMPLIES i <= b`index);

  % Subtype TCC generated (at line 111, column 87) for  j
      % expected type  {i: nat | i <= b`index}
  Bern_poly_inverse_TCC2: OBLIGATION
    FORALL (b: Bernstein_Polynomial, j: nat):
      NOT j > b`index IMPLIES
       (FORALL (i: nat): NOT i > j IMPLIES j <= b`index);

  % Subtype TCC generated (at line 111, column 94) for  i
      % expected type  {i: nat | i <= j}
  Bern_poly_inverse_TCC3: OBLIGATION
    FORALL (b: Bernstein_Polynomial, j: nat):
      NOT j > b`index IMPLIES (FORALL (i: nat): NOT i > j IMPLIES i <= j);

  % Subtype TCC generated (at line 120, column 105) for  i
      % expected type  upto(b2`index)
  Bern_structural_decomp_TCC1: OBLIGATION
    FORALL (P: [Bernstein_Polynomial -> bool], b1, b2: Bernstein_Polynomial):
      b1`index = b2`index AND P(b1) AND P(b2) IMPLIES
       (FORALL (i: upto(b1`index)): i <= b2`index);

  % Subtype TCC generated (at line 133, column 44) for  s
      % expected type  T_high[nat]
  Bernstein_polynomial_TCC1: OBLIGATION
    FORALL (m: nat, s: upto(m)): s >= 0 OR (EXISTS (j: nat): s <= j);

  % Subtype TCC generated (at line 133, column 96) for  i
      % expected type  {i: nat | i <= s}
  Bernstein_polynomial_TCC2: OBLIGATION
    FORALL (p: nat, m: nat, s: upto(m), i: nat):
      NOT i > s AND NOT i > p IMPLIES i <= s;

  % Subtype TCC generated (at line 133, column 103) for  i
      % expected type  {i: nat | i <= m}
  Bernstein_polynomial_TCC3: OBLIGATION
    FORALL (p: nat, m: nat, s: upto(m), i: nat):
      NOT i > s AND NOT i > p IMPLIES i <= m;

  % Subtype TCC generated (at line 145, column 61) for  i
      % expected type  T_high[nat]
  Bern_subdiv_left_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial, i: upto(b`index)):
      i >= 0 OR (EXISTS (j: nat): i <= j);

  % Subtype TCC generated (at line 146, column 60) for  j
      % expected type  {i_1: nat | i_1 <= i}
  Bern_subdiv_left_TCC2: OBLIGATION
    FORALL (b: Bernstein_Polynomial, i: upto(b`index), j: nat):
      NOT j > i IMPLIES j <= i;

  % Subtype TCC generated (at line 146, column 74) for  j
      % expected type  upto(b`index)
  Bern_subdiv_left_TCC3: OBLIGATION
    FORALL (b: Bernstein_Polynomial, i: upto(b`index), j: nat):
      NOT j > i IMPLIES j <= b`index;

  % Subtype TCC generated (at line 150, column 68) for  b`index - i
      % expected type  T_high[nat]
  Bern_subdiv_right_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial, i: upto(b`index)):
      b`index - i >= 0 OR (EXISTS (j: nat): b`index - i <= j);

  % Subtype TCC generated (at line 151, column 63) for  b`index - i
      % expected type  nat
  Bern_subdiv_right_TCC2: OBLIGATION
    FORALL (b: Bernstein_Polynomial, i: upto(b`index), j: nat):
      NOT j > b`index - i IMPLIES b`index - i >= 0;

  % Subtype TCC generated (at line 151, column 73) for  j
      % expected type  {i_1: nat | i_1 <= b`index - i}
  Bern_subdiv_right_TCC3: OBLIGATION
    FORALL (b: Bernstein_Polynomial, i: upto(b`index), j: nat):
      NOT j > b`index - i IMPLIES j <= b`index - i;

  % Subtype TCC generated (at line 151, column 87) for  b`index - j
      % expected type  upto(b`index)
  Bern_subdiv_right_TCC4: OBLIGATION
    FORALL (b: Bernstein_Polynomial, i: upto(b`index), j: nat):
      NOT j > b`index - i IMPLIES b`index - j >= 0 AND b`index - j <= b`index;

  % Subtype TCC generated (at line 179, column 27) for  p - 1
      % expected type  upto(b`index)
  Bern_sweep_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial, p: upto(b`index)):
      NOT p = 0 IMPLIES
       (FORALL (i: upto(b`index)):
          i < p IMPLIES p - 1 >= 0 AND p - 1 <= b`index);

  % Termination TCC generated (at line 179, column 13) for
      % Bern_sweep(b)(p - 1)
  Bern_sweep_TCC2: OBLIGATION
    FORALL (b: Bernstein_Polynomial, p: upto(b`index)):
      NOT p = 0 IMPLIES (FORALL (i: upto(b`index)): i < p IMPLIES p - 1 < p);

  % Subtype TCC generated (at line 179, column 41) for  i
      % expected type  upto(Bern_sweep(b)(p - 1)`index)
  Bern_sweep_TCC3: OBLIGATION
    FORALL (b: Bernstein_Polynomial, p: upto(b`index),
            v:
              [b1: Bernstein_Polynomial ->
                 [{z: upto(b1`index) | z < p} ->
                    {bp: Bernstein_Polynomial | bp`index = b1`index}]]):
      NOT p = 0 IMPLIES
       (FORALL (i: upto(b`index)): i < p IMPLIES i <= v(b)(p - 1)`index);

  % Subtype TCC generated (at line 180, column 41) for  i - 1
      % expected type  upto(Bern_sweep(b)(p - 1)`index)
  Bern_sweep_TCC4: OBLIGATION
    FORALL (b: Bernstein_Polynomial, p: upto(b`index),
            v:
              [b1: Bernstein_Polynomial ->
                 [{z: upto(b1`index) | z < p} ->
                    {bp: Bernstein_Polynomial | bp`index = b1`index}]]):
      NOT p = 0 IMPLIES
       (FORALL (i: upto(b`index)):
          NOT i < p IMPLIES i - 1 >= 0 AND i - 1 <= v(b)(p - 1)`index);

  % Subtype TCC generated (at line 180, column 27) for  p - 1
      % expected type  upto(b`index)
  Bern_sweep_TCC5: OBLIGATION
    FORALL (b: Bernstein_Polynomial, p: upto(b`index)):
      NOT p = 0 IMPLIES
       (FORALL (i: upto(b`index)):
          NOT i < p IMPLIES p - 1 >= 0 AND p - 1 <= b`index);

  % Termination TCC generated (at line 180, column 13) for
      % Bern_sweep(b)(p - 1)
  Bern_sweep_TCC6: OBLIGATION
    FORALL (b: Bernstein_Polynomial, p: upto(b`index)):
      NOT p = 0 IMPLIES
       (FORALL (i: upto(b`index)): NOT i < p IMPLIES p - 1 < p);

  % Subtype TCC generated (at line 180, column 76) for  i
      % expected type  upto(Bern_sweep(b)(p - 1)`index)
  Bern_sweep_TCC7: OBLIGATION
    FORALL (b: Bernstein_Polynomial, p: upto(b`index),
            v:
              [b1: Bernstein_Polynomial ->
                 [{z: upto(b1`index) | z < p} ->
                    {bp: Bernstein_Polynomial | bp`index = b1`index}]]):
      NOT p = 0 IMPLIES
       (FORALL (i: upto(b`index)): NOT i < p IMPLIES i <= v(b)(p - 1)`index);

  % Subtype TCC generated (at line 193, column 72) for  j + (i - p)
      % expected type  upto(b`index)
  Bern_sweep_expand_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial, p: nat):
      p <= b`index IMPLIES
       (FORALL (i: upto(b`index)):
          NOT i <= p IMPLIES
           (FORALL (j: nat):
              NOT j > p IMPLIES j + (i - p) >= 0 AND j + (i - p) <= b`index));

  % Subtype TCC generated (at line 193, column 85) for  j
      % expected type  {i: nat | i <= p}
  Bern_sweep_expand_TCC2: OBLIGATION
    FORALL (b: Bernstein_Polynomial, p: nat):
      p <= b`index IMPLIES
       (FORALL (i: upto(b`index)):
          NOT i <= p IMPLIES (FORALL (j: nat): NOT j > p IMPLIES j <= p));

  % Subtype TCC generated (at line 196, column 57) for  b`index
      % expected type  upto(b`index)
  Bern_subdiv_l_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial): b`index <= b`index;

  % Subtype TCC generated (at line 200, column 81) for  b`index
      % expected type  upto(Bern_sweep(b)(b`index - i)`index)
  Bern_subdiv_r_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial, i: upto(b`index)):
      b`index <= Bern_sweep(b)(b`index - i)`index;

  % Subtype TCC generated (at line 215, column 34) for  msp
      % expected type  T_high[nat]
  Bern_coeff_TCC1: OBLIGATION
    FORALL (p: nat, m: nat, s: upto(m), msp: {k: nat | k <= s AND k <= p}):
      msp = min(s, p) IMPLIES msp >= 0 OR (EXISTS (j: nat): msp <= j);

  % Subtype TCC generated (at line 215, column 83) for  i
      % expected type  {i: nat | i <= s}
  Bern_coeff_TCC2: OBLIGATION
    FORALL (p: nat, m: nat, s: upto(m), msp: {k: nat | k <= s AND k <= p}):
      msp = min(s, p) IMPLIES (FORALL (i: nat): NOT i > msp IMPLIES i <= s);

  % Subtype TCC generated (at line 215, column 90) for  i
      % expected type  {i: nat | i <= m}
  Bern_coeff_TCC3: OBLIGATION
    FORALL (p: nat, m: nat, s: upto(m), msp: {k: nat | k <= s AND k <= p}):
      msp = min(s, p) IMPLIES (FORALL (i: nat): NOT i > msp IMPLIES i <= m);

  % Subtype TCC generated (at line 248, column 59) for  s
      % expected type  upto(b2`index)
  Bern_poly_quotient_le_TCC1: OBLIGATION
    FORALL (b1, b2: Bernstein_Polynomial):
      (b1`index = b2`index AND
        (FORALL (s: upto(b2`index)): b2`bern_seq(s) > 0))
       IMPLIES (FORALL (s1: upto(b1`index)): s1 <= b2`index);

  % Subtype TCC generated (at line 248, column 47) for  b2`bern_seq(s)
      % expected type  nznum
  Bern_poly_quotient_le_TCC2: OBLIGATION
    FORALL (b1, b2: Bernstein_Polynomial):
      (b1`index = b2`index AND
        (FORALL (s: upto(b2`index)): b2`bern_seq(s) > 0))
       IMPLIES (FORALL (s1: upto(b1`index)): b2`bern_seq(s1) /= 0);

  % Subtype TCC generated (at line 251, column 21) for  Bern_poly(b2)(x)
      % expected type  nznum
  Bern_poly_quotient_le_TCC3: OBLIGATION
    FORALL (Ma: real, b1, b2: Bernstein_Polynomial, x: real):
           x <= 1 AND 0 <= x
       AND FORALL (s: upto(b1`index)): b1`bern_seq(s) / b2`bern_seq(s) <= Ma
       AND FORALL (s: upto(b2`index)): b2`bern_seq(s) > 0
       AND b1`index = b2`index AND Bern_poly(b2)(x) > 0
       IMPLIES Bern_poly(b2)(x) /= 0;

  % Subtype TCC generated (at line 284, column 51) for  iq
      % expected type  upto(b`index)
  Bern_min_rec_TCC1: OBLIGATION
    FORALL (b, q: upto(b`index), iq: upto(q)): iq <= b`index;

  % Subtype TCC generated (at line 286, column 49) for  q - 1
      % expected type  q: upto(b`index)
  Bern_min_rec_TCC2: OBLIGATION
    FORALL (b: Bernstein_Polynomial, q: upto(b`index), y: real):
      NOT q = 0 AND y = b`bern_seq(q) IMPLIES q - 1 >= 0 AND q - 1 <= b`index;

  % Termination TCC generated (at line 286, column 33) for
      % Bern_min_rec(b)(q - 1)
  Bern_min_rec_TCC3: OBLIGATION
    FORALL (b: Bernstein_Polynomial, q: upto(b`index), y: real):
      NOT q = 0 AND y = b`bern_seq(q) IMPLIES q - 1 < q;

  % Subtype TCC generated (at line 287, column 7) for  min(y, x)
      % expected type  {r: real |
                     %          (EXISTS (iq: upto(q)): r = b`bern_seq(iq))
                     %           AND
                     %           (FORALL (iq: upto(q)): r <= b`bern_seq(iq))}
  Bern_min_rec_TCC4: OBLIGATION
    FORALL (b: Bernstein_Polynomial, q: upto(b`index),
            v:
              [b1: Bernstein_Polynomial ->
                 [q1: {z: upto(b1`index) | z < q} ->
                    {r: real |
                             (EXISTS (iq: upto(q1)): r = b1`bern_seq(iq)) AND
                              (FORALL (iq: upto(q1)):
                                 r <= b1`bern_seq(iq))}]],
            y: real):
      y = b`bern_seq(q) IMPLIES
       (FORALL (x: real):
          x = IF q = 0 THEN y ELSE v(b)(q - 1) ENDIF IMPLIES
           (EXISTS (iq: upto(q)): min(y, x) = b`bern_seq(iq)) AND
            (FORALL (iq: upto(q)): min(y, x) <= b`bern_seq(iq)));

  % Subtype TCC generated (at line 294, column 6) for  max(y, x)
      % expected type  {r: real |
                     %          (EXISTS (iq: upto(q)): r = b`bern_seq(iq))
                     %           AND
                     %           (FORALL (iq: upto(q)): r >= b`bern_seq(iq))}
  Bern_max_rec_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial, q: upto(b`index),
            v:
              [b1: Bernstein_Polynomial ->
                 [q1: {z: upto(b1`index) | z < q} ->
                    {r: real |
                             (EXISTS (iq: upto(q1)): r = b1`bern_seq(iq)) AND
                              (FORALL (iq: upto(q1)):
                                 r >= b1`bern_seq(iq))}]],
            y: real):
      y = b`bern_seq(q) IMPLIES
       (FORALL (x: real):
          x = IF q = 0 THEN y ELSE v(b)(q - 1) ENDIF IMPLIES
           (EXISTS (iq: upto(q)): max(y, x) = b`bern_seq(iq)) AND
            (FORALL (iq: upto(q)): max(y, x) >= b`bern_seq(iq)));

  % Subtype TCC generated (at line 315, column 41) for  0
      % expected type  upto(b`index)
  Bern_min_est_TCC1: OBLIGATION
    FORALL (b: Bernstein_Polynomial): 0 <= b`index;

  % Subtype TCC generated (at line 334, column 100) for  i
      % expected type  below(BC1`number_polys)
  Bern_concat_TCC1: OBLIGATION
    FORALL (BC1: Bernstein_MinMax_Collection,
            BC2: Bernstein_MinMax_Collection, NN: posint):
      NN = BC1`number_polys + BC2`number_polys IMPLIES
       (FORALL (i: below(NN)):
          i <= BC1`number_polys - 1 IMPLIES i < BC1`number_polys);

  % Subtype TCC generated (at line 335, column 75) for  i - BC1`number_polys
      % expected type  below(BC2`number_polys)
  Bern_concat_TCC2: OBLIGATION
    FORALL (BC1: Bernstein_MinMax_Collection,
            BC2: Bernstein_MinMax_Collection, NN: posint):
      NN = BC1`number_polys + BC2`number_polys IMPLIES
       (FORALL (i: below(NN)):
          NOT i <= BC1`number_polys - 1 IMPLIES
           i - BC1`number_polys >= 0 AND
            i - BC1`number_polys < BC2`number_polys);

  % Subtype TCC generated (at line 338, column 52) for  0
      % expected type  below(BC`number_polys)
  Bern_collection_min_est_rec_TCC1: OBLIGATION
    FORALL (BC: Bernstein_MinMax_Collection, np: below(BC`number_polys)):
      np = 0 IMPLIES 0 < BC`number_polys;

  % Subtype TCC generated (at line 339, column 46) for  0
      % expected type  below(BC`number_polys)
  Bern_collection_min_est_rec_TCC2: OBLIGATION
    FORALL (BC: Bernstein_MinMax_Collection, np: below(BC`number_polys)):
      NOT np = 0 IMPLIES 0 < BC`number_polys;

  % Subtype TCC generated (at line 339, column 91) for  np - 1
      % expected type  below(BC`number_polys)
  Bern_collection_min_est_rec_TCC3: OBLIGATION
    FORALL (BC: Bernstein_MinMax_Collection, np: below(BC`number_polys)):
      NOT np = 0 IMPLIES np - 1 >= 0 AND np - 1 < BC`number_polys;

  % Termination TCC generated (at line 339, column 59) for
      % Bern_collection_min_est_rec(BC)(np - 1)
  Bern_collection_min_est_rec_TCC4: OBLIGATION
    FORALL (BC: Bernstein_MinMax_Collection, np: below(BC`number_polys)):
      NOT np = 0 IMPLIES np - 1 < np;

  % Subtype TCC generated (at line 343, column 65) for  BC`number_polys - 1
      % expected type  below(BC`number_polys)
  Bern_collection_min_est_TCC1: OBLIGATION
    FORALL (BC: Bernstein_MinMax_Collection):
      BC`number_polys /= 0 IMPLIES
       BC`number_polys - 1 >= 0 AND BC`number_polys - 1 < BC`number_polys;

  % Subtype TCC generated (at line 356, column 39) for  BC`number_polys - 1
      % expected type  below(BC`number_polys)
  Bern_collection_reduce_min_TCC1: OBLIGATION
    FORALL (BC: Bernstein_MinMax_Collection):
      BC`number_polys - 1 >= 0 AND BC`number_polys - 1 < BC`number_polys;


body:
  poly_rew : THEORY
  BEGIN

    IMPORTING polynomials

    p,q : VAR sequence[real]
    x,k : VAR real
    n   : VAR nat

    poly_sum : LEMMA
      polynomial(p,n)(x)+polynomial(q,n)(x) = polynomial(p+q,n)(x)

    poly_neg : LEMMA
     -polynomial(p,n)(x) = polynomial(-p,n)(x) 

    poly_diff : LEMMA
      polynomial(p,n)(x)-polynomial(q,n)(x) = polynomial(p-q,n)(x)

    poly_scal : LEMMA 
      k*polynomial(p,n)(x) = polynomial(k*p,n)(x)

  END poly_rew


body:
  % A few lemmas about min and max 
  min_max : THEORY
  BEGIN

    nnx   : VAR nnreal
    npx   : VAR npreal
    x,y,z : VAR real
    px    : VAR posreal

    min_id : LEMMA
      min(x,x) = x

    max_id : LEMMA
      max(x,x) = x

    min_comm : LEMMA
      min(x,y) = min(y,x)

    max_nnreal_0 : LEMMA
      FORALL(x:nnreal): max(x,0) = x

    max_0_nnreal : LEMMA
      FORALL(x:nnreal): max(0,x) = x

    min_nnreal_0 : LEMMA
      FORALL(x:nnreal): min(x,0) = 0

    min_0_nnreal : LEMMA
      FORALL(x:nnreal): min(0,x) = 0

    min_npreal_0 : LEMMA
      FORALL(x:npreal): min(x,0) = x

    min_0_npreal : LEMMA
      FORALL(x:npreal): min(0,x) = x

    max_npreal_0 : LEMMA
      FORALL(x:npreal): max(x,0) = 0

    max_0_npreal : LEMMA
      FORALL(x:npreal): max(0,x) = 0

    max_comm : LEMMA
      max(x,y) = max(y,x)

    min_assoc : LEMMA
      min(min(x,y),z) = min(x,min(y,z))

    max_assoc : LEMMA
      max(max(x,y),z) = max(x,max(y,z))
      
    min_max_id : LEMMA
      min(x,y)+max(x,y) = x+y

    min_max : LEMMA
      min(x,y) = -max(-x,-y)

    max_min : LEMMA
      max(x,y) = -min(-x,-y)

    add_min : LEMMA
      z+min(x,y) = min(z+x,z+y)

    min_sub : LEMMA
      min(x,y)-z = min(x-z,y-z)

    sub_min : LEMMA
      z-min(x,y) = max(z-x,z-y)

    add_max : LEMMA
      z+max(x,y) = max(z+x,z+y)

    max_sub : LEMMA
      max(x,y)-z = max(x-z,y-z)

    sub_max : LEMMA
      z-max(x,y) = min(z-x,z-y)

    abs_max : LEMMA
      abs(x) = max(x,-x)

    abs_min : LEMMA
      abs(x) = -min(x,-x)

    max_abs : LEMMA
      max(x,y) = (x+y+abs(x-y))/2

    nneg_mult_min : LEMMA
      nnx*min(y,z) = min(nnx*y,nnx*z) 

    npos_mult_min : LEMMA
      npx*min(y,z) = max(npx*y,npx*z)

    nneg_mult_max : LEMMA
      nnx*max(y,z) = max(nnx*y,nnx*z) 

    npos_mult_max : LEMMA
      npx*max(y,z) = min(npx*y,npx*z)

    min_div_pos : LEMMA
      min(y,z)/px = min(y/px,z/px) 

    max_div_pos : LEMMA
      max(y,z)/px = max(y/px,z/px) 

    min_le_max_left : LEMMA
      min(max(x,y),z) <= max(min(x,y),z)

    min_le_max_right : LEMMA
      min(max(x,y),z) <= max(x,min(y,z))

    max_rec(F:[nat->real],j:nat,(k:nat|j<=k)): RECURSIVE {r:real|
      (EXISTS (i:nat): j<=i AND i<=k AND F(i)=r) AND
      (FORALL (i:nat): j<=i AND i<=k IMPLIES F(i)<=r)} =
      IF k = j THEN F(j) ELSE
      max(F(k),max_rec(F,j,k-1)) ENDIF
      MEASURE k

    min_rec(F:[nat->real],j:nat,(k:nat|j<=k)): RECURSIVE {r:real|
      (EXISTS (i:nat): j<=i AND i<=k AND F(i)=r) AND
      (FORALL (i:nat): j<=i AND i<=k IMPLIES F(i)>=r)} =
      IF k = j THEN F(j) ELSE
      min(F(k),min_rec(F,j,k-1)) ENDIF
      MEASURE k

    AUTO_REWRITE+ min_id
    AUTO_REWRITE+ max_id
    AUTO_REWRITE+ max_nnreal_0
    AUTO_REWRITE+ max_0_nnreal
    AUTO_REWRITE+ min_nnreal_0
    AUTO_REWRITE+ min_0_nnreal
    AUTO_REWRITE+ min_npreal_0
    AUTO_REWRITE+ min_0_npreal
    AUTO_REWRITE+ max_npreal_0
    AUTO_REWRITE+ max_0_npreal


  END min_max

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

  % Subtype TCC generated (at line 115, column 18) for  F(j)
      % expected type  {r: real |
                     %          (EXISTS (i: nat):
                     %             j <= i AND i <= k AND F(i) = r)
                     %           AND
                     %           (FORALL (i: nat):
                     %              j <= i AND i <= k IMPLIES F(i) <= r)}
  max_rec_TCC1: OBLIGATION
    FORALL (F: [nat -> real], j: nat, (k: nat | j <= k)):
      k = j IMPLIES
       (EXISTS (i: nat): j <= i AND i <= k AND F(i) = F(j)) AND
        (FORALL (i: nat): j <= i AND i <= k IMPLIES F(i) <= F(j));

  % Subtype TCC generated (at line 116, column 25) for  k - 1
      % expected type  {k: nat | j <= k}
  max_rec_TCC2: OBLIGATION
    FORALL (j: nat, (k: nat | j <= k)):
      NOT k = j IMPLIES k - 1 >= 0 AND j <= k - 1;

  % Termination TCC generated (at line 116, column 13) for
      % max_rec(F, j, k - 1)
  max_rec_TCC3: OBLIGATION
    FORALL (j: nat, (k: nat | j <= k)): NOT k = j IMPLIES k - 1 < k;

  % Subtype TCC generated (at line 116, column 4) for
      % max(F(k), max_rec(F, j, k - 1))
      % expected type  {r: real |
                     %          (EXISTS (i: nat):
                     %             j <= i AND i <= k AND F(i) = r)
                     %           AND
                     %           (FORALL (i: nat):
                     %              j <= i AND i <= k IMPLIES F(i) <= r)}
  max_rec_TCC4: OBLIGATION
    FORALL (F: [nat -> real], j: nat, (k: nat | j <= k),
            v:
              [d1:
                 {z: [[nat -> real], j: nat, {k: nat | j <= k}] | z`3 < k} ->
                 {r: real |
                          (EXISTS (i: nat):
                             d1`2 <= i AND i <= d1`3 AND d1`1(i) = r)
                           AND
                           (FORALL (i: nat):
                              d1`2 <= i AND i <= d1`3 IMPLIES
                               d1`1(i) <= r)}]):
      NOT k = j IMPLIES
       (EXISTS (i: nat):
          j <= i AND i <= k AND F(i) = max(F(k), v(F, j, k - 1)))
        AND
        (FORALL (i: nat):
           j <= i AND i <= k IMPLIES F(i) <= max(F(k), v(F, j, k - 1)));

  % Subtype TCC generated (at line 122, column 18) for  F(j)
      % expected type  {r: real |
                     %          (EXISTS (i: nat):
                     %             j <= i AND i <= k AND F(i) = r)
                     %           AND
                     %           (FORALL (i: nat):
                     %              j <= i AND i <= k IMPLIES F(i) >= r)}
  min_rec_TCC1: OBLIGATION
    FORALL (F: [nat -> real], j: nat, (k: nat | j <= k)):
      k = j IMPLIES
       (EXISTS (i: nat): j <= i AND i <= k AND F(i) = F(j)) AND
        (FORALL (i: nat): j <= i AND i <= k IMPLIES F(i) >= F(j));

  % Subtype TCC generated (at line 123, column 4) for
      % min(F(k), min_rec(F, j, k - 1))
      % expected type  {r: real |
                     %          (EXISTS (i: nat):
                     %             j <= i AND i <= k AND F(i) = r)
                     %           AND
                     %           (FORALL (i: nat):
                     %              j <= i AND i <= k IMPLIES F(i) >= r)}
  min_rec_TCC2: OBLIGATION
    FORALL (F: [nat -> real], j: nat, (k: nat | j <= k),
            v:
              [d1:
                 {z: [[nat -> real], j: nat, {k: nat | j <= k}] | z`3 < k} ->
                 {r: real |
                          (EXISTS (i: nat):
                             d1`2 <= i AND i <= d1`3 AND d1`1(i) = r)
                           AND
                           (FORALL (i: nat):
                              d1`2 <= i AND i <= d1`3 IMPLIES
                               d1`1(i) >= r)}]):
      NOT k = j IMPLIES
       (EXISTS (i: nat):
          j <= i AND i <= k AND F(i) = min(F(k), v(F, j, k - 1)))
        AND
        (FORALL (i: nat):
           j <= i AND i <= k IMPLIES F(i) >= min(F(k), v(F, j, k - 1)));


body:
  more_polynomial_props: THEORY
  BEGIN

    IMPORTING polynomials,sign,log_nat,min_max

    a,b,h : VAR sequence[real]
    n   : VAR nat
    m,p   : VAR nat
    x,y,z : VAR real

    polynomial_degree_existence: LEMMA
      ((EXISTS (x): polynomial(a,n)(x)/=0) OR
       (EXISTS (i:upto(n)): a(i)/=0))
      IMPLIES
      EXISTS (i:upto(n)): a(i)/=0 AND
        (FORALL (j:nat): j>i AND j<=n IMPLIES a(j) = 0) AND
        polynomial(a,n) = polynomial(a,i)

    square_free?(a,n): bool =
      FORALL (y:real,g:sequence[real],k:nat): polynomial(a,n)(y)=0 AND
        (FORALL (x:real): polynomial(a,n)(x) = (x-y)*polynomial(g,k)(x))
        IMPLIES
        polynomial(g,k)(y)/=0

    poly_deriv_limit: LEMMA
      FORALL (y:real,epsil:posreal,pn:posnat): EXISTS (delta:posreal):
        FORALL (x:real): abs(x-y)<delta AND x/=y IMPLIES
          abs(polynomial(poly_deriv(a),pn-1)(y) - 
  	    (polynomial(a,pn)(x)-polynomial(a,pn)(y))/(x-y)) < epsil

    square_free_min: LEMMA
      FORALL (epsil:posreal,y,c:real,pn:posnat): polynomial(a,pn)(y) = c AND 
    	(FORALL (x:real): abs(x-y)<epsil IMPLIES polynomial(a,pn)(x)>=c)
    	IMPLIES
    	polynomial(poly_deriv(a),pn-1)(y) = 0
      
    square_free_max: LEMMA
      FORALL (epsil:posreal,y,c:real,pn:posnat): polynomial(a,pn)(y) = c AND 
    	(FORALL (x:real): abs(x-y)<epsil IMPLIES polynomial(a,pn)(x)<=c)
    	IMPLIES
    	polynomial(poly_deriv(a),pn-1)(y) = 0


    IMPORTING binomial_identities

    deriv_poly_shift: LEMMA n>0 AND (FORALL (i:nat):i>n IMPLIES a(i)=0)
    		    	  IMPLIES
  			  poly_deriv(poly_shift(a,n)(y)) =
    		    	  poly_shift(poly_deriv(a),n-1)(y)

    linear_power_is_differentiable: LEMMA
      m>0 IMPLIES EXISTS (a): a(m)=1 AND
      (FORALL (i:nat): i>m IMPLIES a(i)=0) AND
      (FORALL (x): polynomial(a,m)(x) = (x-y)^m) AND
      (FORALL (x): polynomial(poly_deriv(a),m-1)(x)=m*(x-y)^(m-1))

    polynomial_prod_degrees: LEMMA
      FORALL (a,b,g:[nat->real],n,m,p:nat):
      (FORALL (x): polynomial(a,n)(x) = polynomial(b,m)(x)*polynomial(g,p)(x)) AND
      a(n)/=0 AND b(m)/=0 AND g(p)/=0 IMPLIES
      (n=m+p AND FORALL (i:nat): i<=n IMPLIES a(i) = polynomial_prod(b,m,g,p)(i))

    polynomial_div_linear_power_degree: LEMMA
      FORALL (a,b:[nat->real],n,m,k:nat):
        (FORALL (x): polynomial(a,n)(x) = (x-y)^k*polynomial(b,m)(x)) AND
        a(n)/=0 AND b(m)/=0
        IMPLIES
        (a(n)=b(m) AND n=m+k)

    poly_deriv_signs_neq_around_root_left: LEMMA n>0 AND
      x < y AND 
      polynomial(a,n)(y) = 0 AND
      (FORALL (z:real): x<=z AND z<=y AND 
      	    	      (polynomial(a,n)(z)=0 OR polynomial(poly_deriv(a),n-1)(z)=0)
  		      IMPLIES z=y)
      IMPLIES sign_ext(polynomial(a,n)(x)) = -sign_ext(polynomial(poly_deriv(a),n-1)(x))

    poly_deriv_signs_neq_around_root_right: LEMMA n>0 AND
      x > y AND 
      polynomial(a,n)(y) = 0 AND
      (FORALL (z:real): y<=z AND z<=x AND 
      	    	      (polynomial(a,n)(z)=0 OR polynomial(poly_deriv(a),n-1)(z)=0)
  		      IMPLIES z=y)
      IMPLIES sign_ext(polynomial(a,n)(x)) = sign_ext(polynomial(poly_deriv(a),n-1)(x))

    % Every polynomial is divisible by a maximal power (x-y)^m

    max_linear_div_power?(a,n,y)(m:posnat): bool =
      EXISTS (b,q:[nat->real]): m<=n AND
        (FORALL (x): polynomial(a,n)(x)=(x-y)^m*polynomial(b,n-m)(x)) AND
        polynomial(b,n-m)(y)/=0 AND
        (FORALL (x): polynomial(poly_deriv(a),n-1)(x) = (x-y)^(m-1)*polynomial(q,n-m)(x)) AND
        polynomial(q,n-m)(y)/=0

    max_linear_div_power_rew: LEMMA FORALL (m:posnat):
      max_linear_div_power?(a,n,y)(m) IFF
      (m<=n AND EXISTS (b:[nat->real]):
        (FORALL (x): polynomial(a,n)(x)=(x-y)^m*polynomial(b,n-m)(x)) AND
         polynomial(b,n-m)(y)/=0)

    max_linear_div_power_rew2: LEMMA FORALL (m:posnat):
      max_linear_div_power?(a,n,y)(m) IFF
      (EXISTS (b:[nat->real],k:nat):
        (FORALL (x): polynomial(a,n)(x)=(x-y)^m*polynomial(b,k)(x)) AND
         polynomial(b,k)(y)/=0)

    max_linear_div_power_unique: LEMMA FORALL (m,kp:posnat):
      max_linear_div_power?(a,n,y)(m) AND
      max_linear_div_power?(a,n,y)(kp)
      IMPLIES
      m=kp

    max_linear_div_power_additive: LEMMA FORALL (m,kp:posnat,b:[nat->real],k:nat):
      max_linear_div_power?(b,k,y)(kp) AND
      (FORALL (x): polynomial(a,n)(x)=(x-y)^m*polynomial(b,k)(x))
      IMPLIES
      max_linear_div_power?(a,n,y)(m+kp)

    max_linear_div_power_derivative: LEMMA
      FORALL (m:posnat): m>1 IMPLIES
        (max_linear_div_power?(a,n,y)(m) IMPLIES
        (n>0 AND max_linear_div_power?(poly_deriv(a),n-1,y)(m-1)))

    % compute_max_lin_div_pow(a,(n|a(n)/=0),y): RECURSIVE {k:nat| 
    %   (k=0 IMPLIES polynomial(a,n)(y)/=0) AND
    %   (k>0 IMPLIES max_linear_div_power?(a,n,y)(k))} =
    %     IF polynomial(a,n)(y)/=0 THEN 0
    %     ELSIF n = 1 THEN 1
    %     ELSIF 

    poly_max_zero_power: LEMMA polynomial(a,n)(y)=0 AND a(n)/=0 IMPLIES
      EXISTS (m:posnat): max_linear_div_power?(a,n,y)(m)

    max_linear_div_power_scal: LEMMA FORALL (nz:nzreal,m:posnat):
      max_linear_div_power?(a,n,y)(m) IFF
      max_linear_div_power?(nz*a,n,y)(m)

    max_linear_div_power_lower_bound: LEMMA FORALL (b:[nat->real],k,j:nat,m:posnat):
      max_linear_div_power?(a,n,y)(m) AND
      (FORALL (x): polynomial(a,n)(x)=(x-y)^k*polynomial(b,j)(x))
      IMPLIES
      k<=m AND (k=m IFF polynomial(b,j)(y)/=0)

    div_linear_power_reduces: LEMMA FORALL (b:[nat->real],k,j,d:nat):
      (FORALL (x): polynomial(a,n)(x) = (x-y)^k*polynomial(b,j)(x))
      AND k>=d IMPLIES
      (EXISTS (bb:[nat->real],q:nat): 
        FORALL (x): polynomial(a,n)(x) = (x-y)^d*polynomial(bb,q)(x))

    max_linear_div_power_sign_change: LEMMA FORALL (m:posnat):
      x < y AND y < z AND
      (FORALL (r:real): x<= r AND r<= z AND polynomial(a,n)(r) = 0
      	    IMPLIES r = y) AND
      max_linear_div_power?(a,n,y)(m)
      IMPLIES
      LET sigx = sign_ext(polynomial(a,n)(x)), sigz = sign_ext(polynomial(a,n)(z)) IN
        sigx/=0 AND sigz/=0 AND
        ((even?(m) AND (NOT odd?(m)) AND sigx = sigz AND sigx/=-sigz)
         OR
         (odd?(m) AND (NOT even?(m)) AND sigx = -sigz AND sigx/=sigz))

    poly_eq_except_on_finite_set: LEMMA FORALL (b:[nat->real]):
      FORALL (N:posnat): (EXISTS (rootseq:[below(N)->real]): 
          FORALL (x): (FORALL (ib:below(N)): x/=rootseq(ib)) IMPLIES
  	   polynomial(a,n)(x)=polynomial(b,m)(x))
      IMPLIES ((FORALL (j:nat): j<=n AND j>min(n,m) IMPLIES a(j)=0) AND
      	    (FORALL (j:nat): j<=m AND j>min(n,m) IMPLIES b(j)=0) AND
  	    (FORALL (j:nat): j<=min(n,m) IMPLIES a(j) = b(j)) AND
  	    polynomial(a,n) = polynomial(b,m))

    max_div_linear_power_remainder_sign_swaps: LEMMA
      FORALL (p,q,h,r:[nat->real],pn,qn,hn,rn:nat,m,kp:posnat):
      x<y AND y<z AND
      (FORALL (xyz:real): polynomial(p,pn)(xyz)=
        polynomial(q,qn)(xyz)*polynomial(h,hn)(xyz)
          +polynomial(r,rn)(xyz)) AND
      (FORALL (xyz:real): x<=xyz AND xyz<=z AND
        (polynomial(p,pn)(xyz)=0 OR polynomial(h,hn)(xyz)=0 OR polynomial(r,rn)(xyz)=0)
        IMPLIES xyz = y) AND
      max_linear_div_power?(p,pn,y)(m) AND
      max_linear_div_power?(r,rn,y)(m) AND
      max_linear_div_power?(h,hn,y)(kp) AND
      kp>m
      IMPLIES
      (sign_ext(polynomial(p,pn)(x))*sign_ext(polynomial(-r,rn)(x)) = -1 AND
       sign_ext(polynomial(p,pn)(z))*sign_ext(polynomial(-r,rn)(z)) = -1)

    at_zero_remainder_sign_swaps: LEMMA
      FORALL (p,q,h,r:[nat->real],pn,qn,hn,rn:nat):
      x<=y AND y<=z AND
      (FORALL (xyz:real): polynomial(p,pn)(xyz)=
        polynomial(q,qn)(xyz)*polynomial(h,hn)(xyz)
          +polynomial(r,rn)(xyz)) AND
      (FORALL (xyz:real): x<=xyz AND xyz<=z AND
        (polynomial(p,pn)(xyz)=0 OR polynomial(h,hn)(xyz)=0 OR polynomial(r,rn)(xyz)=0)
        IMPLIES xyz = y) AND
     polynomial(h,hn)(y)=0 AND
     polynomial(p,pn)(y)/=0 AND
     polynomial(r,rn)(y)/=0 AND
     polynomial(p,pn)(x)/=0 AND
     polynomial(r,rn)(x)/=0 AND
     polynomial(p,pn)(z)/=0 AND
     polynomial(r,rn)(z)/=0
      IMPLIES
      (sign_ext(polynomial(p,pn)(x))*sign_ext(polynomial(-r,rn)(x)) = -1 AND
       sign_ext(polynomial(p,pn)(z))*sign_ext(polynomial(-r,rn)(z)) = -1)

    %%% All derivatives vanish %%%

    poly_all_derivs_vanish: LEMMA
      (FORALL (i:nat): i<=n IMPLIES polynomial(poly_n_deriv(a,n-i),i)(x)=0)
      IFF
      (FORALL (i:nat): i<=n IMPLIES a(i)=0)


    %%% sign of polynomial values near infinity %%%

    poly_sign_near_infinity: LEMMA a(n)/=0 IMPLIES
      EXISTS (M:posnat): FORALL (x:real): x>=M IMPLIES
        sign_ext(polynomial(a,n)(x)) = sign_ext(a(n))

    poly_sign_near_negative_infinity: LEMMA a(n)/=0 IMPLIES
      EXISTS (M:posnat): FORALL (x:real): x<=-M IMPLIES
        sign_ext(polynomial(a,n)(x)) = sign_ext(IF even?(n) THEN a(n) ELSE -a(n) ENDIF)

    poly_coeff_bound(a,n): RECURSIVE {kr:posreal |
      FORALL (i:nat): i<=n IMPLIES abs(a(i))<kr} =
        IF n = 0 THEN abs(a(0))+1
        ELSE max(abs(a(n))+1,poly_coeff_bound(a,n-1))
        ENDIF MEASURE n
      
    poly_continuity_const(a,n,x,(epsil:posreal)): posreal =
      IF n = 0 THEN 1/2 ELSE 
        LET epcon = epsil/(poly_coeff_bound(a,n) *
                    (sigma(1,n,LAMBDA (i:nat): sigma(1,i,LAMBDA (j:nat): IF (j=0 OR j>i) THEN 0
  		  		    	     ELSE C(i,j-1)*abs(x)^(j-1) ENDIF)) + 1)) 
        IN min(epcon,1/2) 
      ENDIF


    poly_continuity_const_def: LEMMA FORALL (epsil:posreal):
        LET delt = poly_continuity_const(a,n,x,epsil)
        IN  FORALL (y:real): abs(x-y)<delt IMPLIES
        	  abs(polynomial(a,n)(y)-polynomial(a,n)(x))<epsil

    max_nonvanishing_deriv(a,n,x): 
      RECURSIVE {lastn:nat | lastn <= n AND
      		      ((EXISTS (ii:upto(n)): a(ii)/=0) 
    		        IMPLIES (polynomial(poly_n_deriv(a,n-lastn),lastn)(x)/=0 AND
      		      FORALL (i:nat): i>lastn AND i<=n IMPLIES 
    		      polynomial(poly_n_deriv(a,n-i),i)(x)=0))} =
      IF n=0 OR polynomial(a,n)(x)/=0 THEN n
      ELSE max_nonvanishing_deriv(poly_deriv(a),n-1,x) ENDIF
      MEASURE n

    poly_rootless_width(a,n,x,(nzb: bool | nzb 
            IFF (EXISTS (i:upto(n)): a(i)/=0))): posreal =
      LET maxn = max_nonvanishing_deriv(a,n,x)
      IN  IF nzb THEN poly_continuity_const(poly_n_deriv(a,n-maxn),maxn,x,
      	             abs(polynomial(poly_n_deriv(a,n-maxn),maxn)(x)))
      	ELSE 1 ENDIF

    poly_rootless_width_def: LEMMA
      (EXISTS (i:upto(n)): a(i)/=0) IMPLIES
      LET epsil=poly_rootless_width(a,n,x,TRUE),
      	mnd  =max_nonvanishing_deriv(a,n,x)
      IN  FORALL (y:real,j:nat): j<=n-mnd 
            AND polynomial(poly_n_deriv(a,j),n-j)(y)=0 AND abs(x-y)<epsil
  	  IMPLIES x=y

    poly_roots_enumerated: LEMMA (EXISTS (i:upto(n)): a(i)/=0)
      IMPLIES EXISTS (M:nat,rootseq:[below(M)->real]):
        (FORALL (i:below(M)): polynomial(a,n)(rootseq(i))=0)
        AND (FORALL (x:real): polynomial(a,n)(x)=0 IMPLIES
        	  	  EXISTS (i:below(M)): x=rootseq(i)) AND injective?(rootseq)

    min_poly_root_distance: LEMMA (EXISTS (i:upto(n)): a(i)/=0)
      IMPLIES EXISTS (epsil:posreal): FORALL (x,y:real):
      polynomial(a,n)(x)=0 AND polynomial(a,n)(y)=0 AND x/=y IMPLIES
      abs(x-y)>=epsil
      
    min_poly_root_dist(a,(n|a(n)/=0)): {epsil:posreal|FORALL (x,y:real):
      polynomial(a,n)(x)=0 AND polynomial(a,n)(y)=0 AND x/=y IMPLIES
      abs(x-y)>epsil}

    % The bound below is very similar to Cauchy's bound.

    poly_root_bound(a,(n|a(n)/=0)): {K:posreal| FORALL (x:real):
      polynomial(a,n)(x)=0 IMPLIES abs(x) < K} =
        max(2,sigma(0,n-1,LAMBDA (i:nat): abs(a(i)))/abs(a(n)) + 1)

    poly_cancel: LEMMA (EXISTS (i:nat):i<=p AND h(i)/=0) AND
      (FORALL (x): polynomial(h,p)(x)*polynomial(a,n)(x) =
      	    	 polynomial(h,p)(x)*polynomial(b,m)(x)) IMPLIES
      polynomial(a,n)=polynomial(b,m)

    % In order to make Knuth's bound useful, we need a way to comp kth root.
    % We follow the method of de Moura

    Knuth_bound_simple: LEMMA FORALL (r:real):
      a(n)=1 AND polynomial(a,n)(r)=0 AND r>0 AND n>0 IMPLIES
      EXISTS (k:subrange(1,n)): a(n-k)<0 AND r^k <= - 2^k * a(n-k)

    Knuth_poly_pos_root_bound(a,(n|a(n)=1 AND n>0)): {K:real| FORALL (x:real):
      polynomial(a,n)(x)=0 AND x>0 IMPLIES x <= K} =
        LET maxKfun = (LAMBDA (k:nat): IF 1<=k AND k<=n AND a(n-k)<0
        	    	       THEN LET aquot = -a(n-k),
  		       	    	log2j = least_pow_2_ge(aquot),
  				rootexp = floor(log2j/k)+1
  			    IN 2^rootexp
                         ELSE -1 ENDIF)
        IN 2*max_rec(maxKfun,1,n)

    Knuth_poly_root_bound(a,(n|a(n)/=0)): {K:nnreal| FORALL (x:real):
      polynomial(a,n)(x)=0 IMPLIES abs(x) <= K} =
        IF n=0 THEN 0
        ELSE
          LET negsign = (LAMBDA (i:nat): IF even?(i) THEN 1 ELSE -1 ENDIF),
  	    nega = (LAMBDA (i:nat): negsign(i)*negsign(n)*a(i)/a(n)),
  	    newa = (LAMBDA (i:nat): a(i)/a(n)),
  	    negbound = Knuth_poly_pos_root_bound(nega,n),
  	    posbound = Knuth_poly_pos_root_bound(newa,n)
          IN max(posbound,max(negbound,0))
        ENDIF

    Knuth_poly_root_strict_bound(a,(n|a(n)/=0)): {K:posreal| FORALL (x:real):
      polynomial(a,n)(x)=0 IMPLIES abs(x) < K} =
        LET Kprb = Knuth_poly_root_bound(a,n) IN
          IF    Kprb=0 THEN 1
          ELSIF polynomial(a,n)(Kprb)=0 OR polynomial(a,n)(-Kprb)=0 THEN 1.01*Kprb
  	ELSE  Kprb ENDIF
  	    

    poly_increasing_is_strict: LEMMA FORALL (xlb,yub:real):
      xlb < yub AND n > 0 AND a(n)/=0 IMPLIES
      ((FORALL (c:real): xlb <= c AND c <= yub IMPLIES polynomial(poly_deriv(a),n-1)(c) >= 0)
      IFF
      (FORALL (x,y:real): xlb <= x AND x<y AND y<=yub IMPLIES polynomial(a,n)(x) < polynomial(a,n)(y)))

    poly_increasing_is_strict2: LEMMA FORALL (xlb,yub:real):
      xlb < yub AND n > 0 AND a(n)/=0 IMPLIES
      ((FORALL (c:real): xlb <= c AND c <= yub IMPLIES polynomial(poly_deriv(a),n-1)(c) >= 0)
      IFF
      (FORALL (x,y:real): xlb <= x AND x<y AND y<=yub IMPLIES polynomial(a,n)(x) <= polynomial(a,n)(y)))

    poly_decreasing_is_strict: LEMMA FORALL (xlb,yub:real):
      xlb < yub AND n > 0 AND a(n)/=0 IMPLIES
      ((FORALL (c:real): xlb <= c AND c <= yub IMPLIES polynomial(poly_deriv(a),n-1)(c) <= 0)
      IFF
      (FORALL (x,y:real): xlb <= x AND x<y AND y<=yub IMPLIES polynomial(a,n)(x) > polynomial(a,n)(y)))

    poly_decreasing_is_strict2: LEMMA FORALL (xlb,yub:real):
      xlb < yub AND n > 0 AND a(n)/=0 IMPLIES
      ((FORALL (c:real): xlb <= c AND c <= yub IMPLIES polynomial(poly_deriv(a),n-1)(c) <= 0)
      IFF
      (FORALL (x,y:real): xlb <= x AND x<y AND y<=yub IMPLIES polynomial(a,n)(x) >= polynomial(a,n)(y)))

    poly_injective_monotone: LEMMA FORALL (xlb,yub:real):
      xlb < yub AND n > 0 AND a(n)/=0 IMPLIES
      ((FORALL (x,y:real): xlb <= x AND x<y AND y<=yub IMPLIES polynomial(a,n)(x) /= polynomial(a,n)(y))
      IFF
      ((FORALL (x,y:real): xlb <= x AND x<y AND y<=yub IMPLIES polynomial(a,n)(x) > polynomial(a,n)(y)) OR
       (FORALL (x,y:real): xlb <= x AND x<y AND y<=yub IMPLIES polynomial(a,n)(x) < polynomial(a,n)(y))))

    % Max root is like max_linear_div_power, but more robust.

    root_degree(a,n)(y): RECURSIVE {m| m<=n AND (a(n)/=0 IMPLIES
      ((EXISTS (b:[nat->real]): (FORALL (x): polynomial(a,n)(x)=(x-y)^m*polynomial(b,n-m)(x)) AND
        polynomial(b,n-m)(y)/=0 AND b(n-m)/=0) AND
      (polynomial(a,n)(y)=0 IMPLIES m>0) AND
      ((n>0 AND m>0) IMPLIES (EXISTS (q:[nat->real]): (FORALL (x): polynomial(poly_deriv(a),n-1)(x) = 
               (x-y)^(m-1)*polynomial(q,n-m)(x)) AND
        polynomial(q,n-m)(y)/=0))))} =
      IF polynomial(a,n)(y)/=0 OR n=0 THEN 0
      ELSE 1+root_degree(poly_shift(LAMBDA (i:nat): poly_shift(a,n)(y)(i+1),n-1)(-y),n-1)(y)
      ENDIF MEASURE n

    root_degree_pos: LEMMA a(n)/=0 IMPLIES
      (polynomial(a,n)(y)=0 IFF root_degree(a,n)(y)>0)

    root_degree_max_linear_div_power: LEMMA a(n)/=0 AND
      (polynomial(a,n)(y)=0 OR root_degree(a,n)(y)>0) IMPLIES
       max_linear_div_power?(a,n,y)(root_degree(a,n)(y))

    root_degree_unique: LEMMA
      a(n)/=0 AND m<=n AND (EXISTS (b:[nat->real]): (FORALL (x): 
        polynomial(a,n)(x)=(x-y)^m*polynomial(b,n-m)(x)) AND
        polynomial(b,n-m)(y)/=0) IMPLIES
        m = root_degree(a,n)(y)

    only_root_between?(a,n,x,y)(z): bool =
      x<z AND z<y AND 
      (FORALL (r:real): x<=r AND r<=y AND r/=z IMPLIES
        polynomial(a,n)(r)/=0)

    root_degree_odd: LEMMA a(n)/=0 AND only_root_between?(a,n,x,y)(z) IMPLIES
      (odd?(root_degree(a,n)(z)) IFF sign_ext(polynomial(a,n)(x))=
      			          -sign_ext(polynomial(a,n)(y)))

    root_degree_even: LEMMA a(n)/=0 AND only_root_between?(a,n,x,y)(z) IMPLIES
      (even?(root_degree(a,n)(z)) IFF sign_ext(polynomial(a,n)(x))=
      			          sign_ext(polynomial(a,n)(y)))

    root_degree_deriv: LEMMA a(n)/=0 AND polynomial(a,n)(y)=0 AND n>0 IMPLIES
      root_degree(poly_deriv(a),n-1)(y) = root_degree(a,n)(y)-1

    root_degree_mult: LEMMA a(n)/=0 AND b(m)/=0 IMPLIES
      root_degree(polynomial_prod(a,n,b,m),n+m)(y) = root_degree(a,n)(y)+root_degree(b,m)(y)

    root_degree_scal: LEMMA a(n)/=0 AND x/=0 IMPLIES
      root_degree(x*a,n)(y) = root_degree(a,n)(y)

    root_degree_power_linear: LEMMA
      root_degree(power_linear(-y, 1, m),m)(y) = m

    root_degree_eq: LEMMA a(n)/=0 AND
      (FORALL (i:upto(n)): a(i)=b(i)) IMPLIES
      root_degree(a,n)(y) = root_degree(b,n)(y)

    root_degree_lower_bound: LEMMA FORALL (k:nat):
      a(n)/=0 AND (EXISTS (b:[nat->real]): b(k)/=0 AND (FORALL (x):
        polynomial(a,n)(x)=(x-y)^m*polynomial(b,k)(x))) IMPLIES
        (k=n-m AND root_degree(a,n)(y)>=m)

    root_degree_division: LEMMA 
      FORALL (a,b,g,h:[nat->real],n,m,k,p:nat):
      (FORALL (x:real): polynomial(a,n)(x) = 
  	  polynomial(g,k)(x)*polynomial(b,m)(x)
  	    + polynomial(h,p)(x)) AND h(p)/=0 AND
      a(n)/=0 AND b(m)/=0 IMPLIES
      ((root_degree(a,n)(y)<root_degree(b,m)(y) IMPLIES
        root_degree(h,p)(y)=root_degree(a,n)(y)) AND
       root_degree(h,p)(y)>=
       min(root_degree(a,n)(y),root_degree(b,m)(y)))

    signs_swap_division: LEMMA 
      FORALL (a,b,g,h:[nat->real],n,m,k,p:nat):
      only_root_between?(a,n,x,y)(z) AND
      only_root_between?(b,m,x,y)(z) AND
      only_root_between?(h,p,x,y)(z) AND
      (FORALL (r:real): polynomial(a,n)(r) = 
  	  polynomial(g,k)(r)*polynomial(b,m)(r)
  	    + polynomial(h,p)(r)) AND h(p)/=0 AND
      a(n)/=0 AND b(m)/=0 AND
      root_degree(a,n)(z)=root_degree(h,p)(z) AND
      root_degree(b,m)(z)>=root_degree(h,p)(z) IMPLIES
       ((sign_ext(polynomial(a,n)(x))*sign_ext(polynomial(h,p)(x))=1 AND
         sign_ext(polynomial(a,n)(y))*sign_ext(polynomial(h,p)(y))=1) OR
         (EXISTS (sig:Sign): (FORALL (abh:[nat->real],kz:nat): 
           ((abh=a AND kz=n) OR (abh=b AND kz=m) OR (abh=h AND kz=p)) IMPLIES
  	 sign_ext(polynomial(abh,kz)(x)) = sig*sign_ext(polynomial(abh,kz)(y)))))

  END more_polynomial_props

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

  % Subtype TCC generated (at line 28, column 37) for  pn - 1
      % expected type  nat
  poly_deriv_limit_TCC1: OBLIGATION
    FORALL (y: real, pn: posnat, delta: posreal, x: real):
      abs(x - y) < delta AND x /= y IMPLIES pn - 1 >= 0;

  % Subtype TCC generated (at line 29, column 48) for  (x - y)
      % expected type  nznum
  poly_deriv_limit_TCC2: OBLIGATION
    FORALL (y: real, delta: posreal, x: real):
      abs(x - y) < delta AND x /= y IMPLIES (x - y) /= 0;

  % Subtype TCC generated (at line 35, column 28) for  pn - 1
      % expected type  nat
  square_free_min_TCC1: OBLIGATION
    FORALL (a: sequence[real], epsil: posreal, y, c: real, pn: posnat):
      (polynomial(a, pn)(y) = c AND
        (FORALL (x: real):
           abs(x - y) < epsil IMPLIES polynomial(a, pn)(x) >= c))
       IMPLIES pn - 1 >= 0;

  % Subtype TCC generated (at line 41, column 28) for  pn - 1
      % expected type  nat
  square_free_max_TCC1: OBLIGATION
    FORALL (a: sequence[real], epsil: posreal, y, c: real, pn: posnat):
      (polynomial(a, pn)(y) = c AND
        (FORALL (x: real):
           abs(x - y) < epsil IMPLIES polynomial(a, pn)(x) <= c))
       IMPLIES pn - 1 >= 0;

  % Subtype TCC generated (at line 49, column 36) for  n - 1
      % expected type  nat
  deriv_poly_shift_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat):
      (FORALL (i: nat): i > n IMPLIES a(i) = 0) AND n > 0 IMPLIES n - 1 >= 0;

  % Subtype TCC generated (at line 54, column 44) for  m
      % expected type  {i: int | (x - y) /= 0 OR i >= 0}
  linear_power_is_differentiable_TCC1: OBLIGATION
    FORALL (m: nat, y: real):
      m > 0 IMPLIES
       (FORALL (a: sequence[real]):
          (FORALL (i: nat): i > m IMPLIES a(i) = 0) AND a(m) = 1 IMPLIES
           (FORALL (x: real): (x - y) /= 0 OR m >= 0));

  % Subtype TCC generated (at line 65, column 46) for  k
      % expected type  {i: int | (x - y) /= 0 OR i >= 0}
  polynomial_div_linear_power_degree_TCC1: OBLIGATION
    FORALL (y: real, k: nat, x: real): (x - y) /= 0 OR k >= 0;

  % Subtype TCC generated (at line 74, column 66) for  n - 1
      % expected type  nat
  poly_deriv_signs_neq_around_root_left_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat, x, y: real):
      n > 0 AND x < y AND polynomial(a, n)(y) = 0 IMPLIES
       (FORALL (z: real):
          NOT polynomial(a, n)(z) = 0 AND z <= y AND x <= z IMPLIES
           n - 1 >= 0);

  % Subtype TCC generated (at line 76, column 78) for  n - 1
      % expected type  nat
  poly_deriv_signs_neq_around_root_left_TCC2: OBLIGATION
    FORALL (a: sequence[real], n: nat, x, y: real):
      (FORALL (z: real):
         x <= z AND
          z <= y AND
           (polynomial(a, n)(z) = 0 OR
             polynomial(poly_deriv(a), n - 1)(z) = 0)
          IMPLIES z = y)
       AND polynomial(a, n)(y) = 0 AND x < y AND n > 0
       IMPLIES n - 1 >= 0;

  % Subtype TCC generated (at line 82, column 66) for  n - 1
      % expected type  nat
  poly_deriv_signs_neq_around_root_right_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat, x, y: real):
      n > 0 AND x > y AND polynomial(a, n)(y) = 0 IMPLIES
       (FORALL (z: real):
          NOT polynomial(a, n)(z) = 0 AND z <= x AND y <= z IMPLIES
           n - 1 >= 0);

  % Subtype TCC generated (at line 84, column 77) for  n - 1
      % expected type  nat
  poly_deriv_signs_neq_around_root_right_TCC2: OBLIGATION
    FORALL (a: sequence[real], n: nat, x, y: real):
      (FORALL (z: real):
         y <= z AND
          z <= x AND
           (polynomial(a, n)(z) = 0 OR
             polynomial(poly_deriv(a), n - 1)(z) = 0)
          IMPLIES z = y)
       AND polynomial(a, n)(y) = 0 AND x > y AND n > 0
       IMPLIES n - 1 >= 0;

  % Subtype TCC generated (at line 90, column 44) for  m
      % expected type  {i: int | (x - y) /= 0 OR i >= 0}
  max_linear_div_power?_TCC1: OBLIGATION
    FORALL (n: nat, y: real, m: posnat):
      m <= n IMPLIES (FORALL (x: real): (x - y) /= 0 OR m >= 0);

  % Subtype TCC generated (at line 90, column 59) for  n - m
      % expected type  nat
  max_linear_div_power?_TCC2: OBLIGATION
    FORALL (n: nat, m: posnat): m <= n IMPLIES n - m >= 0;

  % Subtype TCC generated (at line 92, column 44) for  n - 1
      % expected type  nat
  max_linear_div_power?_TCC3: OBLIGATION
    FORALL (a: sequence[real], n: nat, y: real, m: posnat, b: [nat -> real]):
      polynomial(b, n - m)(y) /= 0 AND
       (FORALL (x):
          polynomial(a, n)(x) = (x - y) ^ m * polynomial(b, n - m)(x))
        AND m <= n
       IMPLIES n - 1 >= 0;

  % Subtype TCC generated (at line 92, column 61) for  (m - 1)
      % expected type  {i: int | (x - y) /= 0 OR i >= 0}
  max_linear_div_power?_TCC4: OBLIGATION
    FORALL (a: sequence[real], n: nat, y: real, m: posnat, b: [nat -> real]):
      polynomial(b, n - m)(y) /= 0 AND
       (FORALL (x):
          polynomial(a, n)(x) = (x - y) ^ m * polynomial(b, n - m)(x))
        AND m <= n
       IMPLIES (FORALL (x1: real): (x1 - y) /= 0 OR (m - 1) >= 0);

  % Subtype TCC generated (at line 104, column 44) for  m
      % expected type  {i: int | (x - y) /= 0 OR i >= 0}
  max_linear_div_power_rew2_TCC1: OBLIGATION
    FORALL (y: real, m: posnat, x: real): (x - y) /= 0 OR m >= 0;

  % Subtype TCC generated (at line 122, column 58) for  m - 1
      % expected type  posnat
  max_linear_div_power_derivative_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat, y: real, m: posnat):
      n > 0 AND max_linear_div_power?(a, n, y)(m) AND m > 1 IMPLIES
       m - 1 >= 0 AND m - 1 > 0;

  % Subtype TCC generated (at line 122, column 51) for  n - 1
      % expected type  nat
  max_linear_div_power_derivative_TCC2: OBLIGATION
    FORALL (a: sequence[real], n: nat, y: real, m: posnat):
      n > 0 AND max_linear_div_power?(a, n, y)(m) AND m > 1 IMPLIES
       n - 1 >= 0;

  % Subtype TCC generated (at line 148, column 45) for  d
      % expected type  {i: int | (x - y) /= 0 OR i >= 0}
  div_linear_power_reduces_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat, y: real, b: [nat -> real],
            k, j, d: nat):
      (FORALL (x): polynomial(a, n)(x) = (x - y) ^ k * polynomial(b, j)(x))
       AND k >= d
       IMPLIES (FORALL (x1: real): (x1 - y) /= 0 OR d >= 0);

  % Subtype TCC generated (at line 211, column 60) for  n - i
      % expected type  nat
  poly_all_derivs_vanish_TCC1: OBLIGATION
    FORALL (n, i: nat): i <= n IMPLIES n - i >= 0;

  % Subtype TCC generated (at line 228, column 20) for  abs(a(0)) + 1
      % expected type  {kr: posreal |
                     %          FORALL (i: nat):
                     %            i <= n IMPLIES abs(a(i)) < kr}
  poly_coeff_bound_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat):
      n = 0 IMPLIES
       (FORALL (i: nat): i <= n IMPLIES abs(a(i)) < abs(a(0)) + 1);

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

  % Termination TCC generated (at line 229, column 27) for
      % poly_coeff_bound(a, n - 1)
  poly_coeff_bound_TCC3: OBLIGATION
    FORALL (n: nat): NOT n = 0 IMPLIES n - 1 < n;

  % Subtype TCC generated (at line 229, column 11) for
      % max(abs(a(n)) + 1, poly_coeff_bound(a, n - 1))
      % expected type  {kr: posreal |
                     %          FORALL (i: nat):
                     %            i <= n IMPLIES abs(a(i)) < kr}
  poly_coeff_bound_TCC4: OBLIGATION
    FORALL (a: sequence[real], n: nat):
      NOT n = 0 IMPLIES
       (FORALL (i: nat),
               (v:
                  [d1: {z: [sequence[real], nat] | z`2 < n} ->
                     {kr: posreal |
                              FORALL (i_1: nat):
                                i_1 <= d1`2 IMPLIES abs(d1`1(i_1)) < kr}]):
          i <= n IMPLIES abs(a(i)) < max(abs(a(n)) + 1, v(a, n - 1)));

  % Subtype TCC generated (at line 235, column 27) for  n
      % expected type  T_high[nat]
  poly_continuity_const_TCC1: OBLIGATION
    FORALL (n: nat): NOT n = 0 IMPLIES n >= 0 OR (EXISTS (j: nat): n <= j);

  % Subtype TCC generated (at line 235, column 53) for  i
      % expected type  T_high[nat]
  poly_continuity_const_TCC2: OBLIGATION
    FORALL (n: nat):
      NOT n = 0 IMPLIES
       (FORALL (i: nat): i >= 0 OR (EXISTS (j: nat): i <= j));

  % Subtype TCC generated (at line 236, column 25) for  j - 1
      % expected type  {i_1: nat | i_1 <= i}
  poly_continuity_const_TCC3: OBLIGATION
    FORALL (n: nat):
      NOT n = 0 IMPLIES
       (FORALL (i: nat, j: nat):
          NOT j = 0 AND NOT j > i IMPLIES j - 1 >= 0 AND j - 1 <= i);

  % Subtype TCC generated (at line 236, column 38) for  (j - 1)
      % expected type  {i: int | abs(x) /= 0 OR i >= 0}
  poly_continuity_const_TCC4: OBLIGATION
    FORALL (n: nat, x: real):
      NOT n = 0 IMPLIES
       (FORALL (i: nat, j: nat):
          NOT j = 0 AND NOT j > i IMPLIES abs(x) /= 0 OR (j - 1) >= 0);

  % Subtype TCC generated (at line 234, column 25) for
      % (poly_coeff_bound(a, n) *
      %   (sigma(1, n,
      %          LAMBDA (i: nat):
      %            sigma(1, i,
      %                  LAMBDA (j: nat):
      %                    IF (j = 0 OR j > i) THEN 0
      %                    ELSE C(i, j - 1) * abs(x) ^ (j - 1)
      %                    ENDIF))
      %     + 1))
      % expected type  nznum
  poly_continuity_const_TCC5: OBLIGATION
    FORALL (a: sequence[real], n: nat, x: real):
      NOT n = 0 IMPLIES
       (poly_coeff_bound(a, n) *
         (sigma[nat]
              (1, n,
               LAMBDA (i: nat):
                 sigma[nat]
                     (1, i,
                      LAMBDA (j: nat):
                        IF (j = 0 OR j > i) THEN 0
                        ELSE C(i, j - 1) * abs(x) ^ (j - 1)
                        ENDIF))
           + 1))
        /= 0;

  % Subtype TCC generated (at line 237, column 9) for  min(epcon, 1 / 2)
      % expected type  posreal
  poly_continuity_const_TCC6: OBLIGATION
    FORALL (a: sequence[real], n: nat, x: real, (epsil: posreal)):
      NOT n = 0 IMPLIES
       (FORALL (epcon: nzreal):
          epcon =
           epsil /
            (poly_coeff_bound(a, n) *
              (sigma(1, n,
                     LAMBDA (i: nat):
                       sigma(1, i,
                             LAMBDA (j: nat):
                               IF (j = 0 OR j > i) THEN 0
                               ELSE C(i, j - 1) * abs(x) ^ (j - 1)
                               ENDIF))
                + 1))
           IMPLIES min(epcon, 1 / 2) >= 0 AND min(epcon, 1 / 2) > 0);

  % Subtype TCC generated (at line 252, column 41) for  n
      % expected type  {lastn: nat |
                     %          lastn <= n AND
                     %           ((EXISTS (ii: upto(n)): a(ii) /= 0) IMPLIES
                     %             (polynomial(poly_n_deriv(a, n - lastn),
                     %                         lastn)
                     %                        (x)
                     %               /= 0
                     %               AND
                     %               (FORALL
                     %                (i: nat):
                     %                i > lastn AND i <= n
                     %                IMPLIES
                     %                polynomial
                     %                (poly_n_deriv(a, n - i), i)(x)
                     %                =
                     %                0)))}
  max_nonvanishing_deriv_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat, x: real):
      n = 0 OR polynomial(a, n)(x) /= 0 IMPLIES
       n <= n AND
        ((EXISTS (ii: upto(n)): a(ii) /= 0) IMPLIES
          (polynomial(poly_n_deriv(a, n - n), n)(x) /= 0 AND
            (FORALL (i: nat):
               i > n AND i <= n IMPLIES
                polynomial(poly_n_deriv(a, n - i), i)(x) = 0)));

  % Subtype TCC generated (at line 253, column 9) for
      % max_nonvanishing_deriv(poly_deriv(a), n - 1, x)
      % expected type  {lastn: nat |
                     %          lastn <= n AND
                     %           ((EXISTS (ii: upto(n)): a(ii) /= 0) IMPLIES
                     %             (polynomial(poly_n_deriv(a, n - lastn),
                     %                         lastn)
                     %                        (x)
                     %               /= 0
                     %               AND
                     %               (FORALL
                     %                (i: nat):
                     %                i > lastn AND i <= n
                     %                IMPLIES
                     %                polynomial
                     %                (poly_n_deriv(a, n - i), i)(x)
                     %                =
                     %                0)))}
  max_nonvanishing_deriv_TCC2: OBLIGATION
    FORALL (a: sequence[real], n: nat,
            v:
              [d1: {z: [sequence[real], nat, real] | z`2 < n} ->
                 {lastn: nat |
                          lastn <= d1`2 AND
                           ((EXISTS (ii: upto(d1`2)): d1`1(ii) /= 0) IMPLIES
                             (polynomial(poly_n_deriv(d1`1, d1`2 - lastn),
                                         lastn)
                                        (d1`3)
                               /= 0
                               AND
                               (FORALL (i: nat):
                                  i > lastn AND i <= d1`2 IMPLIES
                                   polynomial(poly_n_deriv(d1`1, d1`2 - i), i)
                                             (d1`3)
                                    = 0)))}],
            x: real):
      NOT n = 0 AND NOT polynomial(a, n)(x) /= 0 IMPLIES
       v(poly_deriv(a), n - 1, x) <= n AND
        ((EXISTS (ii: upto(n)): a(ii) /= 0) IMPLIES
          (polynomial(poly_n_deriv(a, n - v(poly_deriv(a), n - 1, x)),
                      v(poly_deriv(a), n - 1, x))
                     (x)
            /= 0
            AND
            (FORALL (i: nat):
               i > v(poly_deriv(a), n - 1, x) AND i <= n IMPLIES
                polynomial(poly_n_deriv(a, n - i), i)(x) = 0)));

  % Subtype TCC generated (at line 259, column 57) for  n - maxn
      % expected type  nat
  poly_rootless_width_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat, x: real,
            (nzb: bool | nzb IFF (EXISTS (i: upto(n)): a(i) /= 0)),
            maxn:
              {lastn: nat |
                       lastn <= n AND
                        ((EXISTS (ii: upto(n)): a(ii) /= 0) IMPLIES
                          (polynomial(poly_n_deriv(a, n - lastn), lastn)(x)
                            /= 0
                            AND
                            (FORALL (i: nat):
                               i > lastn AND i <= n IMPLIES
                                polynomial(poly_n_deriv(a, n - i), i)(x) =
                                 0)))}):
      nzb AND maxn = max_nonvanishing_deriv(a, n, x) IMPLIES n - maxn >= 0;

  % Subtype TCC generated (at line 260, column 18) for
      % abs(polynomial(poly_n_deriv(a, n - maxn), maxn)(x))
      % expected type  posreal
  poly_rootless_width_TCC2: OBLIGATION
    FORALL (a: sequence[real], n: nat, x: real,
            (nzb: bool | nzb IFF (EXISTS (i: upto(n)): a(i) /= 0)),
            maxn:
              {lastn: nat |
                       lastn <= n AND
                        ((EXISTS (ii: upto(n)): a(ii) /= 0) IMPLIES
                          (polynomial(poly_n_deriv(a, n - lastn), lastn)(x)
                            /= 0
                            AND
                            (FORALL (i: nat):
                               i > lastn AND i <= n IMPLIES
                                polynomial(poly_n_deriv(a, n - i), i)(x) =
                                 0)))}):
      nzb AND maxn = max_nonvanishing_deriv(a, n, x) IMPLIES
       abs(polynomial(poly_n_deriv(a, n - maxn), maxn)(x)) > 0;

  % Subtype TCC generated (at line 265, column 40) for  TRUE
      % expected type  {nzb: bool | nzb IFF (EXISTS (i: upto(n)): a(i) /= 0)}
  poly_rootless_width_def_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat):
      (EXISTS (i: upto(n)): a(i) /= 0) IMPLIES
       (TRUE IFF (EXISTS (i: upto(n)): a(i) /= 0));

  % Subtype TCC generated (at line 268, column 43) for  n - j
      % expected type  nat
  poly_rootless_width_def_TCC2: OBLIGATION
    FORALL (a: sequence[real], n: nat, x: real):
      (EXISTS (i: upto(n)): a(i) /= 0) IMPLIES
       (FORALL (epsil: posreal):
          epsil = poly_rootless_width(a, n, x, TRUE) IMPLIES
           (FORALL (mnd:
                      {lastn: nat |
                               lastn <= n AND
                                ((EXISTS (ii: upto(n)): a(ii) /= 0) IMPLIES
                                  (polynomial(poly_n_deriv(a, n - lastn),
                                              lastn)
                                             (x)
                                    /= 0
                                    AND
                                    (FORALL (i: nat):
                                       i > lastn AND i <= n
                                       IMPLIES
                                       polynomial
                                       (poly_n_deriv(a, n - i), i)(x)
                                       =
                                       0)))}):
              mnd = max_nonvanishing_deriv(a, n, x) IMPLIES
               (FORALL (j: nat): j <= n - mnd IMPLIES n - j >= 0)));

  % Existence TCC generated (at line 282, column 2) for
      % min_poly_root_dist(a, (n: nat | a(n) /= 0)):
      %       {epsil: posreal |
      %                FORALL (x, y: real):
      %                  polynomial(a, n)(x) = 0 AND
      %                   polynomial(a, n)(y) = 0 AND x /= y
      %                   IMPLIES abs(x - y) > epsil}
  min_poly_root_dist_TCC1: OBLIGATION
    EXISTS (x1:
              [d: [a: sequence[real], {n | a(n) /= 0}] ->
                 {epsil: posreal |
                          FORALL (x, y: real):
                            polynomial(d`1, d`2)(x) = 0 AND
                             polynomial(d`1, d`2)(y) = 0 AND x /= y
                             IMPLIES abs(x - y) > epsil}]):
      TRUE;

  % Subtype TCC generated (at line 290, column 20) for  n - 1
      % expected type  T_high[nat]
  poly_root_bound_TCC1: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) /= 0)):
      n - 1 >= 0 OR (EXISTS (j: nat): n - 1 <= j);

  % Subtype TCC generated (at line 290, column 51) for  abs(a(n))
      % expected type  nznum
  poly_root_bound_TCC2: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) /= 0)): abs(a(n)) /= 0;

  % Subtype TCC generated (at line 290, column 6) for
      % max(2, sigma(0, n - 1, LAMBDA (i: nat): abs(a(i))) / abs(a(n)) + 1)
      % expected type  {K: posreal |
                     %          FORALL (x: real):
                     %            polynomial(a, n)(x) = 0 IMPLIES abs(x) < K}
  poly_root_bound_TCC3: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) /= 0)):
      max(2,
          sigma[nat](0, n - 1, LAMBDA (i: nat): abs(a(i))) / abs(a(n)) + 1)
       >= 0
       AND
       max(2,
           sigma[nat](0, n - 1, LAMBDA (i: nat): abs(a(i))) / abs(a(n)) + 1)
        > 0
        AND
        (FORALL (x: real):
           polynomial(a, n)(x) = 0 IMPLIES
            abs(x) <
             max(2,
                 sigma[nat](0, n - 1, LAMBDA (i: nat): abs(a(i))) / abs(a(n))
                  + 1));

  % Subtype TCC generated (at line 302, column 32) for  n - k
      % expected type  nat
  Knuth_bound_simple_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat, r: real):
      a(n) = 1 AND polynomial(a, n)(r) = 0 AND r > 0 AND n > 0 IMPLIES
       (FORALL (k: subrange(1, n)): n - k >= 0);

  % Subtype TCC generated (at line 302, column 45) for  k
      % expected type  {i: int | r /= 0 OR i >= 0}
  Knuth_bound_simple_TCC2: OBLIGATION
    FORALL (a: sequence[real], n: nat, r: real):
      a(n) = 1 AND polynomial(a, n)(r) = 0 AND r > 0 AND n > 0 IMPLIES
       (FORALL (k: subrange(1, n)): a(n - k) < 0 IMPLIES r /= 0 OR k >= 0);

  % Subtype TCC generated (at line 308, column 38) for  aquot
      % expected type  xp: posreal
  Knuth_poly_pos_root_bound_TCC1: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) = 1 AND n > 0), k: nat):
      1 <= k AND k <= n AND a(n - k) < 0 IMPLIES
       (FORALL (aquot: real):
          aquot = -a(n - k) IMPLIES aquot >= 0 AND aquot > 0);

  % Subtype TCC generated (at line 309, column 26) for  k
      % expected type  nznum
  Knuth_poly_pos_root_bound_TCC2: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) = 1 AND n > 0), k: nat):
      1 <= k AND k <= n AND a(n - k) < 0 IMPLIES
       (FORALL (aquot: real):
          aquot = -a(n - k) IMPLIES
           (FORALL (log2j:
                      {k: int |
                               aquot <= 2 ^ k AND
                                (FORALL (i: int):
                                   i < k IMPLIES 2 ^ i < aquot)}):
              log2j = least_pow_2_ge(aquot) IMPLIES k /= 0));

  % Subtype TCC generated (at line 312, column 29) for  n
      % expected type  {k: nat | 1 <= k}
  Knuth_poly_pos_root_bound_TCC3: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) = 1 AND n > 0),
            maxKfun: [nat -> rational]):
      (maxKfun =
        (LAMBDA (k: nat):
           IF 1 <= k AND k <= n AND a(n - k) < 0
             THEN LET aquot = -a(n - k),
                      log2j = least_pow_2_ge(aquot),
                      rootexp = floor(log2j / k) + 1
                    IN 2 ^ rootexp
           ELSE -1
           ENDIF))
       IMPLIES 1 <= n;

  % Subtype TCC generated (at line 312, column 9) for
      % 2 * max_rec(maxKfun, 1, n)
      % expected type  {K: real |
                     %          FORALL (x: real):
                     %            polynomial(a, n)(x) = 0 AND x > 0 IMPLIES
                     %             x <= K}
  Knuth_poly_pos_root_bound_TCC4: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) = 1 AND n > 0),
            maxKfun: [nat -> rational]):
      (maxKfun =
        (LAMBDA (k: nat):
           IF 1 <= k AND k <= n AND a(n - k) < 0
             THEN LET aquot = -a(n - k),
                      log2j = least_pow_2_ge(aquot),
                      rootexp = floor(log2j / k) + 1
                    IN 2 ^ rootexp
           ELSE -1
           ENDIF))
       IMPLIES
       (FORALL (x: real):
          polynomial(a, n)(x) = 0 AND x > 0 IMPLIES
           x <= 2 * max_rec(maxKfun, 1, n));

  % Subtype TCC generated (at line 316, column 18) for  0
      % expected type  {K: nnreal |
                     %          FORALL (x: real):
                     %            polynomial(a, n)(x) = 0 IMPLIES abs(x) <= K}
  Knuth_poly_root_bound_TCC1: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) /= 0)):
      n = 0 IMPLIES
       (FORALL (x: real): polynomial(a, n)(x) = 0 IMPLIES abs(x) <= 0);

  % Subtype TCC generated (at line 319, column 56) for  a(n)
      % expected type  nznum
  Knuth_poly_root_bound_TCC2: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) /= 0)):
      NOT n = 0 IMPLIES
       (FORALL (negsign: [nat -> odd_int]):
          negsign = (LAMBDA (i: nat): IF even?(i) THEN 1 ELSE -1 ENDIF)
           IMPLIES a(n) /= 0);

  % Subtype TCC generated (at line 321, column 47) for  n
      % expected type  {n | nega(n) = 1 AND n > 0}
  Knuth_poly_root_bound_TCC3: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) /= 0)):
      NOT n = 0 IMPLIES
       (FORALL (negsign: [nat -> odd_int]):
          negsign = (LAMBDA (i: nat): IF even?(i) THEN 1 ELSE -1 ENDIF)
           IMPLIES
           (FORALL (nega: [nat -> real]):
              (nega =
                (LAMBDA (i: nat): negsign(i) * negsign(n) * a(i) / a(n)))
               IMPLIES
               (FORALL (newa: [nat -> real]):
                  (newa = (LAMBDA (i: nat): a(i) / a(n))) IMPLIES
                   nega(n) = 1 AND n > 0)));

  % Subtype TCC generated (at line 322, column 47) for  n
      % expected type  {n | newa(n) = 1 AND n > 0}
  Knuth_poly_root_bound_TCC4: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) /= 0)):
      NOT n = 0 IMPLIES
       (FORALL (negsign: [nat -> odd_int]):
          negsign = (LAMBDA (i: nat): IF even?(i) THEN 1 ELSE -1 ENDIF)
           IMPLIES
           (FORALL (nega: [nat -> real]):
              (nega =
                (LAMBDA (i: nat): negsign(i) * negsign(n) * a(i) / a(n)))
               IMPLIES
               (FORALL (newa: [nat -> real]):
                  (newa = (LAMBDA (i: nat): a(i) / a(n))) IMPLIES
                   (FORALL (negbound:
                              {K: real |
                                       FORALL
                                       (x: real):
                                       polynomial(nega, n)(x) = 0 AND x > 0
                                       IMPLIES
                                       x <= K}):
                      negbound = Knuth_poly_pos_root_bound(nega, n) IMPLIES
                       newa(n) = 1 AND n > 0))));

  % Subtype TCC generated (at line 323, column 11) for
      % max(posbound, max(negbound, 0))
      % expected type  {K: nnreal |
                     %          FORALL (x: real):
                     %            polynomial(a, n)(x) = 0 IMPLIES abs(x) <= K}
  Knuth_poly_root_bound_TCC5: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) /= 0)):
      NOT n = 0 IMPLIES
       (FORALL (negsign: [nat -> odd_int]):
          negsign = (LAMBDA (i: nat): IF even?(i) THEN 1 ELSE -1 ENDIF)
           IMPLIES
           (FORALL (nega: [nat -> real]):
              (nega =
                (LAMBDA (i: nat): negsign(i) * negsign(n) * a(i) / a(n)))
               IMPLIES
               (FORALL (newa: [nat -> real]):
                  (newa = (LAMBDA (i: nat): a(i) / a(n))) IMPLIES
                   (FORALL (negbound:
                              {K: real |
                                       FORALL
                                       (x: real):
                                       polynomial(nega, n)(x) = 0 AND x > 0
                                       IMPLIES
                                       x <= K}):
                      negbound = Knuth_poly_pos_root_bound(nega, n) IMPLIES
                       (FORALL (posbound:
                                  {K: real |
                                           FORALL
                                           (x: real):
                                           polynomial(newa, n)(x) = 0
                                           AND
                                           x > 0
                                           IMPLIES
                                           x <= K}):
                          posbound = Knuth_poly_pos_root_bound(newa, n)
                           IMPLIES
                           max(posbound, max(negbound, 0)) >= 0 AND
                            (FORALL (x: real):
                               polynomial(a, n)(x) = 0 IMPLIES
                                abs(x) <=
                                 max(posbound, max(negbound, 0))))))));

  % Subtype TCC generated (at line 329, column 26) for  1
      % expected type  {K: posreal |
                     %          FORALL (x: real):
                     %            polynomial(a, n)(x) = 0 IMPLIES abs(x) < K}
  Knuth_poly_root_strict_bound_TCC1: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) /= 0),
            Kprb:
              {K: nnreal |
                       FORALL (x: real):
                         polynomial(a, n)(x) = 0 IMPLIES abs(x) <= K}):
      Kprb = 0 AND Kprb = Knuth_poly_root_bound(a, n) IMPLIES
       (FORALL (x: real): polynomial(a, n)(x) = 0 IMPLIES abs(x) < 1);

  % Subtype TCC generated (at line 330, column 71) for  1.01 * Kprb
      % expected type  {K: posreal |
                     %          FORALL (x: real):
                     %            polynomial(a, n)(x) = 0 IMPLIES abs(x) < K}
  Knuth_poly_root_strict_bound_TCC2: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) /= 0),
            Kprb:
              {K: nnreal |
                       FORALL (x: real):
                         polynomial(a, n)(x) = 0 IMPLIES abs(x) <= K}):
      (polynomial(a, n)(Kprb) = 0 OR polynomial(a, n)(-Kprb) = 0) AND
       NOT Kprb = 0 AND Kprb = Knuth_poly_root_bound(a, n)
       IMPLIES
       1.01 * Kprb > 0 AND
        (FORALL (x: real):
           polynomial(a, n)(x) = 0 IMPLIES abs(x) < 1.01 * Kprb);

  % Subtype TCC generated (at line 331, column 7) for  Kprb
      % expected type  {K: posreal |
                     %          FORALL (x: real):
                     %            polynomial(a, n)(x) = 0 IMPLIES abs(x) < K}
  Knuth_poly_root_strict_bound_TCC3: OBLIGATION
    FORALL (a: sequence[real], (n: nat | a(n) /= 0),
            Kprb:
              {K: nnreal |
                       FORALL (x: real):
                         polynomial(a, n)(x) = 0 IMPLIES abs(x) <= K}):
      NOT polynomial(a, n)(Kprb) = 0 AND
       NOT polynomial(a, n)(-Kprb) = 0 AND
        NOT Kprb = 0 AND Kprb = Knuth_poly_root_bound(a, n)
       IMPLIES
       Kprb > 0 AND
        (FORALL (x: real): polynomial(a, n)(x) = 0 IMPLIES abs(x) < Kprb);

  % Subtype TCC generated (at line 336, column 78) for  n - 1
      % expected type  nat
  poly_increasing_is_strict_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat, xlb, yub: real):
      xlb < yub AND n > 0 AND a(n) /= 0 IMPLIES
       (FORALL (c: real): xlb <= c AND c <= yub IMPLIES n - 1 >= 0);

  % Subtype TCC generated (at line 368, column 68) for  m
      % expected type  {i: int | (x - y) /= 0 OR i >= 0}
  root_degree_TCC1: OBLIGATION
    FORALL (a, n, y, m: nat):
      a(n) /= 0 AND m <= n IMPLIES (FORALL (x: real): (x - y) /= 0 OR m >= 0);

  % Subtype TCC generated (at line 371, column 90) for  n - 1
      % expected type  nat
  root_degree_TCC2: OBLIGATION
    FORALL (a, n, y, m: nat):
           n > 0 AND m > 0 AND (polynomial(a, n)(y) = 0 IMPLIES m > 0)
       AND EXISTS (b: [nat -> real]):
             (FORALL (x):
                polynomial(a, n)(x) = (x - y) ^ m * polynomial(b, n - m)(x))
              AND polynomial(b, n - m)(y) /= 0 AND b(n - m) /= 0
       AND a(n) /= 0 AND m <= n
       IMPLIES n - 1 >= 0;

  % Subtype TCC generated (at line 372, column 20) for  (m - 1)
      % expected type  {i: int | (x - y) /= 0 OR i >= 0}
  root_degree_TCC3: OBLIGATION
    FORALL (a, n, y, m: nat):
           n > 0 AND m > 0 AND (polynomial(a, n)(y) = 0 IMPLIES m > 0)
       AND EXISTS (b: [nat -> real]):
             (FORALL (x):
                polynomial(a, n)(x) = (x - y) ^ m * polynomial(b, n - m)(x))
              AND polynomial(b, n - m)(y) /= 0 AND b(n - m) /= 0
       AND a(n) /= 0 AND m <= n
       IMPLIES (FORALL (x1: real): (x1 - y) /= 0 OR (m - 1) >= 0);

  % Subtype TCC generated (at line 374, column 41) for  0
      % expected type  {m |
                     %          m <= n AND
                     %           (a(n) /= 0 IMPLIES
                     %             ((EXISTS (b: [nat -> real]):
                     %                 (FORALL
                     %                  (x):
                     %                  polynomial(a, n)(x)
                     %                  =
                     %                  (x - y) ^ m
                     %                  *
                     %                  polynomial(b, n - m)(x))
                     %                 AND
                     %                 polynomial(b, n - m)(y) /= 0
                     %                 AND
                     %                 b(n - m) /= 0)
                     %               AND
                     %               (polynomial(a, n)(y) = 0 IMPLIES m > 0)
                     %                AND
                     %                ((n > 0 AND m > 0)
                     %                 IMPLIES
                     %                 (EXISTS
                     %                  (q: [nat -> real]):
                     %                  (FORALL
                     %                   (x):
                     %                   polynomial(poly_deriv(a), n - 1)(x)
                     %                   =
                     %                   (x - y) ^ (m - 1)
                     %                   *
                     %                   polynomial(q, n - m)(x))
                     %                  AND
                     %                  polynomial(q, n - m)(y) /= 0))))}
  root_degree_TCC4: OBLIGATION
    FORALL (a: sequence[real], n: nat, y: real):
      polynomial(a, n)(y) /= 0 OR n = 0 IMPLIES
       0 <= n AND
        (a(n) /= 0 IMPLIES
          ((EXISTS (b: [nat -> real]):
              (FORALL (x):
                 polynomial(a, n)(x) = (x - y) ^ 0 * polynomial(b, n - 0)(x))
               AND polynomial(b, n - 0)(y) /= 0 AND b(n - 0) /= 0)
            AND
            (polynomial(a, n)(y) = 0 IMPLIES 0 > 0) AND
             ((n > 0 AND 0 > 0) IMPLIES
               (EXISTS (q: [nat -> real]):
                  (FORALL (x):
                     polynomial(poly_deriv(a), n - 1)(x) =
                      (x - y) ^ (0 - 1) * polynomial(q, n - 0)(x))
                   AND polynomial(q, n - 0)(y) /= 0))));

  % Subtype TCC generated (at line 375, column 9) for
      % 1 +
      %  root_degree(poly_shift(LAMBDA (i: nat): poly_shift(a, n)(y)(i + 1),
      %                         n - 1)
      %                        (-y),
      %              n - 1)
      %             (y)
      % expected type  {m |
                     %          m <= n AND
                     %           (a(n) /= 0 IMPLIES
                     %             ((EXISTS (b: [nat -> real]):
                     %                 (FORALL
                     %                  (x):
                     %                  polynomial(a, n)(x)
                     %                  =
                     %                  (x - y) ^ m
                     %                  *
                     %                  polynomial(b, n - m)(x))
                     %                 AND
                     %                 polynomial(b, n - m)(y) /= 0
                     %                 AND
                     %                 b(n - m) /= 0)
                     %               AND
                     %               (polynomial(a, n)(y) = 0 IMPLIES m > 0)
                     %                AND
                     %                ((n > 0 AND m > 0)
                     %                 IMPLIES
                     %                 (EXISTS
                     %                  (q: [nat -> real]):
                     %                  (FORALL
                     %                   (x):
                     %                   polynomial(poly_deriv(a), n - 1)(x)
                     %                   =
                     %                   (x - y) ^ (m - 1)
                     %                   *
                     %                   polynomial(q, n - m)(x))
                     %                  AND
                     %                  polynomial(q, n - m)(y) /= 0))))}
  root_degree_TCC5: OBLIGATION
    FORALL (a: sequence[real], n: nat,
            v:
              [d1: {z: [sequence[real], nat] | z`2 < n} ->
                 [y: real ->
                    {m |
                             m <= d1`2 AND
                              (d1`1(d1`2) /= 0 IMPLIES
                                ((EXISTS (b: [nat -> real]):
                                    (FORALL (x):
                                       polynomial(d1`1, d1`2)(x)
                                       =
                                       (x - y) ^ m
                                       *
                                       polynomial(b, d1`2 - m)(x))
                                     AND
                                     polynomial(b, d1`2 - m)(y) /= 0 AND
                                      b(d1`2 - m) /= 0)
                                  AND
                                  (polynomial(d1`1, d1`2)(y) = 0 IMPLIES
                                    m > 0)
                                   AND
                                   ((d1`2 > 0 AND m > 0) IMPLIES
                                     (EXISTS
                                      (q: [nat -> real]):
                                      (FORALL
                                       (x):
                                       polynomial
                                       (poly_deriv(d1`1), d1`2 - 1)(x)
                                       =
                                       (x - y) ^ (m - 1)
                                       *
                                       polynomial(q, d1`2 - m)(x))
                                      AND
                                      polynomial(q, d1`2 - m)(y) /= 0))))}]],
            y: real):
      NOT polynomial(a, n)(y) /= 0 AND NOT n = 0 IMPLIES
       1 +
        v(poly_shift(LAMBDA (i: nat): poly_shift(a, n)(y)(i + 1), n - 1)(-y),
          n - 1)
         (y)
        <= n
        AND
        (a(n) /= 0 IMPLIES
          ((EXISTS (b: [nat -> real]):
              (FORALL (x):
                 polynomial(a, n)(x) =
                  ((x - y) ^
                    (1 +
                      v(poly_shift(LAMBDA (i: nat):
                                     poly_shift(a, n)(y)(i + 1),
                                   n - 1)
                                  (-y),
                        n - 1)
                       (y)))
                   *
                   polynomial(b,
                              n -
                               (1 +
                                 v(poly_shift(LAMBDA
                                              (i: nat):
                                              poly_shift(a, n)(y)(i + 1),
                                              n - 1)
                                             (-y),
                                   n - 1)
                                  (y)))
                             (x))
               AND
               polynomial(b,
                          n -
                           (1 +
                             v(poly_shift(LAMBDA
                                          (i: nat):
                                          poly_shift(a, n)(y)(i + 1),
                                          n - 1)
                                         (-y),
                               n - 1)
                              (y)))
                         (y)
                /= 0
                AND
                b(n -
                   (1 +
                     v(poly_shift(LAMBDA (i: nat):
                                    poly_shift(a, n)(y)(i + 1),
                                  n - 1)
                                 (-y),
                       n - 1)
                      (y)))
                 /= 0)
            AND
            (polynomial(a, n)(y) = 0 IMPLIES
              1 +
               v(poly_shift(LAMBDA (i: nat): poly_shift(a, n)(y)(i + 1),
                            n - 1)
                           (-y),
                 n - 1)
                (y)
               > 0)
             AND
             ((n > 0 AND
                1 +
                 v(poly_shift(LAMBDA (i: nat): poly_shift(a, n)(y)(i + 1),
                              n - 1)
                             (-y),
                   n - 1)
                  (y)
                 > 0)
               IMPLIES
               (EXISTS (q: [nat -> real]):
                  (FORALL (x):
                     polynomial(poly_deriv(a), n - 1)(x) =
                      (x - y) ^
                       (1 +
                         v(poly_shift(LAMBDA
                                      (i: nat):
                                      poly_shift(a, n)(y)(i + 1),
                                      n - 1)
                                     (-y),
                           n - 1)
                          (y)
                         - 1)
                       *
                       polynomial(q,
                                  n -
                                   (1 +
                                     v(poly_shift
                                       (LAMBDA
                                        (i: nat):
                                        poly_shift(a, n)(y)(i + 1),
                                        n - 1)
                                       (-y),
                                       n - 1)
                                      (y)))
                                 (x))
                   AND
                   polynomial(q,
                              n -
                               (1 +
                                 v(poly_shift(LAMBDA
                                              (i: nat):
                                              poly_shift(a, n)(y)(i + 1),
                                              n - 1)
                                             (-y),
                                   n - 1)
                                  (y)))
                             (y)
                    /= 0))));

  % Subtype TCC generated (at line 383, column 34) for  root_degree(a, n)(y)
      % expected type  posnat
  root_degree_max_linear_div_power_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat, y: real):
      (polynomial(a, n)(y) = 0 OR root_degree(a, n)(y) > 0) AND a(n) /= 0
       IMPLIES root_degree(a, n)(y) > 0;

  % Subtype TCC generated (at line 405, column 30) for  n - 1
      % expected type  nat
  root_degree_deriv_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat, y: real):
      n > 0 AND polynomial(a, n)(y) = 0 AND a(n) /= 0 IMPLIES n - 1 >= 0;

  % Subtype TCC generated (at line 422, column 31) for  m
      % expected type  {i: int | (x - y) /= 0 OR i >= 0}
  root_degree_lower_bound_TCC1: OBLIGATION
    FORALL (a: sequence[real], m, n: nat, y: real, k: nat):
      a(n) /= 0 IMPLIES
       (FORALL (b: [nat -> real]):
          b(k) /= 0 IMPLIES (FORALL (x: real): (x - y) /= 0 OR m >= 0));


body:
  base_repr : THEORY

  %------------------------------------------------------------
  %
  %   Base n representation of natural numbers. 
  %   
  %   Given n>1, the base n representation of k>=0 is
  %   k = (a_0, a_1, a_2, ...) where 0<=a_i<n
  %   
  %   k = sum_{i=0}^\infty a_i*n^i. 
  %
  %   
  %
  %   Author: Aaron Dutle, NASA Langley Research Center
  %
  %
  %
  %------------------------------------------------------------

    BEGIN

    IMPORTING log_nat, sigma_nat, structures@array2list

   
    base_n(n: {x:nat| x>1}, k:nat)(i:nat): RECURSIVE nat = 
         	       	       IF k<n THEN (IF i = 0 THEN k ELSE 0 ENDIF)
  		       ELSE (IF i=0 THEN mod(k, n)  ELSE base_n(n, (k-mod(k,n))/n)(i-1) ENDIF)
  		       ENDIF
  		       MEASURE k 

    %base_n_lt_n: LEMMA
    %	   FORALL (n: {x:nat| x>1}, k,i:nat):
    %	   base_n(n,k)(i)<=n-1 

    upper_index(n: {x:nat| x>1}, k:nat): nat = IF k=0 THEN 0 ELSE log_nat(k,n)`1 ENDIF

    base_n_lt_n: LEMMA FORALL (n:{x:nat|x>1},k,i:nat):
      base_n(n,k)(i)<n

    upper_is_bound: LEMMA FORALL (n: {x:nat|x>1}, k:nat, m:nat):  
          m>upper_index(n, k) IMPLIES base_n(n,k)(m) = 0

    base_n_is_n: LEMMA FORALL(n:{x:nat|x>1}, k:nat):
          k = sigma(0, upper_index(n,k), LAMBDA(s:nat): n^s*base_n(n,k)(s))

    base_n_to_nat(n:{x:nat|x>1},F:[nat->nat], m:nat): nat = sigma(0, m, LAMBDA(s:nat): n^s*F(s))

    base_n_is_n_alt: LEMMA FORALL (n: {x:nat|x>1}, k, m:nat):
          k<n^(m+1) IMPLIES  k = base_n_to_nat(n,base_n(n,k),m)  

    base_n_to_nat_lt: LEMMA FORALL (F:[nat->nat],m:nat,(n:nat|n>1)):
      (FORALL (i:nat): i<=m IMPLIES F(i)<n) IMPLIES base_n_to_nat(n,F,m) < n^(m+1)

    base_n_0: LEMMA FORALL (n: {x:nat|x>1}, k:nat, m:nat):  
          k<n^m IMPLIES base_n(n,k)(m) = 0

    base_n_unique: LEMMA FORALL (d:nat,n:{x:nat|x>1},numseq:[nat->below(n)]):
      LET k = sigma(0,d,LAMBDA (s:nat): n^s*numseq(s)) IN
        (FORALL (j:nat): j<=d IMPLIES numseq(j)=base_n(n,k)(j))

    base_n_base_n_to_nat: LEMMA FORALL (n:{x:nat|x>1},F:[nat->nat], m:nat):
      (FORALL (i:upto(m)): F(i)<n)
      IMPLIES
      FORALL (i:upto(m)): base_n(n,base_n_to_nat(n,F,m))(i) = F(i)

    base_n_to_nat_eq: LEMMA FORALL (n: {x:nat|x>1}, k, m:nat,F,G:[nat->nat]):
      (FORALL (i:upto(m)): F(i)=G(i)) IMPLIES
      base_n_to_nat(n,F,m) = base_n_to_nat(n,G,m)

    base_n_to_nat_unique: LEMMA FORALL (n: {x:nat|x>1}, k, m:nat,F,G:[nat->nat]):
      (FORALL (i:upto(m)): F(i)<n AND G(i)<n) AND
      base_n_to_nat(n,F,m) = base_n_to_nat(n,G,m)
      IMPLIES
      (FORALL (i:upto(m)): F(i)=G(i))
    
    base_list(n: {x:nat|x>1},k:nat): 
      listn[below(n)](upper_index(n,k)+1) = 
       array2list[below(n)](upper_index(n,k)+1)( base_n(n,k))

    base_list(n: {x:nat|x>1}, k:nat, digits:posnat):
       listn[below(n)](digits) = array2list[below(n)](digits)(base_n(n,k))

    base_list_cdr: LEMMA FORALL (n: {x:nat|x>1}, k:nat, j:posnat):
            cdr(base_list(n,k,j+1)) = base_list(n, (k-mod(k,n))/n, j)

    base_list_faster(n: {x:nat|x>1}, k:nat, digits:posnat): RECURSIVE listn[below(n)](digits) = 
      IF digits = 1 THEN (: mod(k, n) :) 
      ELSE cons(mod(k, n), base_list_faster(n, (k-mod(k, n))/n, digits-1))
      ENDIF
      MEASURE digits

    base_list_same: LEMMA FORALL (n: {x:nat|x>1}, k:nat, digits:posnat): 
         base_list_faster(n, k, digits) = base_list(n,k,digits)

    base_to_array(n:posnat, l:list[below(n)]): [nat->below(n)] = list2array[below(n)](0)(l) 

    base_to_array_sound: LEMMA FORALL (n:{x:nat|x>1}, k:nat, j:above(upper_index(n,k))): 
         base_to_array(n, base_list(n, k, j)) = base_n(n,k)  




    END base_repr

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

  % Subtype TCC generated (at line 27, column 34) for  n
      % expected type  nonzero_integer
  base_n_TCC1: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k, i: nat):
      i = 0 AND NOT k < n IMPLIES n /= 0;

  % Subtype TCC generated (at line 27, column 27) for  mod(k, n)
      % expected type  nat
  base_n_TCC2: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k, i: nat):
      i = 0 AND NOT k < n IMPLIES mod(k, n) >= 0;

  % Subtype TCC generated (at line 27, column 62) for  n
      % expected type  nonzero_integer
  base_n_TCC3: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k, i: nat):
      NOT i = 0 AND NOT k < n IMPLIES n /= 0;

  % Subtype TCC generated (at line 27, column 53) for  (k - mod(k, n)) / n
      % expected type  nat
  base_n_TCC4: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k, i: nat):
      NOT i = 0 AND NOT k < n IMPLIES
       integer_pred((k - mod(k, n)) / n) AND (k - mod(k, n)) / n >= 0;

  % Termination TCC generated (at line 27, column 43) for
      % base_n(n, (k - mod(k, n)) / n)
  base_n_TCC5: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k, i: nat):
      NOT i = 0 AND NOT k < n IMPLIES (k - mod(k, n)) / n < k;

  % Subtype TCC generated (at line 27, column 69) for  i - 1
      % expected type  nat
  base_n_TCC6: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k, i: nat):
      NOT i = 0 AND NOT k < n IMPLIES i - 1 >= 0;

  % Subtype TCC generated (at line 35, column 72) for  k
      % expected type  {x: real | x >= 1}
  upper_index_TCC1: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k: nat): NOT k = 0 IMPLIES k >= 1;

  % Subtype TCC generated (at line 44, column 21) for  upper_index(n, k)
      % expected type  T_high[nat]
  base_n_is_n_TCC1: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k: nat):
      upper_index(n, k) >= 0 OR (EXISTS (j: nat): upper_index(n, k) <= j);

  % Subtype TCC generated (at line 44, column 56) for  s
      % expected type  {i: int | n /= 0 OR i >= 0}
  base_n_is_n_TCC2: OBLIGATION
    FORALL (n: {x: nat | x > 1}, s: nat): n /= 0 OR s >= 0;

  % Subtype TCC generated (at line 46, column 67) for  m
      % expected type  T_high[nat]
  base_n_to_nat_TCC1: OBLIGATION
    FORALL (n: {x: nat | x > 1}, m: nat): m >= 0 OR (EXISTS (j: nat): m <= j);

  % Subtype TCC generated (at line 49, column 13) for  (m + 1)
      % expected type  {i: int | n /= 0 OR i >= 0}
  base_n_is_n_alt_TCC1: OBLIGATION
    FORALL (n: {x: nat | x > 1}, m: nat): n /= 0 OR (m + 1) >= 0;

  % Subtype TCC generated (at line 78, column 47) for  base_n(n, k)
      % expected type  a: [nat -> below(n)]
  base_list_TCC1: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k: nat):
      FORALL (x1: nat): base_n(n, k)(x1) < n;

  % Existence TCC generated (at line 78, column 5) for  array2list[below(n)]
  base_list_TCC2: OBLIGATION
    FORALL (n: {x: nat | x > 1}): EXISTS (x: below(n)): TRUE;

  % Subtype TCC generated (at line 84, column 14) for  base_list(n, k, j + 1)
      % expected type  (cons?[below(n)])
  base_list_cdr_TCC1: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k: nat, j: posnat):
      cons?[below(n)](base_list(n, k, j + 1));

  % Subtype TCC generated (at line 84, column 58) for  n
      % expected type  nonzero_integer
  base_list_cdr_TCC2: OBLIGATION FORALL (n: {x: nat | x > 1}): n /= 0;

  % Subtype TCC generated (at line 84, column 49) for  (k - mod(k, n)) / n
      % expected type  nat
  base_list_cdr_TCC3: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k: nat):
      integer_pred((k - mod(k, n)) / n) AND (k - mod(k, n)) / n >= 0;

  % Subtype TCC generated (at line 87, column 26) for  mod(k, n)
      % expected type  below(n)
  base_list_faster_TCC1: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k: nat, digits: posnat):
      digits = 1 IMPLIES mod(k, n) >= 0 AND mod(k, n) < n;

  % Subtype TCC generated (at line 87, column 38) for  (: :)
      % expected type  list[below(n)]
  base_list_faster_TCC2: OBLIGATION
    FORALL (n: {x: nat | x > 1}, digits: posnat):
      digits = 1 IMPLIES
       every[number]
           (LAMBDA (x: number):
                   number_field_pred(x) AND real_pred(x) AND rational_pred(x)
               AND integer_pred(x) AND x >= 0 AND x < n)
           ((: :));

  % Subtype TCC generated (at line 87, column 23) for  (: mod(k, n) :)
      % expected type  listn[below(n)](digits)
  base_list_faster_TCC3: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k: nat, digits: posnat):
      digits = 1 IMPLIES length[below(n)]((: mod(k, n) :)) = digits;

  % Subtype TCC generated (at line 88, column 14) for  mod(k, n)
      % expected type  below(n)
  base_list_faster_TCC4: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k: nat, digits: posnat):
      NOT digits = 1 IMPLIES mod(k, n) >= 0 AND mod(k, n) < n;

  % Subtype TCC generated (at line 88, column 62) for  digits - 1
      % expected type  posnat
  base_list_faster_TCC5: OBLIGATION
    FORALL (n: {x: nat | x > 1}, digits: posnat):
      NOT digits = 1 IMPLIES digits - 1 >= 0 AND digits - 1 > 0;

  % Termination TCC generated (at line 88, column 25) for
      % base_list_faster(n, (k - mod(k, n)) / n, digits - 1)
  base_list_faster_TCC6: OBLIGATION
    FORALL (n: {x: nat | x > 1}, digits: posnat):
      NOT digits = 1 IMPLIES digits - 1 < digits;

  % Subtype TCC generated (at line 88, column 9) for
      % cons(mod(k, n), base_list_faster(n, (k - mod(k, n)) / n, digits - 1))
      % expected type  listn[below(n)](digits)
  base_list_faster_TCC7: OBLIGATION
    FORALL (n: {x: nat | x > 1}, k: nat, digits: posnat,
            v:
              [d1: {z: [{x: nat | x > 1}, nat, posnat] | z`3 < digits} ->
                 listn[below(d1`1)](d1`3)]):
      NOT digits = 1 IMPLIES
       length[below(n)]
           (cons[below(n)](mod(k, n), v(n, (k - mod(k, n)) / n, digits - 1)))
        = digits;

  % Subtype TCC generated (at line 95, column 84) for  0
      % expected type  below(n)
  base_to_array_TCC1: OBLIGATION FORALL (n: posnat): 0 < n;

  % Existence TCC generated (at line 95, column 63) for  list2array[below(n)]
  base_to_array_TCC2: OBLIGATION
    FORALL (n: posnat): EXISTS (x: below(n)): TRUE;

  % Subtype TCC generated (at line 98, column 21) for  n
      % expected type  posnat
  base_to_array_sound_TCC1: OBLIGATION FORALL (n: {x: nat | x > 1}): n > 0;


body:
  harmonic_polynomials: THEORY
  BEGIN

    IMPORTING sq, sigma_nat, binomial

    pn:  VAR posnat
    x,y: VAR real

    harmonic_poly_real(pn:posnat,x,y:real):real
      = sigma(0,pn,LAMBDA (i:nat):
                   IF i > pn OR odd?(i) THEN 0 ELSE (-1)^(i/2)*C(pn,i)*
                        (IF    i = 0  THEN x^pn
                         ELSIF i = pn THEN y^pn
                                      ELSE x^(pn-i)*y^i ENDIF) ENDIF)

    harmonic_poly_imag(pn:posnat,x,y:real):real
      = sigma(0,pn,LAMBDA (i:nat):
                   IF i > pn OR even?(i) THEN 0 ELSE (-1)^((i-1)/2)*C(pn,i)*
                        (IF    i = pn THEN y^pn
                                      ELSE x^(pn-i)*y^i ENDIF) ENDIF)

    harmonic_polynomial_real_n1:  LEMMA harmonic_poly_real(1,x,y) = x
   
    harmonic_polynomial_imag_n1:  LEMMA harmonic_poly_imag(1,x,y) = y

    harmonic_polynomial_real_rec: LEMMA
        harmonic_poly_real(pn+1,x,y)
          = x*harmonic_poly_real(pn,x,y) - y*harmonic_poly_imag(pn,x,y)

    harmonic_polynomial_imag_rec: LEMMA
        harmonic_poly_imag(pn+1,x,y)
          = x*harmonic_poly_imag(pn,x,y) + y*harmonic_poly_real(pn,x,y)

    harmonic_polynomial_modulus: LEMMA
        sq(harmonic_poly_real(pn,x,y)) + sq(harmonic_poly_imag(pn,x,y))
      = (sq(x)+sq(y))^pn
      
  END harmonic_polynomials

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

  % Subtype TCC generated (at line 10, column 14) for  pn
      % expected type  T_high[nat]
  harmonic_poly_real_TCC1: OBLIGATION
    FORALL (pn: posnat): pn >= 0 OR (EXISTS (j: nat): pn <= j);

  % Subtype TCC generated (at line 11, column 56) for  (i / 2)
      % expected type  {i: int | TRUE}
  harmonic_poly_real_TCC2: OBLIGATION
    FORALL (pn: posnat, i: nat):
      NOT i > pn AND NOT odd?(i) IMPLIES integer_pred((i / 2));

  % Subtype TCC generated (at line 11, column 66) for  i
      % expected type  {i: nat | i <= pn}
  harmonic_poly_real_TCC3: OBLIGATION
    FORALL (pn: posnat, i: nat): NOT i > pn AND NOT odd?(i) IMPLIES i <= pn;

  % Subtype TCC generated (at line 12, column 43) for  pn
      % expected type  {i: int | x /= 0 OR i >= 0}
  harmonic_poly_real_TCC4: OBLIGATION
    FORALL (pn: posnat, x: real, i: nat):
      i = 0 AND NOT i > pn AND NOT odd?(i) IMPLIES x /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 13, column 43) for  pn
      % expected type  {i: int | y /= 0 OR i >= 0}
  harmonic_poly_real_TCC5: OBLIGATION
    FORALL (pn: posnat, y: real, i: nat):
      i = pn AND NOT i = 0 AND NOT i > pn AND NOT odd?(i) IMPLIES
       y /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 14, column 44) for  (pn - i)
      % expected type  {i: int | x /= 0 OR i >= 0}
  harmonic_poly_real_TCC6: OBLIGATION
    FORALL (pn: posnat, x: real, i: nat):
      NOT i = pn AND NOT i = 0 AND NOT i > pn AND NOT odd?(i) IMPLIES
       x /= 0 OR (pn - i) >= 0;

  % Subtype TCC generated (at line 14, column 52) for  i
      % expected type  {i: int | y /= 0 OR i >= 0}
  harmonic_poly_real_TCC7: OBLIGATION
    FORALL (pn: posnat, y: real, i: nat):
      NOT i = pn AND NOT i = 0 AND NOT i > pn AND NOT odd?(i) IMPLIES
       y /= 0 OR i >= 0;

  % Subtype TCC generated (at line 18, column 57) for  ((i - 1) / 2)
      % expected type  {i: int | TRUE}
  harmonic_poly_imag_TCC1: OBLIGATION
    FORALL (pn: posnat, i: nat):
      NOT i > pn AND NOT even?(i) IMPLIES integer_pred(((i - 1) / 2));

  % Subtype TCC generated (at line 18, column 71) for  i
      % expected type  {i: nat | i <= pn}
  harmonic_poly_imag_TCC2: OBLIGATION
    FORALL (pn: posnat, i: nat): NOT i > pn AND NOT even?(i) IMPLIES i <= pn;

  % Subtype TCC generated (at line 19, column 43) for  pn
      % expected type  {i: int | y /= 0 OR i >= 0}
  harmonic_poly_imag_TCC3: OBLIGATION
    FORALL (pn: posnat, y: real, i: nat):
      i = pn AND NOT i > pn AND NOT even?(i) IMPLIES y /= 0 OR pn >= 0;

  % Subtype TCC generated (at line 20, column 44) for  (pn - i)
      % expected type  {i: int | x /= 0 OR i >= 0}
  harmonic_poly_imag_TCC4: OBLIGATION
    FORALL (pn: posnat, x: real, i: nat):
      NOT i = pn AND NOT i > pn AND NOT even?(i) IMPLIES
       x /= 0 OR (pn - i) >= 0;

  % Subtype TCC generated (at line 20, column 52) for  i
      % expected type  {i: int | y /= 0 OR i >= 0}
  harmonic_poly_imag_TCC5: OBLIGATION
    FORALL (pn: posnat, y: real, i: nat):
      NOT i = pn AND NOT i > pn AND NOT even?(i) IMPLIES y /= 0 OR i >= 0;

  % Subtype TCC generated (at line 36, column 20) for  pn
      % expected type  {i: int | (sq(x) + sq(y)) /= 0 OR i >= 0}
  harmonic_polynomial_modulus_TCC1: OBLIGATION
    FORALL (pn: posnat, x, y: real): (sq(x) + sq(y)) /= 0 OR pn >= 0;


body:
  factorial_props: THEORY
  %----------------------------------------------------------------------------
  %
  %  Factorial function:  factorial(n) = n!
  %  
  %  Author: Rick Butler                   NASA Langley Research Center
  %          David Lester                  Manchester University
  %
  %----------------------------------------------------------------------------
  BEGIN
   
     IMPORTING ints@factorial, sqrt

     n,k: VAR nat

     factorial_2n_lb: LEMMA sqrt(n)^(2*n) <= factorial(2*n)

     factorial_2np1_lb: LEMMA sqrt(n)^(2*n+1) <= factorial(2*n+1)


  END factorial_props

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

  % Subtype TCC generated (at line 16, column 35) for  (2 * n)
      % expected type  {i: int | sqrt(n) /= 0 OR i >= 0}
  factorial_2n_lb_TCC1: OBLIGATION
    FORALL (n: nat): sqrt(n) /= 0 OR (2 * n) >= 0;

  % Subtype TCC generated (at line 18, column 37) for  (2 * n + 1)
      % expected type  {i: int | sqrt(n) /= 0 OR i >= 0}
  factorial_2np1_lb_TCC1: OBLIGATION
    FORALL (n: nat): sqrt(n) /= 0 OR (2 * n + 1) >= 0;


body:
  expt_rew: THEORY
  %------------------------------------------------------------------------------
  %
  % EXPERIMENTAL theory -- not ready for prime time
  %
  %------------------------------------------------------------------------------
  BEGIN

    pn: VAR posnat


    AUTO_REWRITE+  expt_x0_aux    % LEMMA expt(x, 0) = 1
    AUTO_REWRITE+  expt_x1_aux    % LEMMA expt(x, 1) = x
    AUTO_REWRITE+  expt_1n_aux    % LEMMA expt(1, n) = 1

    AUTO_REWRITE+  expt_of_mult   % LEMMA expt(x*y, n) = expt(x, n) * expt(y, n)
    AUTO_REWRITE+  expt_of_div    % LEMMA expt(x/z, n) = expt(x, n) / expt(z, n) 
    AUTO_REWRITE+  expt_of_inv    % LEMMA expt(1 / z, n) = 1 / expt(z, n)   


    AUTO_REWRITE+ expt_x0         % LEMMA x^0 = 1
    AUTO_REWRITE+ expt_x1         % LEMMA x^1 = x
    AUTO_REWRITE+ expt_1i         % LEMMA 1^i = 1

    i:  VAR int
    n0x, n0y: VAR nzreal

    zero_hat : LEMMA 0^pn = 0
    mult_hat : LEMMA n0x^i * n0y^i = (n0x * n0y) ^i  
    div_hat  : LEMMA n0x^i / n0y^i = (n0x / n0y)^i  
    inv_hat  : LEMMA 1 / n0x^i = (1 / n0x)^i  

    AUTO_REWRITE+  zero_hat  
    AUTO_REWRITE+  mult_hat     
    AUTO_REWRITE+  div_hat      
    AUTO_REWRITE+  inv_hat      



    AUTO_REWRITE+ pos_expt_gt     % LEMMA n < b^n
    AUTO_REWRITE+ expt_ge1        % LEMMA b^n >= 1
    AUTO_REWRITE+ expt_gt1_pos    % LEMMA gt1x^pm >= gt1x
    AUTO_REWRITE+ expt_gt1_neg    % LEMMA gt1x^(-pm) < 1
    AUTO_REWRITE+ expt_gt1_nonpos % LEMMA gt1x^(-m) <= 1
    AUTO_REWRITE+ expt_lt1_bound1 % LEMMA  expt(lt1x, n) <= 1
    AUTO_REWRITE+ expt_lt1_bound2 % LEMMA  expt(lt1x, pn) < 1
    AUTO_REWRITE+ expt_gt1_bound1 % LEMMA  1 <= expt(gt1x, n)
    AUTO_REWRITE+ expt_gt1_bound2 % LEMMA  1 < expt(gt1x, pn)


  END expt_rew

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

  % Subtype TCC generated (at line 29, column 23) for  i
      % expected type  {i: int | n0x /= 0 OR i >= 0}
  mult_hat_TCC1: OBLIGATION FORALL (i: int, n0x: nzreal): n0x /= 0 OR i >= 0;

  % Subtype TCC generated (at line 29, column 48) for  i
      % expected type  {i: int | (n0x * n0y) /= 0 OR i >= 0}
  mult_hat_TCC2: OBLIGATION
    FORALL (i: int, n0x, n0y: nzreal): (n0x * n0y) /= 0 OR i >= 0;

  % Subtype TCC generated (at line 30, column 47) for  i
      % expected type  {i: int | (n0x / n0y) /= 0 OR i >= 0}
  div_hat_TCC1: OBLIGATION
    FORALL (i: int, n0x, n0y: nzreal): (n0x / n0y) /= 0 OR i >= 0;


body:
  exponent_props : THEORY
  %-------------------------------------------------------------------------
  %  More properties of expt  
  %
  %      by Bruno Dutertre    Royal Holloway & Bedford New College
  %
  %     9/10/00  -- removed duplications with prelude  RWB
  %                 changed names of 
  %
  %                    expt_mult --> expt_of_mult
  %                    expt_div  --> expt_of_div 
  %                    expt_inv  --> expt_of_inv 
  %                 
  %                 to eliminate duplications with prelude
  %
  %  Note. This library is retained for upward compatibility only.  New 
  %        users should use the prelude theorems.
  %-------------------------------------------------------------------------
  BEGIN

    n, m: VAR nat
    p: VAR posnat
    x, y: VAR real
    z: VAR nzreal
    n0x, n0y: VAR nzreal

  %  JUDGEMENT expt(z: nzreal, m: nat) HAS_TYPE nzreal

    abs_expt    : LEMMA abs(expt(x, n)) = expt(abs(x), n)

    expt_ne_0:    LEMMA expt(z, n) /= 0;

  %% The following is named abs_of_expt_inv in prelude

    abs_expt_inv: LEMMA abs(1 / expt(z, n)) = 1 / expt(abs(z),n)


    i:  VAR int
    pn: VAR posnat

  % The following all appear in the prelude under different names

    zero_hat : LEMMA 0^pn = 0

    mult_hat : LEMMA (n0x * n0y) ^i = n0x^i * n0y^i

    div_hat  : LEMMA (n0x / n0y)^i = n0x^i / n0y^i

    inv_hat  : LEMMA (1 / n0x)^i = 1 / n0x^i

    abs_hat  : LEMMA abs(n0x^i) = abs(n0x)^i

    AUTO_REWRITE+ expt_x0         % LEMMA x^0 = 1
    AUTO_REWRITE+ expt_x1         % LEMMA x^1 = x
    AUTO_REWRITE+ expt_1i         % LEMMA 1^i = 1
    AUTO_REWRITE+ zero_hat  


  %%  a, b: VAR posreal
  %%  lt1x: VAR { a | a < 1}
  %%  gt1x: VAR { a | 1 < a }
  %%  expt_lt1_bound1 : LEMMA  expt(lt1x, n) <= 1   %%  In Prelude
  %%  expt_lt1_bound2 : LEMMA  expt(lt1x, p) < 1    %%  In Prelude
  %%  expt_gt1_bound1 : LEMMA  1 <= expt(gt1x, n)  %%  In Prelude
  %%  expt_gt1_bound2 : LEMMA  1 < expt(gt1x, p)   %%  In Prelude
  %%  nnx: VAR nonneg_real
  %%  expt_lt1_le     : LEMMA nnx < 1 => nnx^pn <= nnx %%  In Prelude
  %%  large_expt      : LEMMA 1 < a  IMPLIES (FORALL b: EXISTS n: b < expt(a, n))
  %%  small_expt      : LEMMA a < 1  IMPLIES (FORALL b: EXISTS n: expt(a, n) < b)
  END exponent_props

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

  % Subtype TCC generated (at line 45, column 32) for  i
      % expected type  {i: int | (n0x * n0y) /= 0 OR i >= 0}
  mult_hat_TCC1: OBLIGATION
    FORALL (i: int, n0x, n0y: nzreal): (n0x * n0y) /= 0 OR i >= 0;

  % Subtype TCC generated (at line 45, column 40) for  i
      % expected type  {i: int | n0x /= 0 OR i >= 0}
  mult_hat_TCC2: OBLIGATION FORALL (i: int, n0x: nzreal): n0x /= 0 OR i >= 0;

  % Subtype TCC generated (at line 47, column 31) for  i
      % expected type  {i: int | (n0x / n0y) /= 0 OR i >= 0}
  div_hat_TCC1: OBLIGATION
    FORALL (i: int, n0x, n0y: nzreal): (n0x / n0y) /= 0 OR i >= 0;

  % Subtype TCC generated (at line 51, column 41) for  i
      % expected type  {i: int | abs(n0x) /= 0 OR i >= 0}
  abs_hat_TCC1: OBLIGATION
    FORALL (i: int, n0x: nzreal): abs(n0x) /= 0 OR i >= 0;


body:
  circles_and_lines: THEORY
  %------------------------------------------------------------------------
  %
  %  ------ Intersection of parametric line and a circle -----
  %
  %  See related theorems in vectors@closest_approach_2D
  %
  %  Author: Cesar Munoz           National Institute for Aerospace
  %
  %------------------------------------------------------------------------
  BEGIN

    IMPORTING quad_minmax

    sx,sy,vx,vy   : VAR real

    % The first lemma states that if t1 and t2 are the intersection
    % points with a circle of radius D, then the distance for all times
    % between t1 and t2 is less than D 

    t1_lt_t2_lt_D : LEMMA FORALL (t,t1,t2,D:real):
        	     	     vx*vx + vy*vy /= 0 AND
        	     	     t1 < t2 AND
        	     	     (sx+vx*t1)*(sx+vx*t1) + (sy+vy*t1)*(sy+vy*t1) = D AND
        	     	     (sx+vx*t2)*(sx+vx*t2) + (sy+vy*t2)*(sy+vy*t2) = D AND
        	     	     t1 < t AND t < t2 IMPLIES
        	     	     (sx+vx*t)*(sx+vx*t) + (sy+vy*t)*(sy+vy*t) < D

    % The second lemma is the reciprocal of the previous lemma. It states that
    % if the distance at time t is less than D, then t is between t1 and
    % t2.
   
    lt_D_t1_lt_t2 : LEMMA FORALL (t,t1,t2,D:real):
        		      	   vx*vx + vy*vy /= 0 AND
        		      	   t1 < t2 AND
        		      	   (sx+vx*t1)*(sx+vx*t1) + (sy+vy*t1)*(sy+vy*t1) = D
        		      	   AND
        		      	   (sx+vx*t2)*(sx+vx*t2) + (sy+vy*t2)*(sy+vy*t2) = D
        		      	   AND
        		      	   (sx+vx*t)*(sx+vx*t) + (sy+vy*t)*(sy+vy*t) < D IMPLIES
        		      	   t1 < t AND t < t2 

    % The third lemma states that if there are no intersection points with
    % a circle of radius D then the distance at any time is greater than D.

    discr_le_0 : LEMMA FORALL (t,discrm,D:real): 
        		  	discrm = 2*sx*vx*sy*vy + D*(vx*vx+vy*vy) - 
        		  	         (sx*sx*vy*vy + sy*sy*vx*vx) AND
        		  	discrm <= 0 AND vx*vx + vy*vy /= 0 
        		  	IMPLIES
        		  	(sx+vx*t)*(sx+vx*t) + (sy+vy*t)*(sy+vy*t) >= D 

  END circles_and_lines


body:
  root: THEORY

  % Computes nth root %

  % Narkawicz 12/13 %

  BEGIN


    r,x,y: VAR real
    n: VAR posnat
    epsil,delta: VAR posreal
    f,g : VAR [real->real]
    nnr,nnx: VAR nnreal
    m : VAR nat

    mult_expt_pos: LEMMA
      (x*y)^n = x^n*y^n

    real_mult_cont: LEMMA
      (FORALL (epsil,x): EXISTS (delta): FORALL (y):
        abs(x-y)<delta IMPLIES abs(f(x)-f(y))<epsil) AND
      (FORALL (epsil,x): EXISTS (delta): FORALL (y):
        abs(x-y)<delta IMPLIES abs(g(x)-g(y))<epsil)
      IMPLIES
      (FORALL (epsil,x): EXISTS (delta): FORALL (y):
        abs(x-y)<delta IMPLIES abs(f(x)*g(x)-f(y)*g(y))<epsil)
    
    expt_increasing: LEMMA
      nnr<=nnx IMPLIES nnr^m<=nnx^m

    expt_cont: LEMMA
      EXISTS (delta): FORALL (y):
        abs(x-y)<=delta IMPLIES abs(x^n-y^n)<epsil

    nn_root_exists: LEMMA
      EXISTS (nnx): nnx^n=nnr

    root_pos(nnr,n): {nnx|nnx^n=nnr}

    root_real(r)(n|r>=0 OR odd?(n)): {x | (x=0 IFF r = 0) AND
    		      	 	       	 (x>0 IFF r>0) AND
  					 (x<0 IFF r<0) AND
  					 (x>=0 IFF r>=0) AND
  					 (x<=0 IFF r<=0) AND
  					 x^n = r}
      = IF r=0 THEN 0
        ELSIF r>0 THEN root_pos(r,n)
        ELSE -1*root_pos(-r,n) ENDIF


  END root

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

  % Subtype TCC generated (at line 18, column 10) for  n
      % expected type  {i: int | (x * y) /= 0 OR i >= 0}
  mult_expt_pos_TCC1: OBLIGATION
    FORALL (n: posnat, x, y: real): (x * y) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 18, column 16) for  n
      % expected type  {i: int | x /= 0 OR i >= 0}
  mult_expt_pos_TCC2: OBLIGATION
    FORALL (n: posnat, x: real): x /= 0 OR n >= 0;

  % Subtype TCC generated (at line 30, column 25) for  m
      % expected type  {i: int | nnr /= 0 OR i >= 0}
  expt_increasing_TCC1: OBLIGATION
    FORALL (m: nat, nnr, nnx: nnreal): nnr <= nnx IMPLIES nnr /= 0 OR m >= 0;

  % Subtype TCC generated (at line 30, column 32) for  m
      % expected type  {i: int | nnx /= 0 OR i >= 0}
  expt_increasing_TCC2: OBLIGATION
    FORALL (m: nat, nnr, nnx: nnreal): nnr <= nnx IMPLIES nnx /= 0 OR m >= 0;

  % Subtype TCC generated (at line 34, column 40) for  n
      % expected type  {i: int | y /= 0 OR i >= 0}
  expt_cont_TCC1: OBLIGATION
    FORALL (n: posnat, x: real, delta: posreal, y: real):
      abs(x - y) <= delta IMPLIES y /= 0 OR n >= 0;

  % Subtype TCC generated (at line 37, column 22) for  n
      % expected type  {i: int | nnx /= 0 OR i >= 0}
  nn_root_exists_TCC1: OBLIGATION
    FORALL (n: posnat, nnx: nnreal): nnx /= 0 OR n >= 0;

  % Existence TCC generated (at line 39, column 2) for
      % root_pos(nnr, n): {nnx | nnx ^ n = nnr}
  root_pos_TCC1: OBLIGATION
    EXISTS (x: [d: [nnreal, posnat] -> {nnx | nnx ^ d`2 = d`1}]): TRUE;

  % Subtype TCC generated (at line 47, column 18) for  0
      % expected type  {x |
                     %               (x = 0 IFF r = 0) AND (x > 0 IFF r > 0)
                     %           AND (x < 0 IFF r < 0) AND (x >= 0 IFF r >= 0)
                     %           AND (x <= 0 IFF r <= 0) AND x ^ n = r}
  root_real_TCC1: OBLIGATION
    FORALL (r: real, n: posnat | r >= 0 OR odd?(n)):
      r = 0 IMPLIES
            (TRUE IFF r = 0) AND (0 > 0 IFF r > 0) AND (0 < 0 IFF r < 0)
        AND (0 >= 0 IFF r >= 0) AND (0 <= 0 IFF r <= 0) AND 0 ^ n = r;

  % Subtype TCC generated (at line 48, column 30) for  r
      % expected type  nnreal
  root_real_TCC2: OBLIGATION
    FORALL (r: real, n: posnat | r >= 0 OR odd?(n)):
      r > 0 AND NOT r = 0 IMPLIES r >= 0;

  % Subtype TCC generated (at line 48, column 21) for  root_pos(r, n)
      % expected type  {x |
                     %               (x = 0 IFF r = 0) AND (x > 0 IFF r > 0)
                     %           AND (x < 0 IFF r < 0) AND (x >= 0 IFF r >= 0)
                     %           AND (x <= 0 IFF r <= 0) AND x ^ n = r}
  root_real_TCC3: OBLIGATION
    FORALL (r: real, n: posnat | r >= 0 OR odd?(n)):
      r > 0 AND NOT r = 0 IMPLIES
            (root_pos(r, n) = 0 IFF r = 0) AND (root_pos(r, n) > 0 IFF r > 0)
        AND (root_pos(r, n) < 0 IFF r < 0)
        AND (root_pos(r, n) >= 0 IFF r >= 0)
        AND (root_pos(r, n) <= 0 IFF r <= 0) AND root_pos(r, n) ^ n = r;

  % Subtype TCC generated (at line 49, column 23) for  -r
      % expected type  nnreal
  root_real_TCC4: OBLIGATION
    FORALL (r: real, n: posnat | r >= 0 OR odd?(n)):
      NOT r > 0 AND NOT r = 0 IMPLIES -r >= 0;

  % Subtype TCC generated (at line 49, column 11) for  -1 * root_pos(-r, n)
      % expected type  {x |
                     %               (x = 0 IFF r = 0) AND (x > 0 IFF r > 0)
                     %           AND (x < 0 IFF r < 0) AND (x >= 0 IFF r >= 0)
                     %           AND (x <= 0 IFF r <= 0) AND x ^ n = r}
  root_real_TCC5: OBLIGATION
    FORALL (r: real, n: posnat | r >= 0 OR odd?(n)):
      NOT r > 0 AND NOT r = 0 IMPLIES
            (-1 * root_pos(-r, n) = 0 IFF r = 0)
        AND (-1 * root_pos(-r, n) > 0 IFF r > 0)
        AND (-1 * root_pos(-r, n) < 0 IFF r < 0)
        AND (-1 * root_pos(-r, n) >= 0 IFF r >= 0)
        AND (-1 * root_pos(-r, n) <= 0 IFF r <= 0)
        AND (-1 * root_pos(-r, n)) ^ n = r;


body:
  abs_lems : THEORY
  BEGIN

    x,y  : VAR real
    t,a,b: VAR real
    z    : VAR nzreal
    n    : VAR nat

    IMPORTING sq,root

    abs_eq_0         : LEMMA abs(x) = 0 IFF x = 0

    abs_0            : LEMMA abs(0) = 0

    abs_nat          : LEMMA abs(n) = n

    abs_diff         : LEMMA abs(x) - abs(y) <= abs(x - y)

    abs_neg          : LEMMA abs(-x) = abs(x)

    abs_diff_commute : LEMMA abs(x - y) = abs(y - x)

    abs_diff_0       : LEMMA x = y IFF abs(x - y) = 0

    abs_add_pos      : LEMMA 
      x*y >= 0 IMPLIES
      abs(x+y) = abs(x)+abs(y)

    triangle2        : LEMMA abs(x - t) < a AND abs(x - y) < b 
                                        IMPLIES abs(t - y) < a + b

    abs_sq           : LEMMA abs(sq(a)) = sq(a)

    abs_lt           : LEMMA abs(x) < a IFF x > -a AND x < a
    abs_le           : LEMMA abs(x) <= a IFF x >= -a AND x <= a

    abs_gt           : LEMMA abs(x) > a IFF x < -a OR x > a
    abs_ge           : LEMMA abs(x) >= a IFF x <= -a OR x >= a

    abs_pos          : LEMMA abs(x) > 0 IFF x /= 0

    gt_abs           : LEMMA a > abs(x) IFF x > -a AND x < a
    ge_abs           : LEMMA a >= abs(x) IFF x >= -a AND x <= a

    lt_abs           : LEMMA a < abs(x) IFF x < -a OR x > a
    le_abs           : LEMMA a <= abs(x) IFF x <= -a OR x >= a

    pos_abs          : LEMMA 0 < abs(x) IFF x /= 0


  % -------- abs(f) and abs of linear function: minimum property ----

     f: VAR [real -> real]
     m: VAR real


     abs_mono_inc: LEMMA
                     m*t + b = 0 AND
                     t <= x AND x <= y
                     IMPLIES
                            abs(m*x+b) <= abs(m*y+b)


     abs_mono_dec: LEMMA
                     m*t + b = 0 AND
                     x <= y AND y <= t
                     IMPLIES
                            abs(m*x+b) >= abs(m*y+b)




    AUTO_REWRITE+  abs_0
    AUTO_REWRITE+  abs_nat

    AUTO_REWRITE-  abs_diff_commute

    abs_root: LEMMA n>0 AND (x<0 IMPLIES odd?(n))
    	    	  IMPLIES abs(root_real(x)(n)) =
    	    	  root_real(abs(x))(n)

  END abs_lems

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

  % Subtype TCC generated (at line 79, column 35) for  n
      % expected type  n: {n | x >= 0 OR odd?(n)}
  abs_root_TCC1: OBLIGATION
    FORALL (n: nat, x: real):
      (x < 0 IMPLIES odd?(n)) AND n > 0 IMPLIES x >= 0 OR odd?(n);

  % Subtype TCC generated (at line 80, column 28) for  n
      % expected type  n: {n | abs(x) >= 0 OR odd?(n)}
  abs_root_TCC2: OBLIGATION
    FORALL (n: nat, x: real):
      (x < 0 IMPLIES odd?(n)) AND n > 0 IMPLIES abs(x) >= 0 OR odd?(n);


body:
  old_sigma[T: TYPE FROM int]: THEORY
  %------------------------------------------------------------------------------
  % The summations theory introduces and defines properties of the sigma 
  % function that sums an arbitrary function F: [T -> real] over a range
  % from low to high
  %
  %  		          high
  %		          ----
  %  sigma(low, high, F) =  \     F(j)
  %		          /
  %		          ----
  %		         j = low
  %
  %  NOTE:
  %
  %     This is the generic theory.  It is usually preferable to use
  %     sigma_nat, sigma_int, sigma_below, etc.
  %
  %  MODIFICATIONS:
  %
  %    8/7/01   added sigma_zero, sigma_with 
  %
  %    3/24/06  generalized to allow index ranges to fall outside of
  %             domain of T when high < low.  This upgrade will break
  %             some old proofs, but will reduce TCC generation significantly
  %  
  %  AUTHORS:
  %
  %    Rick Butler     NASA Langley Research Center           
  %    Paul Miner      NASA Langley Research Center           
  %
  %------------------------------------------------------------------------------

  BEGIN

    ASSUMING

      connected_domain: ASSUMPTION (FORALL (x, y: T), (z: integer):
                                         x <= z AND z <= y IMPLIES T_pred(z))

    ENDASSUMING

    T_low?: MACRO set[int] = {i:int | EXISTS (j:T): j <= i}
    T_low  : TYPE = {i:int | T_pred(i) OR T_low?(i)}

    T_high?: MACRO set[int] = {i:int | EXISTS (j:T): i <= j}
    T_high : TYPE = {i:int | T_pred(i) OR T_high?(i)}

    low       : VAR T_low
    high      : VAR T_high 
    l,h,n,m,i : VAR T
    rng, nn   : VAR nat
    pn        : VAR posnat
    z         : VAR int
    a,x,B     : VAR real

    T_pred_lem : LEMMA low <= z AND z <= high IMPLIES T_pred(z)

  % AUTO_REWRITE+ T_pred_lem  %% THIS DOES NOT HELP

  % T_pred_low : LEMMA low <= m IMPLIES T_pred(low)
  % T_pred_high: LEMMA m <= high IMPLIES T_pred(high)
  %  AUTO_REWRITE+ T_pred_low, T_pred_high  %% DOES NOT HELP

    high_low_rewrite: LEMMA
     (FORALL (p: pred[[T_high, T_low]]):
       (FORALL (high: T_high), (low: T_low):
        IF high < low THEN p(high, low) 
        ELSE (FORALL (n: subrange(low, high)): p(n, low))
        ENDIF)
      IMPLIES
        (FORALL high, low:  p(high, low)))


    F, G: VAR function[T -> real]
    
    sigma(low, high, F): RECURSIVE real
        = IF low > high THEN 0
          ELSIF high = low THEN F(low) 
          ELSE  F(high) + sigma(low, high-1, F)
          ENDIF
     MEASURE (LAMBDA low, high, F: abs(high+1-low))

  % ---- the following rewrite can be used in place of "expand" to obtain a more
  % ---- compact expansion.  The above form retained for upward compatibility.

    sigma_rew: LEMMA sigma(low, high, F) = IF low > high THEN 0
         					 ELSE  F(high) + sigma(low, high-1, F)
         					 ENDIF                            


    sigma_spl     : THEOREM T_pred(low + nn + rng) IMPLIES 
                             sigma(low, low+nn+rng, F) = 
                                sigma(low,low+nn,F) + sigma(low+nn+1,low+nn+rng,F)

    sigma_split   : THEOREM low - 1 <= z AND z <= high IMPLIES 
                              sigma(low, high, F) = 
                                       sigma(low, z, F) + sigma(z+1, high, F)


  % Both of the following are now coverd by sigma_split

  %   sigma_split_l: THEOREM %T_pred(low-1) AND
  %                           low-1 <= m AND m < high IMPLIES 
  %                             sigma(low, high, F) = 
  %                                      sigma(low, m, F) + sigma(m+1, high, F)


  %   sigma_split_h: THEOREM low <= m AND m <= high AND T_pred(m+1) IMPLIES 
  %                             sigma(low, high, F) = 
  %                                      sigma(low, m, F) + sigma(m+1, high, F)


    sigma_diff    : THEOREM low - 1 <= z AND z <= high IMPLIES
                      sigma(low, high, F) - sigma(low, z, F) = sigma(z+1, high, F)

    sigma_diff_neg: THEOREM low - 1 <= z AND z <= high IMPLIES
                    sigma(low, z, F) - sigma(low, high, F) = - sigma(z+1, high, F)
   		 
    sigma_eq_arg  : THEOREM sigma(m, m, F) = F(m)

    sigma_first   : THEOREM high >= low IMPLIES 
                             sigma(low, high, F) = F(low) + sigma(low+1, high, F)

    sigma_last    : THEOREM high >= low IMPLIES 
                            sigma(low, high, F) = sigma(low, high-1, F) + F(high)

    sigma_middle : THEOREM high >= i AND i >= low IMPLIES
                            sigma(low, high, F) = sigma(low, i-1, F) + F(i) +
                                                  sigma(i+1, high, F) 

  %  Covered by sigma_middle
  %   sigma_mid     : THEOREM high >= i AND i >= low AND T_pred(i-1) AND T_pred(i+1) 
  %                           IMPLIES 
  %                           sigma(low, high, F) = sigma(low, i-1, F) + F(i) +
  %                                                 sigma(i+1, high, F) 



    sigma_const   : THEOREM sigma(low, high, (LAMBDA i: x)) = 
                             IF high >= low THEN (high-low+1) * x ELSE 0 ENDIF


    sigma_zero    : THEOREM sigma(low, high, (LAMBDA i: 0)) = 0
   		 
    sigma_scal    : THEOREM sigma(low, high, (LAMBDA i: a * F(i)))
                               = a * sigma(low, high, F)
  		 
    sigma_bound   : THEOREM low - 1 <= high AND
                           (FORALL i: i >= low AND i <= high IMPLIES F(i) <= B)
                              IMPLIES sigma(low, high, F) <= B*(high-low+1) %was abs(high-low+1)

    sigma_abs     : THEOREM abs(sigma(low, high, F)) <= 
                                sigma(low, high, LAMBDA (n: T): abs(F(n)))

    sigma_ge_0    : THEOREM (FORALL (n: subrange(low,high)): F(n) >= 0)
                                  IMPLIES sigma(low,high,F) >= 0

    sigma_gt_0    : THEOREM low <= high AND 
                            (FORALL (n: subrange(low,high)): F(n) > 0)
                                  IMPLIES sigma(low,high,F) > 0


    sigma_shift_T : THEOREM (FORALL (i:T): T_pred(i+z)) IMPLIES 
  			         sigma(low+z,high+z,F) = 
                                      sigma(low,high, (LAMBDA (i:T): F(i+z)))

    sigma_shift_T2 : THEOREM T_pred(low+z) AND T_pred(high+z) IMPLIES 
  			         sigma(low+z,high+z,F) = 
                   sigma(low,high, (LAMBDA (i:T): IF T_pred(i+z) THEN F(i+z)
                                                  ELSE 0 ENDIF))


  % ------------------ Summation Involving Two Functions ------------------

    sigma_sum     : THEOREM sigma(low, high, F) + sigma(low, high, G)
                               = sigma(low, high, (LAMBDA i: F(i) + G(i)))

    sigma_minus   : THEOREM sigma(low, high, F) - sigma(low, high, G)
                               = sigma(low, high, (LAMBDA i: F(i) - G(i)))

    sigma_abs_bnd  : THEOREM (FORALL (i: subrange(low,high)): abs(F(i)) <= G(i))
                         IMPLIES sigma(low, high, LAMBDA (n: T): abs(F(n))) <=
                                          sigma(low, high, G)

    restrict(F, low, high): function[T -> real] = 
       (LAMBDA i: IF i < low OR i > high THEN 0 ELSE F(i) ENDIF )

    sigma_restrict   : THEOREM l <= low AND h >= high IMPLIES	
                              sigma(low,high,F) = sigma(low,high,restrict(F,l,h))


    sigma_restrict_to: THEOREM sigma(low,high,F) = 
                                  sigma(low,high,restrict(F,low,high))

    sigma_restrict_eq: THEOREM restrict(F,low,high) = restrict(G,low,high) 
                                  IMPLIES sigma(low,high,F) = sigma(low,high,G) 


    sigma_eq         : THEOREM (FORALL (n: subrange(low,high)): F(n) = G(n))
                                  IMPLIES sigma(low,high,F) = sigma(low,high,G) 


    sigma_le         : THEOREM (FORALL (n: subrange(low,high)): F(n) <= G(n))
                                  IMPLIES sigma(low,high,F) <= sigma(low,high,G) 

    sigma_lt         : THEOREM low <= high AND
                               (FORALL (n: subrange(low,high)): F(n) < G(n))
                                  IMPLIES sigma(low,high,F) < sigma(low,high,G) 


    sigma_with       : THEOREM low <= i AND i <= high AND
                               F = G WITH [i := a] IMPLIES
                            sigma(low, high,F) = sigma(low,high,G) - G(i) + a


  % ------------------------ Special Arguments --------------------------------

    sigma_nonneg     : THEOREM (FORALL i: F(i) >= 0) 
                                   IMPLIES sigma(low, high, F) >= 0
   
    sigma_nonpos     : THEOREM (FORALL i: F(i) <= 0) 
                                   IMPLIES sigma(low, high, F) <= 0


    Fnnr: VAR function[T -> nonneg_real]
    Fnpr: VAR function[T -> nonpos_real]
    Fnat: VAR function[T -> nat]
    Fnpi: VAR function[T -> nonpos_int]

    JUDGEMENT sigma(low,high,Fnnr) HAS_TYPE nonneg_real

    JUDGEMENT sigma(low,high,Fnpr) HAS_TYPE nonpos_real

    JUDGEMENT sigma(low,high,Fnat) HAS_TYPE nat

    JUDGEMENT sigma(low,high,Fnpi) HAS_TYPE nonpos_int

    sigma_nonneg_eq_0  : THEOREM sigma(low,high,Fnnr) = 0 
                                AND low <= i AND i <= high IMPLIES Fnnr(i) = 0

    sigma_nn_ge_comps  : THEOREM low <= i AND i <= high IMPLIES 
                                    sigma(low,high,Fnnr) >= Fnnr(i) 

  % ------------------- Iterative Summation (tail recursion) ------------

     sum_it_def(low, high, F,a): RECURSIVE real
        = IF low > high THEN a
          ELSE  sum_it_def(low+1,high,F,a+F(low))
          ENDIF
     MEASURE (LAMBDA low, high, F, a: abs(high+1-low))

     sum_it(low,high,F) : real = sum_it_def(low,high,F,0)

     sum_it_prop : LEMMA
       low - 1 <= i AND i <= high =>
       sum_it_def(i+1,high,F,sigma(low,i,F)) = sigma(low,high,F)

     sum_it_sigma: LEMMA sum_it(low,high,F) = sigma(low,high,F)

  % Note: We would have preferred to use the following definitions:
  %
  %   T_low?: MACRO set[int] = {i:int | EXISTS (j:T): j <= i}
  %   T_low  : TYPE = {i:int | T_low?(i)}
  %
  %   T_high?: MACRO set[int] = {i:int | EXISTS (j:T): i <= j}
  %   T_high : TYPE = {i:int | T_high?(i)}
  %
  % but could not find any judgements that would fire and prevent
  % spurious TCC generation.

  END old_sigma

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

  % Subtype TCC generated (at line 69, column 47) for  n
      % expected type  T_high
  high_low_rewrite_TCC1: OBLIGATION
    FORALL (high: T_high, low: T_low):
      NOT high < low IMPLIES
       (FORALL (n: subrange(low, high)):
          T_pred(n) OR (EXISTS (j: T): n <= j));

  % Subtype TCC generated (at line 79, column 32) for  low
      % expected type  T
  sigma_TCC1: OBLIGATION
    FORALL (low: T_low, high: T_high):
      high = low AND NOT low > high IMPLIES T_pred(low);

  % Subtype TCC generated (at line 80, column 16) for  high
      % expected type  T
  sigma_TCC2: OBLIGATION
    FORALL (low: T_low, high: T_high):
      NOT high = low AND NOT low > high IMPLIES T_pred(high);

  % Subtype TCC generated (at line 80, column 35) for  high - 1
      % expected type  T_high
  sigma_TCC3: OBLIGATION
    FORALL (low: T_low, high: T_high):
      NOT high = low AND NOT low > high IMPLIES
       T_pred(high - 1) OR (EXISTS (j: T): high - 1 <= j);

  % Termination TCC generated (at line 80, column 24) for
      % sigma(low, high - 1, F)
  sigma_TCC4: OBLIGATION
    FORALL (low: T_low, high: T_high):
      NOT high = low AND NOT low > high IMPLIES
       abs(high - 1 + 1 - low) < abs(high + 1 - low);

  % Subtype TCC generated (at line 88, column 21) for  high
      % expected type  T
  sigma_rew_TCC1: OBLIGATION
    FORALL (high: T_high, low: T_low): NOT low > high IMPLIES T_pred(high);

  % Subtype TCC generated (at line 88, column 40) for  high - 1
      % expected type  T_high
  sigma_rew_TCC2: OBLIGATION
    FORALL (high: T_high, low: T_low):
      NOT low > high IMPLIES
       T_pred(high - 1) OR (EXISTS (j: T): high - 1 <= j);

  % Subtype TCC generated (at line 93, column 38) for  low + nn + rng
      % expected type  T_high
  sigma_spl_TCC1: OBLIGATION
    FORALL (low: T_low, nn, rng: nat):
      T_pred(low + nn + rng) IMPLIES
       T_pred(low + nn + rng) OR (EXISTS (j: T): low + nn + rng <= j);

  % Subtype TCC generated (at line 94, column 40) for  low + nn
      % expected type  T_high
  sigma_spl_TCC2: OBLIGATION
    FORALL (low: T_low, nn, rng: nat):
      T_pred(low + nn + rng) IMPLIES
       T_pred(low + nn) OR (EXISTS (j: T): low + nn <= j);

  % Subtype TCC generated (at line 94, column 58) for  low + nn + 1
      % expected type  T_low
  sigma_spl_TCC3: OBLIGATION
    FORALL (low: T_low, nn, rng: nat):
      T_pred(low + nn + rng) IMPLIES
       T_pred(low + nn + 1) OR (EXISTS (j: T): j <= low + nn + 1);

  % Subtype TCC generated (at line 98, column 48) for  z
      % expected type  T_high
  sigma_split_TCC1: OBLIGATION
    FORALL (high: T_high, low: T_low, z: int):
      z <= high AND low - 1 <= z IMPLIES T_pred(z) OR (EXISTS (j: T): z <= j);

  % Subtype TCC generated (at line 98, column 62) for  z + 1
      % expected type  T_low
  sigma_split_TCC2: OBLIGATION
    FORALL (high: T_high, low: T_low, z: int):
      z <= high AND low - 1 <= z IMPLIES
       T_pred(z + 1) OR (EXISTS (j: T): j <= z + 1);

  % Subtype TCC generated (at line 123, column 51) for  low
      % expected type  T
  sigma_first_TCC1: OBLIGATION
    FORALL (high: T_high, low: T_low): high >= low IMPLIES T_pred(low);

  % Subtype TCC generated (at line 123, column 64) for  low + 1
      % expected type  T_low
  sigma_first_TCC2: OBLIGATION
    FORALL (high: T_high, low: T_low):
      high >= low IMPLIES T_pred(low + 1) OR (EXISTS (j: T): j <= low + 1);

  % Subtype TCC generated (at line 126, column 59) for  high - 1
      % expected type  T_high
  sigma_last_TCC1: OBLIGATION
    FORALL (high: T_high, low: T_low):
      high >= low IMPLIES T_pred(high - 1) OR (EXISTS (j: T): high - 1 <= j);

  % Subtype TCC generated (at line 126, column 74) for  high
      % expected type  T
  sigma_last_TCC2: OBLIGATION
    FORALL (high: T_high, low: T_low): high >= low IMPLIES T_pred(high);

  % Subtype TCC generated (at line 129, column 59) for  i - 1
      % expected type  T_high
  sigma_middle_TCC1: OBLIGATION
    FORALL (high: T_high, i: T, low: T_low):
      i >= low AND high >= i IMPLIES
       T_pred(i - 1) OR (EXISTS (j: T): i - 1 <= j);

  % Subtype TCC generated (at line 130, column 54) for  i + 1
      % expected type  T_low
  sigma_middle_TCC2: OBLIGATION
    FORALL (high: T_high, i: T, low: T_low):
      i >= low AND high >= i IMPLIES
       T_pred(i + 1) OR (EXISTS (j: T): j <= i + 1);

  % Subtype TCC generated (at line 156, column 61) for  n
      % expected type  T
  sigma_ge_0_TCC1: OBLIGATION
    FORALL (high: T_high, low: T_low, n: subrange(low, high)): T_pred(n);

  % Subtype TCC generated (at line 165, column 18) for  low + z
      % expected type  T_low
  sigma_shift_T_TCC1: OBLIGATION
    FORALL (low: T_low, z: int):
      (FORALL (i: T): T_pred(i + z)) IMPLIES
       T_pred(low + z) OR (EXISTS (j: T): j <= low + z);

  % Subtype TCC generated (at line 165, column 24) for  high + z
      % expected type  T_high
  sigma_shift_T_TCC2: OBLIGATION
    FORALL (high: T_high, z: int):
      (FORALL (i: T): T_pred(i + z)) IMPLIES
       T_pred(high + z) OR (EXISTS (j: T): high + z <= j);

  % Subtype TCC generated (at line 166, column 69) for  i + z
      % expected type  T
  sigma_shift_T_TCC3: OBLIGATION
    FORALL (z: int):
      (FORALL (i: T): T_pred(i + z)) IMPLIES (FORALL (i1: T): T_pred(i1 + z));

  % Subtype TCC generated (at line 169, column 18) for  low + z
      % expected type  T_low
  sigma_shift_T2_TCC1: OBLIGATION
    FORALL (high: T_high, low: T_low, z: int):
      T_pred(high + z) AND T_pred(low + z) IMPLIES
       T_pred(low + z) OR (EXISTS (j: T): j <= low + z);

  % Subtype TCC generated (at line 169, column 24) for  high + z
      % expected type  T_high
  sigma_shift_T2_TCC2: OBLIGATION
    FORALL (high: T_high, low: T_low, z: int):
      T_pred(high + z) AND T_pred(low + z) IMPLIES
       T_pred(high + z) OR (EXISTS (j: T): high + z <= j);

  % Judgement subtype TCC generated (at line 231, column 12) for
      % sigma(low, high, Fnnr)
      % expected type  nonneg_real
  sigma_TCC5: OBLIGATION
    FORALL (Fnnr, high, low): sigma(low, high, Fnnr) >= 0;

  % Judgement subtype TCC generated (at line 233, column 12) for
      % sigma(low, high, Fnpr)
      % expected type  nonpos_real
  sigma_TCC6: OBLIGATION
    FORALL (Fnpr, high, low): sigma(low, high, Fnpr) <= 0;

  % Judgement subtype TCC generated (at line 235, column 12) for
      % sigma(low, high, Fnat)
      % expected type  nat
  sigma_TCC7: OBLIGATION
    FORALL (Fnat, high, low):
      rational_pred(sigma(low, high, Fnat)) AND
       integer_pred(sigma(low, high, Fnat)) AND sigma(low, high, Fnat) >= 0;

  % Judgement subtype TCC generated (at line 237, column 12) for
      % sigma(low, high, Fnpi)
      % expected type  nonpos_int
  sigma_TCC8: OBLIGATION
    FORALL (Fnpi, high, low):
      rational_pred(sigma(low, high, Fnpi)) AND
       integer_pred(sigma(low, high, Fnpi)) AND sigma(low, high, Fnpi) <= 0;

  % Subtype TCC generated (at line 249, column 25) for  low + 1
      % expected type  T_low
  sum_it_def_TCC1: OBLIGATION
    FORALL (low: T_low, high: T_high):
      NOT low > high IMPLIES T_pred(low + 1) OR (EXISTS (j: T): j <= low + 1);

  % Subtype TCC generated (at line 249, column 42) for  low
      % expected type  T
  sum_it_def_TCC2: OBLIGATION
    FORALL (low: T_low, high: T_high): NOT low > high IMPLIES T_pred(low);

  % Termination TCC generated (at line 249, column 14) for
      % sum_it_def(low + 1, high, F, a + F(low))
  sum_it_def_TCC3: OBLIGATION
    FORALL (low: T_low, high: T_high):
      NOT low > high IMPLIES abs(high + 1 - (low + 1)) < abs(high + 1 - low);

  % Subtype TCC generated (at line 257, column 16) for  i + 1
      % expected type  T_low
  sum_it_prop_TCC1: OBLIGATION
    FORALL (high: T_high, i: T, low: T_low):
      i <= high AND low - 1 <= i IMPLIES
       T_pred(i + 1) OR (EXISTS (j: T): j <= i + 1);


body:
  mixed_sigmas[T, H: TYPE FROM int]: THEORY


  BEGIN

    ASSUMING

       connected_domain1: ASSUMPTION (FORALL (x, y: T), (z: integer):
                                         x <= z AND z <= y IMPLIES T_pred(z))

       connected_domain2: ASSUMPTION (FORALL (x, y: H), (z: integer):
                                         x <= z AND z <= y IMPLIES H_pred(z))

    ENDASSUMING

    IMPORTING sigma[T],sigma[H]


    tlow      : VAR T_low[T]
    thigh     : VAR T_high[T]
    hlow      : VAR T_low[H]
    hhigh     : VAR T_high[H]
    i,j       : VAR T
    k,l	    : VAR H
    rng, nn   : VAR nat
    pn        : VAR posnat
    z         : VAR int
    a,x,B     : VAR real


    F : VAR [T -> real]

    G : VAR [H -> real]

    mixed_sigmas_const_eq: LEMMA
      thigh-tlow = hhigh-hlow AND 
      (FORALL (i:nat): i<=thigh-tlow IMPLIES F(tlow + i) = G(hlow + i))
      IMPLIES
      x*sigma[T](tlow,thigh,F) = x*sigma[H](hlow,hhigh,G)
      

   mixed_sigmas_eq: LEMMA
      thigh-tlow = hhigh-hlow AND 
      (FORALL (i:nat): i<=thigh-tlow IMPLIES F(tlow + i) = G(hlow + i))
      IMPLIES
      sigma[T](tlow,thigh,F) = sigma[H](hlow,hhigh,G)

  END mixed_sigmas

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

  % Assuming TCC generated (at line 16, column 12) for  sigma[T]
      % generated from assumption sigma.connected_domain
  IMP_sigma_TCC1: OBLIGATION
    (FORALL (x, y: T), (z: integer): x <= z AND z <= y IMPLIES T_pred(z));

  % Assuming TCC generated (at line 16, column 21) for  sigma[H]
      % generated from assumption sigma.connected_domain
  IMP_sigma_TCC2: OBLIGATION
    (FORALL (x, y: H), (z: integer): x <= z AND z <= y IMPLIES H_pred(z));

  % Subtype TCC generated (at line 37, column 45) for  tlow + i
      % expected type  T
  mixed_sigmas_const_eq_TCC1: OBLIGATION
    FORALL (hhigh: T_high[H], hlow: T_low[H], thigh: T_high[T],
            tlow: T_low[T]):
      thigh - tlow = hhigh - hlow IMPLIES
       (FORALL (i: nat): i <= thigh - tlow IMPLIES T_pred(tlow + i));

  % Subtype TCC generated (at line 37, column 59) for  hlow + i
      % expected type  H
  mixed_sigmas_const_eq_TCC2: OBLIGATION
    FORALL (hhigh: T_high[H], hlow: T_low[H], thigh: T_high[T],
            tlow: T_low[T]):
      thigh - tlow = hhigh - hlow IMPLIES
       (FORALL (i: nat): i <= thigh - tlow IMPLIES H_pred(hlow + i));


body:
  mixed_products[T, H: TYPE FROM int]: THEORY


  BEGIN

    ASSUMING

       connected_domain1: ASSUMPTION (FORALL (x, y: T), (z: integer):
                                         x <= z AND z <= y IMPLIES T_pred(z))

       connected_domain2: ASSUMPTION (FORALL (x, y: H), (z: integer):
                                         x <= z AND z <= y IMPLIES H_pred(z))

    ENDASSUMING

    IMPORTING product[T],product[H]


    tlow      : VAR T_low[T]
    thigh     : VAR T_high[T]
    hlow      : VAR T_low[H]
    hhigh     : VAR T_high[H]
    i,j       : VAR T
    k,l	    : VAR H
    rng, nn   : VAR nat
    pn        : VAR posnat
    z         : VAR int
    a,x,B     : VAR real


    F : VAR [T -> real]

    G : VAR [H -> real]

    mixed_products_const_eq: LEMMA
      thigh-tlow = hhigh-hlow AND 
      (FORALL (i:nat): i<=thigh-tlow IMPLIES F(tlow + i) = G(hlow + i))
      IMPLIES
      x*product[T](tlow,thigh,F) = x*product[H](hlow,hhigh,G)

   mixed_products_eq: LEMMA
      thigh-tlow = hhigh-hlow AND 
      (FORALL (i:nat): i<=thigh-tlow IMPLIES F(tlow + i) = G(hlow + i))
      IMPLIES
      product[T](tlow,thigh,F) = product[H](hlow,hhigh,G)

  END mixed_products

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

  % Assuming TCC generated (at line 16, column 12) for  product[T]
      % generated from assumption product.connected_domain
  IMP_product_TCC1: OBLIGATION
    (FORALL (x, y: T), (z: integer): x <= z AND z <= y IMPLIES T_pred(z));

  % Assuming TCC generated (at line 16, column 23) for  product[H]
      % generated from assumption product.connected_domain
  IMP_product_TCC2: OBLIGATION
    (FORALL (x, y: H), (z: integer): x <= z AND z <= y IMPLIES H_pred(z));

  % Subtype TCC generated (at line 37, column 45) for  tlow + i
      % expected type  T
  mixed_products_const_eq_TCC1: OBLIGATION
    FORALL (hhigh: T_high[H], hlow: T_low[H], thigh: T_high[T],
            tlow: T_low[T]):
      thigh - tlow = hhigh - hlow IMPLIES
       (FORALL (i: nat): i <= thigh - tlow IMPLIES T_pred(tlow + i));

  % Subtype TCC generated (at line 37, column 59) for  hlow + i
      % expected type  H
  mixed_products_const_eq_TCC2: OBLIGATION
    FORALL (hhigh: T_high[H], hlow: T_low[H], thigh: T_high[T],
            tlow: T_low[T]):
      thigh - tlow = hhigh - hlow IMPLIES
       (FORALL (i: nat): i <= thigh - tlow IMPLIES H_pred(hlow + i));


body:
  sigma_fseq_def[T: TYPE+ FROM real]: THEORY
  %------------------------------------------------------------------------------
  % The summations theory provides properties of the sigma 
  % function that sums up sequence of reals
  %
  %  		           l(fs)
  %		           ----
  %             sigma(fs) =  \     fs`seq(j)
  %		           /
  %		           ----
  %		          j = 0
  %------------------------------------------------------------------------------


  BEGIN

    IMPORTING sigma_nat, structures@fseqs

    fs: VAR fseq[T]

    sigma(fs): real = sigma(0,l(fs)-1,(LAMBDA (n: nat): fs`seq(n)))
   
                                                
  END sigma_fseq_def

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

  % Subtype TCC generated (at line 21, column 28) for  fs`length - 1
      % expected type  T_high[nat]
  sigma_TCC1: OBLIGATION
    FORALL (fs: fseq[T]):
      fs`length - 1 >= 0 OR (EXISTS (j: nat): fs`length - 1 <= j);


body:
  sigma_fseq: THEORY
  %------------------------------------------------------------------------------
  % The summations theory provides properties of the sigma 
  % function that sums up a sequence of reals, e.g. fseq[real]
  %
  %  		           l(fs)
  %		           ----
  %             sigma(fs) =  \     fs`seq(j)
  %		           /
  %		           ----
  %		          j = 0
  %
  %  WILL NOT TYPECHECK BECAUSE OF PVS BUG:
  %
  %      Error: the assertion (fully-instantiated? domtypes) failed.
  %       
  %------------------------------------------------------------------------------
  BEGIN

    IMPORTING sigma_fseq_def

    fs_nnr   : VAR fseq[nonneg_real]
    fs_npr   : VAR fseq[nonpos_real]
    fs_nat   : VAR fseq[nat]
    fs_npi   : VAR fseq[nonpos_int]
    fs_posnat: VAR fseq[posnat]


    sigma_fs_nnr	 : JUDGEMENT sigma[nonneg_real](fs_nnr) HAS_TYPE nonneg_real

    sigma_fs_npr	 : JUDGEMENT sigma[nonpos_real](fs_npr) HAS_TYPE nonpos_real

    sigma_fs_nat	 : JUDGEMENT sigma[nat](fs_nat)         HAS_TYPE nat

    sigma_fs_npi	 : JUDGEMENT sigma[nonpos_int](fs_npi)  HAS_TYPE nonpos_int

                                                
  END sigma_fseq

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

  % Judgement subtype TCC generated (at line 29, column 28) for
      % sigma[nonneg_real](fs_nnr)
      % expected type  nonneg_real
  sigma_fs_nnr: OBLIGATION FORALL (fs_nnr): sigma[nonneg_real](fs_nnr) >= 0;

  % Judgement subtype TCC generated (at line 31, column 28) for
      % sigma[nonpos_real](fs_npr)
      % expected type  nonpos_real
  sigma_fs_npr: OBLIGATION FORALL (fs_npr): sigma[nonpos_real](fs_npr) <= 0;

  % Judgement subtype TCC generated (at line 33, column 28) for
      % sigma[nat](fs_nat)
      % expected type  nat
  sigma_fs_nat: OBLIGATION
    FORALL (fs_nat):
      rational_pred(sigma[nat](fs_nat)) AND
       integer_pred(sigma[nat](fs_nat)) AND sigma[nat](fs_nat) >= 0;

  % Judgement subtype TCC generated (at line 35, column 28) for
      % sigma[nonpos_int](fs_npi)
      % expected type  nonpos_int
  sigma_fs_npi: OBLIGATION
    FORALL (fs_npi):
      rational_pred(sigma[nonpos_int](fs_npi)) AND
       integer_pred(sigma[nonpos_int](fs_npi)) AND
        sigma[nonpos_int](fs_npi) <= 0;


body:
  sigma_below[N: posnat]: THEORY %below(0) is an empty type
  %sigma_below[N: nat]: THEORY
  %------------------------------------------------------------------------------
  % The summations theory provides properties of the sigma 
  % function that sums an arbitrary function F: [below[N] -> real] over a range
  % from low to high
  %
  %  		          high
  %		          ----
  %  sigma(low, high, F) =  \     F(j)
  %		          /
  %		          ----
  %		         j = low
  %
  %
  %------------------------------------------------------------------------------


  BEGIN

    IMPORTING sigma[below(N)]

    int_below: TYPE = {i:int | i < N}
    int_below_T_high: JUDGEMENT int_below SUBTYPE_OF T_high
    nat_is_T_low: JUDGEMENT nat SUBTYPE_OF T_low

    low :VAR nat
    high : VAR int_below 
    n, m, i: VAR below[N]
    F: VAR function[below[N] -> real]


  %   play1: LEMMA FORALL (x: below[N]): EXISTS (j: below(N)): j <= x;
  %   play2: LEMMA FORALL (x: below[N]): EXISTS (j: below(N)): x <= j;
  %   AUTO_REWRITE+ play1, play2



  % --------- Following Theorems Not Provable In Generic Framework -------

    sigma_first_ge : THEOREM high >= low IMPLIES
                             sigma(low, high, F) = F(low) + sigma(low+1, high, F)

    sigma_last_ge  : THEOREM high >= low IMPLIES 
                            sigma(low, high, F) = sigma(low, high-1, F) + F(high)

    sigma_split_ge : THEOREM low - 1 <= m AND m <= high IMPLIES 
                              sigma(low, high, F) = 
                                       sigma(low, m, F) + sigma(m+1, high, F)

  % ---- Auto-rewrites


    nn: VAR negint
    sigma_0_neg: LEMMA sigma(0,nn,F) = 0
    AUTO_REWRITE+ sigma_0_neg



  END sigma_below

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

  % Assuming TCC generated (at line 21, column 12) for  sigma[below(N)]
      % generated from assumption sigma.connected_domain
  IMP_sigma_TCC1: OBLIGATION
    (FORALL (x, y: below(N)), (z: integer):
       x <= z AND z <= y IMPLIES z >= 0 AND z < N);

  % Judgement subtype TCC generated (at line 24, column 30) for  x
      % expected type  T_high[below(N)]
  int_below_T_high: OBLIGATION
    FORALL (x: int_below): x >= 0 AND x < N OR (EXISTS (j: below(N)): x <= j);

  % Judgement subtype TCC generated (at line 25, column 26) for  x
      % expected type  T_low[below(N)]
  nat_is_T_low: OBLIGATION
    FORALL (x: nat): x >= 0 AND x < N OR (EXISTS (j: below(N)): j <= x);

  % Subtype TCC generated (at line 42, column 51) for  low
      % expected type  below[N]
  sigma_first_ge_TCC1: OBLIGATION
    FORALL (high: int_below, low: nat): high >= low IMPLIES low < N;

  % Subtype TCC generated (at line 45, column 59) for  high - 1
      % expected type  T_high[below(N)]
  sigma_last_ge_TCC1: OBLIGATION
    FORALL (high: int_below, low: nat):
      high >= low IMPLIES
       high - 1 >= 0 AND high - 1 < N OR
        (EXISTS (j: below(N)): high - 1 <= j);

  % Subtype TCC generated (at line 45, column 74) for  high
      % expected type  below[N]
  sigma_last_ge_TCC2: OBLIGATION
    FORALL (high: int_below, low: nat):
      high >= low IMPLIES high >= 0 AND high < N;

  % Subtype TCC generated (at line 49, column 48) for  m
      % expected type  T_high[below(N)]
  sigma_split_ge_TCC1: OBLIGATION
    FORALL (high: int_below, low: nat, m: below[N]):
      m <= high AND low - 1 <= m IMPLIES
       m >= 0 AND m < N OR (EXISTS (j: below(N)): m <= j);

  % Subtype TCC generated (at line 55, column 29) for  nn
      % expected type  T_high[below(N)]
  sigma_0_neg_TCC1: OBLIGATION
    FORALL (nn: negint):
      nn >= 0 AND nn < N OR (EXISTS (j: below(N)): nn <= j);


body:
  sigma_below_sub[N1,N2: nat]: THEORY
  BEGIN
   
      IMPORTING sigma_below
   
      n0,n,m,i: VAR nat

      f1: VAR [below(N1) -> real]
      f2: VAR [below(N2) -> real]

      sigma_diff_eq: LEMMA n < N1 AND n < N2 AND  n0 <= n AND
                     (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i))
                    IMPLIES
                        sigma[below(N1)](n0,n,f1) = 
                        sigma[below(N2)](n0,n,f2) 



      sigma_diff_shift: LEMMA n < N1 AND n+m < N2 AND  n0 <= n AND
                     (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i+m))
                    IMPLIES
                        sigma[below(N1)](n0,n,f1) = 
                        sigma[below(N2)](n0+m,n+m,f2) 


  END sigma_below_sub

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

  % Subtype TCC generated (at line 12, column 60) for  i
      % expected type  below(N1)
  sigma_diff_eq_TCC1: OBLIGATION
    FORALL (n, n0: nat):
      n < N1 AND n < N2 AND n0 <= n IMPLIES
       (FORALL (i): n0 <= i AND i <= n IMPLIES i < N1);

  % Subtype TCC generated (at line 12, column 68) for  i
      % expected type  below(N2)
  sigma_diff_eq_TCC2: OBLIGATION
    FORALL (n, n0: nat):
      n < N1 AND n < N2 AND n0 <= n IMPLIES
       (FORALL (i): n0 <= i AND i <= n IMPLIES i < N2);

  % Subtype TCC generated (at line 14, column 39) for  n0
      % expected type  T_low[below(N1)]
  sigma_diff_eq_TCC3: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i)) AND
       n0 <= n AND n < N2 AND n < N1
       IMPLIES n0 >= 0 AND n0 < N1 OR (EXISTS (j: below(N1)): j <= n0);

  % Subtype TCC generated (at line 14, column 42) for  n
      % expected type  T_high[below(N1)]
  sigma_diff_eq_TCC4: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i)) AND
       n0 <= n AND n < N2 AND n < N1
       IMPLIES n >= 0 AND n < N1 OR (EXISTS (j: below(N1)): n <= j);

  % Assuming TCC generated (at line 41, column 5) for  sigma[below(N1)]
      % generated from assumption sigma.connected_domain
  sigma_diff_eq_TCC5: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i)) AND
       n0 <= n AND n < N2 AND n < N1
       IMPLIES
       (FORALL (x, y: below(N1)), (z: integer):
          x <= z AND z <= y IMPLIES z >= 0 AND z < N1);

  % Subtype TCC generated (at line 15, column 39) for  n0
      % expected type  T_low[below(N2)]
  sigma_diff_eq_TCC6: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i)) AND
       n0 <= n AND n < N2 AND n < N1
       IMPLIES n0 >= 0 AND n0 < N2 OR (EXISTS (j: below(N2)): j <= n0);

  % Subtype TCC generated (at line 15, column 42) for  n
      % expected type  T_high[below(N2)]
  sigma_diff_eq_TCC7: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i)) AND
       n0 <= n AND n < N2 AND n < N1
       IMPLIES n >= 0 AND n < N2 OR (EXISTS (j: below(N2)): n <= j);

  % Assuming TCC generated (at line 41, column 5) for  sigma[below(N2)]
      % generated from assumption sigma.connected_domain
  sigma_diff_eq_TCC8: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i)) AND
       n0 <= n AND n < N2 AND n < N1
       IMPLIES
       (FORALL (x, y: below(N2)), (z: integer):
          x <= z AND z <= y IMPLIES z >= 0 AND z < N2);

  % Subtype TCC generated (at line 20, column 60) for  i
      % expected type  below(N1)
  sigma_diff_shift_TCC1: OBLIGATION
    FORALL (m, n, n0: nat):
      n < N1 AND n + m < N2 AND n0 <= n IMPLIES
       (FORALL (i): n0 <= i AND i <= n IMPLIES i < N1);

  % Subtype TCC generated (at line 20, column 68) for  i + m
      % expected type  below(N2)
  sigma_diff_shift_TCC2: OBLIGATION
    FORALL (m, n, n0: nat):
      n < N1 AND n + m < N2 AND n0 <= n IMPLIES
       (FORALL (i): n0 <= i AND i <= n IMPLIES i + m < N2);

  % Subtype TCC generated (at line 22, column 39) for  n0
      % expected type  T_low[below(N1)]
  sigma_diff_shift_TCC3: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], m, n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i + m)) AND
       n0 <= n AND n + m < N2 AND n < N1
       IMPLIES n0 >= 0 AND n0 < N1 OR (EXISTS (j: below(N1)): j <= n0);

  % Subtype TCC generated (at line 22, column 42) for  n
      % expected type  T_high[below(N1)]
  sigma_diff_shift_TCC4: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], m, n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i + m)) AND
       n0 <= n AND n + m < N2 AND n < N1
       IMPLIES n >= 0 AND n < N1 OR (EXISTS (j: below(N1)): n <= j);

  % Assuming TCC generated (at line 41, column 5) for  sigma[below(N1)]
      % generated from assumption sigma.connected_domain
  sigma_diff_shift_TCC5: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], m, n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i + m)) AND
       n0 <= n AND n + m < N2 AND n < N1
       IMPLIES
       (FORALL (x, y: below(N1)), (z: integer):
          x <= z AND z <= y IMPLIES z >= 0 AND z < N1);

  % Subtype TCC generated (at line 23, column 39) for  n0 + m
      % expected type  T_low[below(N2)]
  sigma_diff_shift_TCC6: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], m, n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i + m)) AND
       n0 <= n AND n + m < N2 AND n < N1
       IMPLIES
       n0 + m >= 0 AND n0 + m < N2 OR (EXISTS (j: below(N2)): j <= n0 + m);

  % Subtype TCC generated (at line 23, column 44) for  n + m
      % expected type  T_high[below(N2)]
  sigma_diff_shift_TCC7: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], m, n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i + m)) AND
       n0 <= n AND n + m < N2 AND n < N1
       IMPLIES
       n + m >= 0 AND n + m < N2 OR (EXISTS (j: below(N2)): n + m <= j);

  % Assuming TCC generated (at line 41, column 5) for  sigma[below(N2)]
      % generated from assumption sigma.connected_domain
  sigma_diff_shift_TCC8: OBLIGATION
    FORALL (f1: [below(N1) -> real], f2: [below(N2) -> real], m, n, n0: nat):
      (FORALL i: n0 <= i AND i <= n IMPLIES f1(i) = f2(i + m)) AND
       n0 <= n AND n + m < N2 AND n < N1
       IMPLIES
       (FORALL (x, y: below(N2)), (z: integer):
          x <= z AND z <= y IMPLIES z >= 0 AND z < N2);


body:
  sigma_int: THEORY
  %------------------------------------------------------------------------------
  % The summations theory introduces and defines properties of the sigma 
  % function that sums an arbitrary function F: [int -> real] over a range
  % from low to high
  %
  %  		          high
  %		          ----
  %  sigma(low, high, F) =  \     F(j)
  %		          /
  %		          ----
  %		         j = low
  %
  %------------------------------------------------------------------------------


  BEGIN

    IMPORTING sigma[int]

    int_is_T_high: JUDGEMENT int SUBTYPE_OF T_high
    int_is_T_low : JUDGEMENT int SUBTYPE_OF T_low

    low, high, i, j, m: VAR int
    F: VAR function[int -> real]


  % --------- Following Theorems Not Provable In Generic Framework -------

    sigma_shift    :  THEOREM sigma(low+j,high+j,F) = 
                                sigma(low,high, (LAMBDA (i: int): F(i+j)))


    sigma_split_ge : THEOREM low-1 <= m AND m <= high IMPLIES 
                              sigma(low, high, F) = 
                                       sigma(low, m, F) + sigma(m+1, high, F)


    sigma_first_ge : THEOREM high >= low IMPLIES
                             sigma(low, high, F) = F(low) + sigma(low+1, high, F)

    sigma_mid_ge  : THEOREM high >= i AND i >= low IMPLIES 
                            sigma(low, high, F) = sigma(low, i-1, F) + F(i) +
                                                  sigma(i+1, high, F) 

    sigma_last_ge  : THEOREM high >= low IMPLIES 
                            sigma(low, high, F) = sigma(low, high-1, F) + F(high)


  END sigma_int

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

  % Assuming TCC generated (at line 19, column 12) for  sigma[int]
      % generated from assumption sigma.connected_domain
  IMP_sigma_TCC1: OBLIGATION (FORALL (x, y: int), (z: integer): TRUE);


body:
  sigma_posnat: THEORY
  %------------------------------------------------------------------------------
  % The summations theory introduces and defines properties of the sigma 
  % function that sums an arbitrary function F: [T -> real] over a range
  % from low to high
  %
  %  		          high
  %		          ----
  %  sigma(low, high, F) =  \     F(j)
  %		          /
  %		          ----
  %		         j = low
  %
  %------------------------------------------------------------------------------


  BEGIN

    IMPORTING sigma[posnat]

    int_is_T_high: JUDGEMENT int SUBTYPE_OF T_high
    posnat_is_T_low : JUDGEMENT posnat SUBTYPE_OF T_low

    low, n, m: VAR posnat
    high: VAR int
    F: VAR function[posnat -> real]


  % --------- Following Theorems Not Provable In Generic Framework -------

    sigma_shift:  THEOREM sigma(low+m,high+m,F) = 
                                sigma(low,high, (LAMBDA (n: posnat): F(n+m)))

    sigma_shift_neg:  THEOREM low - m > 0 IMPLIES 
                           sigma(low-m,high-m,F) = 
                               sigma(low,high, (LAMBDA n: IF n-m <= 0 THEN 0 
                                                          ELSE F(n-m) 
                                                          ENDIF))

    sigma_split_ge : THEOREM low-1 <= m AND m <= high IMPLIES 
                              sigma(low, high, F) = 
                                       sigma(low, m, F) + sigma(m+1, high, F)


  END sigma_posnat

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

  % Assuming TCC generated (at line 19, column 12) for  sigma[posnat]
      % generated from assumption sigma.connected_domain
  IMP_sigma_TCC1: OBLIGATION
    (FORALL (x, y: posnat), (z: integer):
       x <= z AND z <= y IMPLIES z >= 0 AND z > 0);

  % Judgement subtype TCC generated (at line 21, column 27) for  x
      % expected type  T_high[posnat]
  int_is_T_high: OBLIGATION
    FORALL (x: int): x >= 0 AND x > 0 OR (EXISTS (j: posnat): x <= j);

  % Judgement subtype TCC generated (at line 22, column 30) for  x
      % expected type  T_low[posnat]
  posnat_is_T_low: OBLIGATION
    FORALL (x: posnat): x >= 0 AND x > 0 OR (EXISTS (j: posnat): j <= x);

  % Subtype TCC generated (at line 31, column 36) for  high + m
      % expected type  T_high[posnat]
  sigma_shift_TCC1: OBLIGATION
    FORALL (high: int, m: posnat):
      high + m >= 0 AND high + m > 0 OR (EXISTS (j: posnat): high + m <= j);

  % Subtype TCC generated (at line 35, column 31) for  low - m
      % expected type  T_low[posnat]
  sigma_shift_neg_TCC1: OBLIGATION
    FORALL (low, m: posnat):
      low - m > 0 IMPLIES
       low - m >= 0 AND low - m > 0 OR (EXISTS (j: posnat): j <= low - m);

  % Subtype TCC generated (at line 35, column 37) for  high - m
      % expected type  T_high[posnat]
  sigma_shift_neg_TCC2: OBLIGATION
    FORALL (high: int, low, m: posnat):
      low - m > 0 IMPLIES
       high - m >= 0 AND high - m > 0 OR (EXISTS (j: posnat): high - m <= j);

  % Subtype TCC generated (at line 37, column 63) for  n - m
      % expected type  posnat
  sigma_shift_neg_TCC3: OBLIGATION
    FORALL (low, m: posnat):
      low - m > 0 IMPLIES
       (FORALL (n): NOT n - m <= 0 IMPLIES n - m >= 0 AND n - m > 0);

  % Subtype TCC generated (at line 42, column 48) for  m
      % expected type  T_high[posnat]
  sigma_split_ge_TCC1: OBLIGATION
    FORALL (high: int, low, m: posnat):
      m <= high AND low - 1 <= m IMPLIES
       m >= 0 AND m > 0 OR (EXISTS (j: posnat): m <= j);


body:
  top_sigma: THEORY
  %------------------------------------------------------------------------------
  % The sigma theory introduces and defines properties of the sigma 
  % function that sum an arbitrary function F: [T -> real] over a range
  % from low to high
  %
  %                             high
  %                             ----
  %      sigma(low, high, F) =  \     F(j)
  %                             /
  %                             ----
  %                            j = low
  %
  % and alternate (tail recursion) form
  %
  %                                       high
  %                                       ----
  %      sum_it(low, high, F, a )=  a  +  \     F(j)
  %                                       /
  %                                       ----
  %                                       j = low
  %
  %
  %
  %      by Ricky W. Butler      NASA Langley
  %         Cesar Munoz          Langley ICASE
  %         Paul Miner           NASA Langley
  %
   
  %      Version 1.0    original version 7/12/96
  %      Version 2.0    4/2/01               
  %
  %
  %  NOTE:  T can be any subtype of the integers that is connected.  For 
  %         example "subrange(-12,7)", nat, or posnat.
  %
  %  NOTE:  Summations over functions with an arbirary number of arguments
  %         is accomodated by the following technique:
  %
  %              G(x,y,z: real,n: nat): real
  %
  %              IMPORTING sigma[nat]    % or sigma_nat
  %
  %              sum = sigma(low,high, (LAMBDA (n:nat): G(x,y,z,n))
  %
  %  NOTE: The old library "sigma_real" is now subsumed by sigma_nat.
  %
  %  NOTE: "sigma_real.sigma_mult"  is named "sigma_scal" in "sigma"
  %------------------------------------------------------------------------------

  BEGIN
   
    IMPORTING sigma,           % generic theory
              sigma_nat,       % sigma over functions [nat --> real]
              sigma_posnat,    % sigma over functions [posnat --> real]
              sigma_int,       % sigma over functions [int --> real]
              sigma_upto,      % sigma over functions [upto[N] --> real]
              sigma_below,     % sigma over functions [below[N] --> real]
              sigma_below_sub, % equality of sigmas with different domains


              sigma_fseq_def,  % summation over finite sequences
              sigma_fseq       % Bug prevents typecheck


  %  The more specific theories have stronger theorems than the generic one


  %% -------  Following Obsolete

  %             old_sigma_below,     
  %             old_sigma_below_sub,
  %             old_sigma_int,
  %             old_sigma_nat,
  %             old_sigma_posnat,
  %             old_sigma,
  %             old_sigma_real,
  %             old_sigma_upto

                           
  END top_sigma


body:
  top: THEORY
  %----------------------------------------------------------------------------
  %
  %  Orders Library
  %  --------------
  %
  %  Version 1.0    Extracted From sets_aux library on 4/21/05
  %  Version 1.1    Added finite_below, similarity, and similarity_props
  % 
  %  Authors:
  %      Bruno Dutertre <bruno@sdl.sri.com> SRI International
  %      Jerry James    <jamesj@acm.org>    University of Kansas
  %      Alfons Geser   <geser@nianet.org>  National Institute For Aerospace
  %----------------------------------------------------------------------------
  BEGIN

   %---- Alfons Geser theories on order
   IMPORTING
    bounded_integers,         % nonempty, above/below bounded => greatest/least
    bounded_orders,           % definitions of lub, glb, (complete) lattice
    bounded_sets,             % judgements about boundedness properties of sets
    closure_ops,              % reflexive, symmetric, transitive, etc. closure
    complementary_lattices,   % lattices with a "complement" function
    complementary_orders,     % ordered sets with a "complement" function
    complete_lattices,        % every set is tightly bounded
    complete_lower_semilattices, % every set is greatest bounded below
    complete_upper_semilattices, % every set is least bounded above
    finite_orders,            % properties of an order on a finite type
    finite_pointwise_orders,  % orders on functions with a finite domain
    finite_total_orders,      % total orders on a finite type
    fixed_points,             % fixed points characterized by prefixed points
    integer_enumerations,     % infinite below bounded set of ints => enumerable
    lattices,                 % operations that preserve tight-boundedness
    lower_semilattices,       % definition of binary glb function
    minmax_orders,            % minimal, maximal, least, greatest elements
    monotone_sequences,       % infinite ascending/descending sequences
    new_mucalculus_prop,      % a simulation of fixedpoints@mucalculus_prop
    non_empty_bounded_sets,   % nonempty sets of reals bounded above/below
    pointwise_orders,         % lifting an order to functions
    sets_complete_lattices,   % sets ordered by "subset?" form a complete lattice
    total_lattices,           % a lattice defined by a total order
    upper_semilattices,       % definition of binary lub function
    well_foundedness          % well-foundedness = no infinite descending seq.

   %---- Jerry James theories on order
   IMPORTING
    bounded_nats,             % all nonempty sets of nats have a least element
    chain,                    % totally ordered subsets of a poset
    chain_chain,              % chains of chains in inclusion order
    converse_zorn,            % lower bound on all chains => min. element exists
    finite_below,             % finite set = monotonic bijection with below[N]
    isomorphism,              % isomorphisms between ordered sets
    isomorphism_equivalence,  % automorphisms and equivalence classes thereof
    isomorphism_symmetric,    % the isomorphic? relation is symmetric
    isomorphism_transitive,   % the isomorphic? relation is transitive
    kuratowski,               % there exists a maximal chain in any set
    monotone_functions,       % (non)in/decreasing functions on ordered sets
    numbers_infinite,         % the nats, ints, rats, and reals are infinite
    order_strength,           % strengthenings and weakenings of orders
    ordered_int,              % ordered subsets of the integers
    ordered_nat,              % ordered subsets of the natural numbers
    ordered_subset,           % prefix, suffix, upto, below, upfrom, etc.
    range,                    % open and closed ranges of numbers
    range_real,               % the range theory, tailored to ranges of reals
    set_antisymmetric,        % injective maps both ways => bijection exists
    set_dichotomous,          % injective map exists between any 2 sets
    similarity,               % similar ordered sets: order-preserving bijection
    similarity_props,         % least, greatest, and all finite sets are similar
    subset_chain,             % chains of sets in inclusion order
    well_nat,                 % well-ordered relations on sets of nats
    well_ordered_finite,      % linear order + finite below sets = well-ordered
    well_ordered_props,       % some properties of well-ordered sets
    well_ordered_traversal,   % first, last, next, & prev for well-ordered sets
    well_ordering,            % every set has a well-ordering relation
    zorn                      % upper bound on all chains => max. element exists

   %---- Alfons Geser prelude-style theories
   IMPORTING
    booleans_are_finite,      % the booleans are a finite type
    finite_types,             % if T is finite, then every set of T is finite
    function_image_extra,     % Two more rewrite rules for function_image
    indexed_sets_extra,       % IUnion and IIntersection are monotone
    infinite_pigeonhole,      % [infinite_domain -> finite_range] enumerates
                              % some range element infinitely often
    relation_iterate,         % R o R o ... o R  n times.
    relations_extra,          % rewrite rules and judgements for binary relations
    skolemization,            % how to eliminate inner quantifiers

   %--- New Content From David Lester, Manchester

    directed_orders,        % New theories for orders library
    bounded_order_props,    % Properties of bounded orders
    directed_order_props,   % Properties of directed orders
    partial_order_props,    % Properties of partial orders
    lift_props,             % Extras for the lift datatype
    lifted_orders,          % Induced properties of lifted orders
    partial_order_lift,
    sum_orders,             % Induced properties of union orders
    product_orders          % Induced properties of product orders
    
    %------- Bruno Dutertre
    IMPORTING
     mucalculus_prop           % originally in library fixedpoints
   
  END top


body:
  mucalculus_prop [ T:TYPE ] : THEORY
  %-------------------------------------------------------------------
  %  Fixed points of monotonic functions of type [set[T] -> set[T]]
  %  (predicate transformers)
  %
  %  Shows that operators mu and nu defined in theory mucalculus 
  %  of the prelude defines the least and greatest fixpoints of 
  %  a monotonic function
  %
  %  Defines dual(H) = complement o H o complement
  %
  %  Shows that mu o dual = complement o nu and 
  %             nu o dual = complement o mu
  %-------------------------------------------------------------------

    BEGIN

    F: VAR (monotonic?[T])

    p, q: VAR pred[T]

    A: VAR set[pred[T]]


    % Auxiliary functions defined in the prelude (theory mucalculus):
    % - relation <= is the same as the subset? relation
    % - glb(A) = { x:T | EXISTS (p: (A)): p(x) }
    % - lub(A) = { x:T | FORALL (p: (A)): p(x) }

    antisymmetry: LEMMA p <= q AND q <= p IMPLIES p = q

    reflexivity: LEMMA p <= p


    %--- glb(A) is the greatest lower bound of A

    glb_lower_bound: LEMMA FORALL (q: (A)): glb(A) <= q

    glb_greatest_lower_bound: LEMMA
         p <= glb(A) IFF FORALL (q: (A)): p <= q


    %--- lub(A) is the least upper bound of A 

    lub_upper_bound: LEMMA FORALL (q: (A)): q <= lub(A)

    lub_least_upper_bound: LEMMA
         lub(A) <= p IFF FORALL (q: (A)): q <= p

    

    %--- properties of mu operator

    closure_mu: PROPOSITION F(mu(F)) <= mu(F)

    smallest_closed: PROPOSITION F(p) <= p IMPLIES mu(F) <= p

    fixpoint_mu1: PROPOSITION F(mu(F)) = mu(F)

    fixpoint_mu2: PROPOSITION fixpoint?(F)(mu(F))

    least_fixpoint1: PROPOSITION F(p) = p IMPLIES mu(F) <= p

    least_fixpoint2: PROPOSITION fixpoint?(F)(p) IMPLIES mu(F) <= p

    mu_lfp: JUDGEMENT mu(F) HAS_TYPE (lfp?(F))



    %--- properties of nu operator

    closure_nu: PROPOSITION nu(F) <= F(nu(F))

    largest_closed: PROPOSITION p <= F(p) IMPLIES p <= nu(F)

    fixpoint_nu1: PROPOSITION F(nu(F)) = nu(F)

    fixpoint_nu2: PROPOSITION fixpoint?(F)(nu(F))

    greatest_fixpoint1: PROPOSITION F(p) = p IMPLIES p <= nu(F)

    greatest_fixpoint2: PROPOSITION fixpoint?(F)(p) IMPLIES p <= nu(F)

    nu_gfp: JUDGEMENT nu(F) HAS_TYPE (gfp?(F))



    %--- dual of a predicate transformer

    H: VAR [pred[T] -> pred[T]]

    dual(H): [pred[T] -> pred[T]] = complement o H o complement


    dual_dual : LEMMA dual(dual(H)) = H


    dual_inclusion1 : LEMMA
  	H(complement(p)) <= complement(p) IFF p <= dual(H)(p)

    dual_inclusion2 : LEMMA
  	complement(p) <= H(complement(p)) IFF dual(H)(p) <= p

    dual_inclusion3 : LEMMA
  	H(p) <= p IFF complement(p) <= dual(H)(complement(p))

    dual_inclusion4 : LEMMA
  	p <= H(p) IFF dual(H)(complement(p)) <= complement(p)


    %--- fixed points and dual

    monotonic_dual_monotonic: JUDGEMENT dual(F) HAS_TYPE (monotonic?[T])

    least_fixpoint_dual: PROPOSITION mu(dual(F)) = complement(nu(F))

    greatest_fixpoint_dual: PROPOSITION nu(dual(F)) = complement(mu(F))

    END mucalculus_prop

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

  % Judgement subtype TCC generated (at line 66, column 20) for  mu(F)
      % expected type  (lfp?(F))
  mu_lfp: OBLIGATION FORALL (F): lfp?[T](F)(mu[T](F));

  % Judgement subtype TCC generated (at line 84, column 20) for  nu(F)
      % expected type  (gfp?(F))
  nu_gfp: OBLIGATION FORALL (F): gfp?[T](F)(nu[T](F));

  % Judgement subtype TCC generated (at line 113, column 38) for  dual(F)
      % expected type  (monotonic?[T])
  monotonic_dual_monotonic: OBLIGATION FORALL (F): monotonic?[T](dual(F));


body:
  %-------------------------------------------------------------------------
  %
  %  Definitions of asymmetric? and order?, along with judgements for the
  %  properties that binary relations may have.  Alfons Geser wrote the
  %  definition of asymmetric?, the judgements dealing with asymmetric?,
  %  and dichotomous_is_trichotomous in Oct. 2004.  Jerry James wrote the
  %  rest at various times.
  %
  %  For PVS version 3.2.  February 23, 2005
  %  ---------------------------------------------------------------------
  %      Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  %      Author: Jerry James (jamesj@acm.org), University of Kansas
  %
  %  EXPORTS
  %  -------
  %  prelude: orders[T], relations[T]
  %  orders: relations_extra[T]
  %
  %-------------------------------------------------------------------------
  relations_extra[T: TYPE]: THEORY

  BEGIN

    IMPORTING relations[T], orders[T]

    x, y, z: VAR T
    R: VAR pred[[T, T]]
    p: VAR pred[T]


    % ==========================================================================
    % Asymmetry
    % ==========================================================================

    asymmetric?(R): bool = FORALL x, y: NOT R(x, y) OR NOT R(y, x)

    strict_order_is_asymmetric: JUDGEMENT
      (strict_order?) SUBTYPE_OF (asymmetric?)

    asymmetric_is_antisymmetric: JUDGEMENT
      (asymmetric?) SUBTYPE_OF (antisymmetric?)

    asymmetric_is_irreflexive: JUDGEMENT
      (asymmetric?) SUBTYPE_OF (irreflexive?)


    % ==========================================================================
    % Dichotomous-trichotomous relationship
    % ==========================================================================

    dichotomous_is_trichotomous: JUDGEMENT
      (dichotomous?) SUBTYPE_OF (trichotomous?)


    % ==========================================================================
    % Orders: a generalization of partial and strict orders
    % ==========================================================================

    order?(R): bool = transitive?(R) AND antisymmetric?(R)

    order_is_transitive: JUDGEMENT (order?) SUBTYPE_OF (transitive?)

    order_is_antisymmetric: JUDGEMENT (order?) SUBTYPE_OF (antisymmetric?)

    partial_order_is_order: JUDGEMENT (partial_order?) SUBTYPE_OF (order?)

    strict_order_is_order: JUDGEMENT (strict_order?) SUBTYPE_OF (order?)


    % ==========================================================================
    % Linear orders: a generalization of total and strict_total orders
    % ==========================================================================

    linear_order?(R): bool = order?(R) AND trichotomous?(R)

    total_order_is_linear: JUDGEMENT (total_order?) SUBTYPE_OF (linear_order?)

    strict_total_order_is_linear: JUDGEMENT
      (strict_total_order?) SUBTYPE_OF (linear_order?)


    % ==========================================================================
    % Convenience lemmas
    % ==========================================================================

    reflexive: LEMMA FORALL (R: (reflexive?)): FORALL x: R(x, x)

    irreflexive: LEMMA FORALL (R: (irreflexive?)): FORALL x: NOT R(x, x)

    symmetric: LEMMA FORALL (R: (symmetric?)): FORALL x, y: R(x, y) => R(y, x)

    antisymmetric: LEMMA
      FORALL (R: (antisymmetric?)): FORALL x, y: R(x, y) & R(y, x) => x = y

    asymmetric: LEMMA
      FORALL (R: (asymmetric?)): FORALL x, y: NOT R(x, y) OR NOT R(y, x)

  % connected? is the same as trichotomous?
  %  connected: LEMMA FORALL (R: (connected?)): x = y OR R(x, y) OR R(y, x)

    transitive: LEMMA
      FORALL (R: (transitive?)): FORALL x, y, z: R(x, y) & R(y, z) => R(x, z)

    dichotomous: LEMMA
      FORALL (R: (dichotomous?)): FORALL x, y: R(x, y) OR R(y, x)

    trichotomous: LEMMA
      FORALL (R: (trichotomous?)): FORALL x, y: R(x, y) OR R(y, x) OR x = y

    well_founded: LEMMA
      FORALL (R: (well_founded?)):
        FORALL p:
          (EXISTS y: p(y)) IMPLIES
           (EXISTS (y: (p)): FORALL (x: (p)): NOT R(x, y))

  END relations_extra

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

  % Judgement subtype TCC generated (at line 38, column 4) for  x
      % expected type  (asymmetric?)
  strict_order_is_asymmetric: OBLIGATION
    FORALL (x: (strict_order?)): asymmetric?(x);

  % Judgement subtype TCC generated (at line 41, column 4) for  x
      % expected type  (antisymmetric?)
  asymmetric_is_antisymmetric: OBLIGATION
    FORALL (x: (asymmetric?)): antisymmetric?[T](x);

  % Judgement subtype TCC generated (at line 44, column 4) for  x
      % expected type  (irreflexive?)
  asymmetric_is_irreflexive: OBLIGATION
    FORALL (x: (asymmetric?)): irreflexive?[T](x);

  % Judgement subtype TCC generated (at line 52, column 4) for  x
      % expected type  (trichotomous?)
  dichotomous_is_trichotomous: OBLIGATION
    FORALL (x: (dichotomous?)): trichotomous?[T](x);

  % Judgement subtype TCC generated (at line 61, column 33) for  x
      % expected type  (transitive?)
  order_is_transitive: OBLIGATION FORALL (x: (order?)): transitive?[T](x);

  % Judgement subtype TCC generated (at line 63, column 36) for  x
      % expected type  (antisymmetric?)
  order_is_antisymmetric: OBLIGATION
    FORALL (x: (order?)): antisymmetric?[T](x);

  % Judgement subtype TCC generated (at line 65, column 36) for  x
      % expected type  (order?)
  partial_order_is_order: OBLIGATION FORALL (x: (partial_order?)): order?(x);

  % Judgement subtype TCC generated (at line 67, column 35) for  x
      % expected type  (order?)
  strict_order_is_order: OBLIGATION FORALL (x: (strict_order?)): order?(x);

  % Judgement subtype TCC generated (at line 76, column 35) for  x
      % expected type  (linear_order?)
  total_order_is_linear: OBLIGATION
    FORALL (x: (total_order?)): linear_order?(x);

  % Judgement subtype TCC generated (at line 79, column 4) for  x
      % expected type  (linear_order?)
  strict_total_order_is_linear: OBLIGATION
    FORALL (x: (strict_total_order?)): linear_order?(x);


body:
  %  Upper and lower bounds on subsets; lub, glb;
  % (complete) upper and lower semilattices; (complete) lattices
  %
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Oct 2004 / Jan 2005
  %
  % lub_singleton, least_upper_bound_singleton, glb_singleton, and
  % greates_lower_bound_singleton added 23 Feb 2005 by Jerry James
  % <jamesj@acm.org>, University of Kansas.

  bounded_orders[T: TYPE]: THEORY

  BEGIN

    IMPORTING sets[T], finite_sets[T], relations_extra[T]

    t, u, r: VAR T
    S, R: VAR set
    NF: VAR non_empty_finite_set
    <=: VAR pred[[T,T]]

    % ==========================================================================
    % Upper bounds
    % ==========================================================================

    upper_bound?(t, S, <=): bool = FORALL (r: (S)): r <= t
    upper_bound?(S, <=)(t): MACRO bool = upper_bound?(t, S, <=)
    bounded_above?(S, <=): bool = EXISTS t: upper_bound?(t, S, <=)
    bounded_above?(<=)(S): MACRO bool = bounded_above?(S, <=)

    least_upper_bound?(t, S, <=): bool =
      upper_bound?(t, S, <=) AND
      (FORALL r: upper_bound?(r, S, <=) => t <= r)
    least_upper_bound?(S, <=)(t): MACRO bool = least_upper_bound?(t, S, <=)
    least_bounded_above?(S, <=): bool = EXISTS t: least_upper_bound?(t, S, <=)
    least_bounded_above?(<=)(S): MACRO bool = least_bounded_above?(S, <=)

    complete_upper_semilattice?(<=): bool =
      partial_order?(<=) AND FORALL S: least_bounded_above?(S, <=)
    upper_semilattice?(<=): bool =
      partial_order?(<=) AND FORALL NF: least_bounded_above?(NF, <=)

    lub(<=)(S: (least_bounded_above?(<=))): (least_upper_bound?(S, <=))

    % Properties
    unique_least_upper_bound: THEOREM
      FORALL (<=: (antisymmetric?[T]), t, r: (least_upper_bound?(S, <=))): t = r

    subset_upper_bound: LEMMA
      (subset?(S, R) AND upper_bound?(t, R, <=)) => upper_bound?(t, S, <=)

    subset_least_upper_bound: COROLLARY
      subset?(S, R) AND
      least_upper_bound?(t, R, <=) AND
      least_upper_bound?(r, S, <=) IMPLIES
        r <= t

    lub_def: LEMMA
      FORALL (<=: (antisymmetric?[T]), S: (least_bounded_above?(<=))):
        (lub(<=)(S) = t IFF least_upper_bound?(S, <=)(t))

    lub_eq: LEMMA
      FORALL (<=: (antisymmetric?[T]), S: (least_bounded_above?(<=)),
              t: (least_upper_bound?(S, <=))):
        lub(<=)(S) = t

    lub_ge: LEMMA
      FORALL (S: (least_bounded_above?(<=)), t: (S)):
        t <= lub(<=)(S)

    lub_le: LEMMA
      FORALL (<=: (transitive?[T]), S: (least_bounded_above?(<=))):
        (lub(<=)(S) <= t IFF upper_bound?(S, <=)(t))

    all_least_bounded: LEMMA
      FORALL (<=: (complete_upper_semilattice?)):
        least_bounded_above?(S, <=)

    all_finite_least_bounded: LEMMA
      FORALL (<=: (upper_semilattice?)):
        least_bounded_above?(NF, <=)

    complete_upper_semilattice_upper: JUDGEMENT
      (complete_upper_semilattice?) SUBTYPE_OF (upper_semilattice?)

    upper_semilattice_is_partial_order: JUDGEMENT
      (upper_semilattice?) SUBTYPE_OF (partial_order?)


    % ==========================================================================
    % Lower bounds
    % ==========================================================================

    lower_bound?(t, S, <=): bool = FORALL (r: (S)): t <= r
    lower_bound?(S, <=)(t): MACRO bool = lower_bound?(t, S, <=)
    bounded_below?(S, <=): bool = EXISTS t: lower_bound?(t, S, <=)
    bounded_below?(<=)(S): MACRO bool = bounded_below?(S, <=)

    greatest_lower_bound?(t, S, <=): bool =
      lower_bound?(t, S, <=) AND
      (FORALL r: lower_bound?(r, S, <=) => r <= t)
    greatest_lower_bound?(S, <=)(t): MACRO bool = greatest_lower_bound?(t, S, <=)
    greatest_bounded_below?(S, <=): bool =
      EXISTS t: greatest_lower_bound?(t, S, <=)
    greatest_bounded_below?(<=)(S): MACRO bool = greatest_bounded_below?(S, <=)

    complete_lower_semilattice?(<=): bool = 
      partial_order?(<=) AND FORALL S: greatest_bounded_below?(S, <=)
    lower_semilattice?(<=): bool = 
      partial_order?(<=) AND FORALL NF: greatest_bounded_below?(NF, <=)

    glb(<=)(S: (greatest_bounded_below?(<=))): (greatest_lower_bound?(S, <=))

    % Properties
    unique_greatest_lower_bound: THEOREM
      FORALL (<=: (antisymmetric?[T]), t, r: (greatest_lower_bound?(S, <=))):
        t = r

    subset_lower_bound: LEMMA
      FORALL S, R, t:
        (subset?(S, R) AND lower_bound?(t, R, <=)) => lower_bound?(t, S, <=)

    subset_greatest_lower_bound: COROLLARY
      subset?(S, R) AND
      greatest_lower_bound?(t, S, <=) AND
      greatest_lower_bound?(r, R, <=) IMPLIES
        r <= t

    glb_def: LEMMA
      FORALL (<=: (antisymmetric?[T]), S: (greatest_bounded_below?(<=))):
        (glb(<=)(S) = t IFF greatest_lower_bound?(S, <=)(t))

    glb_eq: LEMMA
      FORALL (<=: (antisymmetric?[T]), S: (greatest_bounded_below?(<=)),
              t: (greatest_lower_bound?(S, <=))):
        glb(<=)(S) = t

    glb_le: LEMMA
      FORALL (S: (greatest_bounded_below?(<=)), t: (S)):
        glb(<=)(S) <= t

    glb_ge: LEMMA
      FORALL (<=: (transitive?[T]), S: (greatest_bounded_below?(<=))):
        (t <= glb(<=)(S) IFF lower_bound?(S, <=)(t))

    all_greatest_bounded: LEMMA
      FORALL (<=: (complete_lower_semilattice?)):
        greatest_bounded_below?(S, <=)

    all_finite_greatest_bounded: LEMMA
      FORALL (<=: (lower_semilattice?)):
        greatest_bounded_below?(NF, <=)

    complete_lower_semilattice_lower: JUDGEMENT
      (complete_lower_semilattice?) SUBTYPE_OF (lower_semilattice?)

    lower_semilattice_is_partial_order: JUDGEMENT
      (lower_semilattice?) SUBTYPE_OF (partial_order?)


    % ==========================================================================
    % Upper and lower bounds
    % ==========================================================================

    bounded?(S, <=): bool = bounded_above?(S, <=) AND bounded_below?(S, <=)
    bounded?(<=)(S): MACRO bool = bounded?(S, <=)
    tightly_bounded?(S, <=): bool =
      least_bounded_above?(S, <=) AND greatest_bounded_below?(S, <=)
    tightly_bounded?(<=)(S): MACRO bool = tightly_bounded?(S, <=)
    complete_lattice?(<=): bool =
       complete_upper_semilattice?(<=) AND complete_lower_semilattice?(<=)
    lattice?(<=): bool =
       upper_semilattice?(<=) AND lower_semilattice?(<=)

    bounded_is_bounded_above: JUDGEMENT (bounded?) SUBTYPE_OF (bounded_above?)
   
    bounded_is_bounded_below: JUDGEMENT (bounded?) SUBTYPE_OF (bounded_below?)
   
    tightly_bounded_above: JUDGEMENT
      (tightly_bounded?) SUBTYPE_OF (least_bounded_above?)
   
    tightly_bounded_below: JUDGEMENT
      (tightly_bounded?) SUBTYPE_OF (greatest_bounded_below?)
   
    complete_lattice_upper: JUDGEMENT
      (complete_lattice?) SUBTYPE_OF (complete_upper_semilattice?)

    complete_lattice_lower: JUDGEMENT
      (complete_lattice?) SUBTYPE_OF (complete_lower_semilattice?)

    lattice_upper: JUDGEMENT
      (lattice?) SUBTYPE_OF (upper_semilattice?)

    lattice_lower: JUDGEMENT
      (lattice?) SUBTYPE_OF (lower_semilattice?)

    complete_lattice_is_lattice: JUDGEMENT
      (complete_lattice?) SUBTYPE_OF (lattice?)


    % bounds of singleton sets

    upper_bound_singleton: LEMMA
      upper_bound?[T](t, singleton(u), <=) IFF u <= t

    least_upper_bound_singleton: LEMMA
      FORALL (<=: (reflexive?)): least_upper_bound?[T](t, singleton(t), <=)

    lub_singleton: LEMMA
      FORALL (<=: (partial_order?)): lub(<=)(singleton(u)) = u

    lower_bound_singleton: LEMMA
      lower_bound?[T](t, singleton(u), <=) IFF t <= u

    greatest_lower_bound_singleton: LEMMA
      FORALL (<=: (reflexive?)): greatest_lower_bound?[T](t, singleton(t), <=)

    glb_singleton: LEMMA
      FORALL (<=: (partial_order?)): glb(<=)(singleton(u)) = u


    % bounds of the empty set
    upper_bound_emptyset: LEMMA
      upper_bound?(t, emptyset, <=)

    lower_bound_emptyset: LEMMA
      lower_bound?(t, emptyset, <=)

    lub_emptyset_is_glb_fullset: THEOREM
      least_upper_bound?(t, emptyset, <=) IFF
      greatest_lower_bound?(t, fullset, <=)

    glb_emptyset_is_lub_fullset: THEOREM
      greatest_lower_bound?(t, emptyset, <=) IFF
      least_upper_bound?(t, fullset, <=)

    least_bounded_above_emptyset: COROLLARY
      least_bounded_above?(emptyset, <=) IFF
      greatest_bounded_below?(fullset, <=)

    greatest_bounded_below_emptyset: COROLLARY
      greatest_bounded_below?(emptyset, <=) IFF
      least_bounded_above?(fullset, <=)


  % --------- New content from David Lester

    nonempty_least_bounded_above?(<=)(S):bool
       = nonempty?(S) AND least_bounded_above?(<=)(S)

    nonempty_greatest_bounded_below?(<=)(S):bool
       = nonempty?(S) AND greatest_bounded_below?(<=)(S)

    le_lub: LEMMA FORALL (<=:(partial_order?),S,R:(least_bounded_above?(<=))):
        (FORALL (s:(S)): EXISTS (r:(R)): s <= r) IMPLIES lub(<=)(S) <= lub(<=)(R)

    eq_lub: LEMMA FORALL (<=:(partial_order?),S,R:(least_bounded_above?(<=))):
        (FORALL (s:(S)): EXISTS (r:(R)): s <= r) AND
        (FORALL (r:(R)): EXISTS (s:(S)): r <= s) IMPLIES lub(<=)(S) = lub(<=)(R)

    lub_add: LEMMA FORALL (<=:(partial_order?),S:(least_bounded_above?(<=))):
        lub(<=)(add(lub(<=)(S),S)) = lub(<=)(S)

    le_glb: LEMMA FORALL (<=:(partial_order?),S,R:(greatest_bounded_below?(<=))):
        (FORALL (r:(R)): EXISTS (s:(S)): s <= r) IMPLIES glb(<=)(S) <= glb(<=)(R)

    eq_glb: LEMMA FORALL (<=:(partial_order?),S,R:(greatest_bounded_below?(<=))):
        (FORALL (s:(S)): EXISTS (r:(R)): r <= s) AND
        (FORALL (r:(R)): EXISTS (s:(S)): s <= r) IMPLIES glb(<=)(S) = glb(<=)(R)

    glb_add: LEMMA FORALL (<=:(partial_order?),S:(greatest_bounded_below?(<=))):
        glb(<=)(add(glb(<=)(S),S)) = glb(<=)(S)




  END bounded_orders

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

  % Existence TCC generated (at line 43, column 2) for
      % lub(<=)(S: (LAMBDA (S): least_bounded_above?(S, <=))):
      %       (LAMBDA (t): least_upper_bound?(t, S, <=))
  lub_TCC1: OBLIGATION
    EXISTS (x:
              [<=: pred[[T, T]] ->
                 [S: (LAMBDA (S): least_bounded_above?(S, <=)) ->
                    (LAMBDA (t): least_upper_bound?(t, S, <=))]]):
      TRUE;

  % Judgement subtype TCC generated (at line 84, column 4) for  x
      % expected type  (upper_semilattice?)
  complete_upper_semilattice_upper: OBLIGATION
    FORALL (x: (complete_upper_semilattice?)): upper_semilattice?(x);

  % Judgement subtype TCC generated (at line 87, column 4) for  x
      % expected type  (partial_order?)
  upper_semilattice_is_partial_order: OBLIGATION
    FORALL (x: (upper_semilattice?)): partial_order?[T](x);

  % Existence TCC generated (at line 112, column 2) for
      % glb(<=)(S: (LAMBDA (S): greatest_bounded_below?(S, <=))):
      %       (LAMBDA (t): greatest_lower_bound?(t, S, <=))
  glb_TCC1: OBLIGATION
    EXISTS (x:
              [<=: pred[[T, T]] ->
                 [S: (LAMBDA (S): greatest_bounded_below?(S, <=)) ->
                    (LAMBDA (t): greatest_lower_bound?(t, S, <=))]]):
      TRUE;

  % Judgement subtype TCC generated (at line 155, column 4) for  x
      % expected type  (lower_semilattice?)
  complete_lower_semilattice_lower: OBLIGATION
    FORALL (x: (complete_lower_semilattice?)): lower_semilattice?(x);

  % Judgement subtype TCC generated (at line 158, column 4) for  x
      % expected type  (partial_order?)
  lower_semilattice_is_partial_order: OBLIGATION
    FORALL (x: (lower_semilattice?)): partial_order?[T](x);

  % Judgement subtype TCC generated (at line 175, column 38) for  x
      % expected type  (bounded_above?)
  bounded_is_bounded_above: OBLIGATION
    FORALL (x: (bounded?)): bounded_above?(x);

  % Judgement subtype TCC generated (at line 177, column 38) for  x
      % expected type  (bounded_below?)
  bounded_is_bounded_below: OBLIGATION
    FORALL (x: (bounded?)): bounded_below?(x);

  % Judgement subtype TCC generated (at line 180, column 4) for  x
      % expected type  (least_bounded_above?)
  tightly_bounded_above: OBLIGATION
    FORALL (x: (tightly_bounded?)): least_bounded_above?(x);

  % Judgement subtype TCC generated (at line 183, column 4) for  x
      % expected type  (greatest_bounded_below?)
  tightly_bounded_below: OBLIGATION
    FORALL (x: (tightly_bounded?)): greatest_bounded_below?(x);

  % Judgement subtype TCC generated (at line 186, column 4) for  x
      % expected type  (complete_upper_semilattice?)
  complete_lattice_upper: OBLIGATION
    FORALL (x: (complete_lattice?)): complete_upper_semilattice?(x);

  % Judgement subtype TCC generated (at line 189, column 4) for  x
      % expected type  (complete_lower_semilattice?)
  complete_lattice_lower: OBLIGATION
    FORALL (x: (complete_lattice?)): complete_lower_semilattice?(x);

  % Judgement subtype TCC generated (at line 192, column 4) for  x
      % expected type  (upper_semilattice?)
  lattice_upper: OBLIGATION FORALL (x: (lattice?)): upper_semilattice?(x);

  % Judgement subtype TCC generated (at line 195, column 4) for  x
      % expected type  (lower_semilattice?)
  lattice_lower: OBLIGATION FORALL (x: (lattice?)): lower_semilattice?(x);

  % Judgement subtype TCC generated (at line 198, column 4) for  x
      % expected type  (lattice?)
  complete_lattice_is_lattice: OBLIGATION
    FORALL (x: (complete_lattice?)): lattice?(x);

  % Subtype TCC generated (at line 210, column 43) for  singleton(u)
      % expected type  S: (LAMBDA (S): least_bounded_above?(S, <=))
  lub_singleton_TCC1: OBLIGATION
    FORALL (u: T, <=: (partial_order?[T])):
      least_bounded_above?(singleton[T](u), <=);

  % Subtype TCC generated (at line 219, column 43) for  singleton(u)
      % expected type  S: (LAMBDA (S): greatest_bounded_below?(S, <=))
  glb_singleton_TCC1: OBLIGATION
    FORALL (u: T, <=: (partial_order?[T])):
      greatest_bounded_below?(singleton[T](u), <=);

  % Subtype TCC generated (at line 262, column 14) for  add(lub(<=)(S), S)
      % expected type  S: (LAMBDA (S): least_bounded_above?(S, <=))
  lub_add_TCC1: OBLIGATION
    FORALL (<=: (partial_order?[T]),
            S: (LAMBDA (S): least_bounded_above?(S, <=))):
      least_bounded_above?(add[T](lub(<=)(S), S), <=);

  % Subtype TCC generated (at line 272, column 14) for  add(glb(<=)(S), S)
      % expected type  S: (LAMBDA (S): greatest_bounded_below?(S, <=))
  glb_add_TCC1: OBLIGATION
    FORALL (<=: (partial_order?[T]),
            S: (LAMBDA (S): greatest_bounded_below?(S, <=))):
      greatest_bounded_below?(add[T](glb(<=)(S), S), <=);


body:
  %  Maximal, greatest, minimal, least elements on subsets, and their
  %  correlation with least upper and greatest lower bounds.
  %
  %  Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  %  Date: Oct 2004 / Jan 2005

  minmax_orders[T: TYPE]: THEORY

  BEGIN

    IMPORTING bounded_orders[T], finite_sets@finite_sets_minmax

    t, r: VAR T
    S: VAR set
    F: VAR finite_set
    NF: VAR non_empty_finite_set[T]
    <=, R: VAR pred[[T,T]]
    le: VAR (total_order?[T])
    ale: VAR (antisymmetric?[T])
    tle: VAR (dichotomous?[T])

    % ==========================================================================
    % Maximal/greatest elements
    % ==========================================================================

    % Maximal elements
    maximal?(t, S, <=): bool =
      S(t) AND NOT (EXISTS (r: (S)): t <= r AND t /= r)
  %    S(t) AND NOT lower_bound(t, S, irreflexive_kernel(<=))
    maximal?(S, <=)(t): MACRO bool = maximal?(t, S, <=)
    has_maximal?(S, <=): bool = EXISTS t: maximal?(t, S, <=)

    % Greatest elements
    greatest?(t, S, <=): bool = S(t) AND upper_bound?(t, S, <=)
    greatest?(S, <=)(t): MACRO bool = greatest?(t, S, <=)
    has_greatest?(S, <=): bool = EXISTS t: greatest?(t, S, <=)
    has_greatest?(<=)(S): MACRO bool = has_greatest?(S, <=)
    greatest(<=)(S: (has_greatest?(<=))): {t: (S) | greatest?(t, S, <=)}

    % Properties
    greatest_iff_least_upper_bound: LEMMA
      greatest?(t, S, <=) IFF least_upper_bound?(t, S, <=) AND S(t)

    greatest_is_least_upper_bound: JUDGEMENT
      (greatest?) SUBTYPE_OF (least_upper_bound?)

    has_greatest_is_least_bounded_above: JUDGEMENT
      (has_greatest?) SUBTYPE_OF (least_bounded_above?)

    greatest_equals_lub: LEMMA
      FORALL (S: (has_greatest?(ale))): greatest(ale)(S) = lub(ale)(S)

    greatest_unique: LEMMA
      FORALL (<=: (antisymmetric?[T]), (s, t: (greatest?(S, <=)))): s = t

    greatest_is_maximal: LEMMA
      greatest?(t, S, ale) => maximal?(t, S, ale)

    maximal_is_greatest: LEMMA
      maximal?(t, S, tle) => greatest?(t, S, tle)

    non_empty_finite_has_greatest: LEMMA
      has_greatest?(NF, le)

    greatest_ge: LEMMA
      FORALL (S: (has_greatest?(<=)), m: (S)): m <= greatest(<=)(S)

    greatest_monotone: LEMMA
      FORALL (S1, S2: (has_greatest?(<=))):
        subset?(S1, S2) => greatest(<=)(S1) <= greatest(<=)(S2)

    greatest_def: LEMMA
      FORALL (S: (has_greatest?(ale))):
        greatest(ale)(S) = t IFF greatest?(t, S, ale)

    greatest_upper_bound: LEMMA
      FORALL (<=: (partial_order?[T]), S: (has_greatest?(<=))):
        greatest(<=)(S) <= t IFF upper_bound?[T](t, S, <=)

    % ==========================================================================
    % Minimal/least elements
    % ==========================================================================

    % Minimal elements
    minimal?(t, S, <=): bool =
      S(t) AND NOT (EXISTS (r: (S)): r <= t AND t /= r)
    minimal?(S, <=)(t): MACRO bool = minimal?(t, S, <=)
    has_minimal?(S, <=): bool = EXISTS t: minimal?(t, S, <=)

    % Least elements
    least?(t, S, <=): bool = S(t) AND lower_bound?(t, S, <=)
    least?(S, <=)(t): MACRO bool = least?(t, S, <=)
    has_least?(S, <=): bool = EXISTS t: least?(t, S, <=)
    has_least?(<=)(S): MACRO bool = has_least?(S, <=)
    least(<=)(S: (has_least?(<=))): {t: (S) | least?(t, S, <=)}

    % Properties
    least_iff_greatest_lower_bound: LEMMA
      least?(t, S, <=) IFF greatest_lower_bound?(t, S, <=) AND S(t)

    least_is_greatest_lower_bound: JUDGEMENT
      (least?) SUBTYPE_OF (greatest_lower_bound?)

    has_least_is_greatest_bounded_below: JUDGEMENT
      (has_least?) SUBTYPE_OF (greatest_bounded_below?)

    least_equals_glb: LEMMA
      FORALL (S: (has_least?(ale))): least(ale)(S) = glb(ale)(S)

    least_unique: LEMMA
      FORALL (<=: (antisymmetric?[T]), (s, t: (least?(S, <=)))): s = t

    least_is_minimal: LEMMA
      least?(t, S, ale) => minimal?(t, S, ale)

    minimal_is_least: LEMMA
      minimal?(t, S, tle) => least?(t, S, tle)

    non_empty_finite_has_least: LEMMA
      has_least?(NF, le)

    least_le: LEMMA
      FORALL (S: (has_least?(<=)), m: (S)): least(<=)(S) <= m

    least_monotone: LEMMA
      FORALL (S1, S2: (has_least?(<=))):
        subset?(S1, S2) => least(<=)(S2) <= least(<=)(S1)

    least_def: LEMMA
      FORALL (S: (has_least?(ale))):
        least(ale)(S) = t IFF least?(t, S, ale)

    least_lower_bound: LEMMA
      FORALL (<=: (partial_order?[T]), S: (has_least?(<=))):
        t <= least(<=)(S) IFF lower_bound?[T](t, S, <=)

    % ==========================================================================
    % Both greatest and least elements exist
    % ==========================================================================

    has_extrema?(S, <=): bool = has_greatest?(S, <=) AND has_least?(S, <=)
  %  bounded_type?(<=): bool = has_extrema?(fullset, <=)

    has_extrema_has_greatest: JUDGEMENT
      (has_extrema?) SUBTYPE_OF (has_greatest?)
   
    has_extrema_has_least: JUDGEMENT
      (has_extrema?) SUBTYPE_OF (has_least?)

    total_order_is_lattice: JUDGEMENT
      (total_order?) SUBTYPE_OF (lattice?)

  END minmax_orders

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

  % Existence TCC generated (at line 38, column 2) for
      % greatest(<=)(S: (LAMBDA (S): has_greatest?(S, <=))):
      %       {t: (S) | greatest?(t, S, <=)}
  greatest_TCC1: OBLIGATION
    EXISTS (x:
              [<=: pred[[T, T]] ->
                 [S: (LAMBDA (S): has_greatest?(S, <=)) ->
                    {t: (S) | greatest?(t, S, <=)}]]):
      TRUE;

  % Judgement subtype TCC generated (at line 45, column 4) for  x
      % expected type  (least_upper_bound?)
  greatest_is_least_upper_bound: OBLIGATION
    FORALL (x: (greatest?)): least_upper_bound?[T](x);

  % Judgement subtype TCC generated (at line 48, column 4) for  x
      % expected type  (least_bounded_above?)
  has_greatest_is_least_bounded_above: OBLIGATION
    FORALL (x: (has_greatest?)): least_bounded_above?[T](x);

  % Subtype TCC generated (at line 51, column 66) for  S
      % expected type  S: (LAMBDA (S: set[T]): least_bounded_above?(S, ale))
  greatest_equals_lub_TCC1: OBLIGATION
    FORALL (ale: (antisymmetric?[T]),
            S: (LAMBDA (S): has_greatest?(S, ale))):
      least_bounded_above?[T](S, ale);

  % Existence TCC generated (at line 95, column 2) for
      % least(<=)(S: (LAMBDA (S): has_least?(S, <=))):
      %       {t: (S) | least?(t, S, <=)}
  least_TCC1: OBLIGATION
    EXISTS (x:
              [<=: pred[[T, T]] ->
                 [S: (LAMBDA (S): has_least?(S, <=)) ->
                    {t: (S) | least?(t, S, <=)}]]):
      TRUE;

  % Judgement subtype TCC generated (at line 102, column 4) for  x
      % expected type  (greatest_lower_bound?)
  least_is_greatest_lower_bound: OBLIGATION
    FORALL (x: (least?)): greatest_lower_bound?[T](x);

  % Judgement subtype TCC generated (at line 105, column 4) for  x
      % expected type  (greatest_bounded_below?)
  has_least_is_greatest_bounded_below: OBLIGATION
    FORALL (x: (has_least?)): greatest_bounded_below?[T](x);

  % Subtype TCC generated (at line 108, column 60) for  S
      % expected type  S:
                     %   (LAMBDA (S: set[T]): greatest_bounded_below?(S, ale))
  least_equals_glb_TCC1: OBLIGATION
    FORALL (ale: (antisymmetric?[T]), S: (LAMBDA (S): has_least?(S, ale))):
      greatest_bounded_below?[T](S, ale);

  % Judgement subtype TCC generated (at line 145, column 4) for  x
      % expected type  (has_greatest?)
  has_extrema_has_greatest: OBLIGATION
    FORALL (x: (has_extrema?)): has_greatest?(x);

  % Judgement subtype TCC generated (at line 148, column 4) for  x
      % expected type  (has_least?)
  has_extrema_has_least: OBLIGATION FORALL (x: (has_extrema?)): has_least?(x);

  % Judgement subtype TCC generated (at line 151, column 4) for  x
      % expected type  (lattice?)
  total_order_is_lattice: OBLIGATION
    FORALL (x: (total_order?)): lattice?[T](x);


body:
  % supplement to indexed_sets: monotony properties
  %
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Dec 2004

  indexed_sets_extra[index, T: TYPE]: THEORY

  BEGIN

    IMPORTING indexed_sets[index, T]

    i: VAR index
    A, B: VAR [index -> set[T]]

    IUnion_is_monotone: LEMMA
      (FORALL i: subset?(A(i), B(i))) =>
        subset?(IUnion(A), IUnion(B))

    IIntersection_is_monotone: LEMMA
      (FORALL i: subset?(A(i), B(i))) =>
        subset?(IIntersection(A), IIntersection(B))

  END indexed_sets_extra


body:
  % iteration of binary relations R, i.e., R composed with itself n times
  % R o ... o R
  %
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Dec 2004

  relation_iterate[T: TYPE]: THEORY

  BEGIN

    IMPORTING relations_extra[T], relation_props2[T, T, T, T]

    R, R1, R2, S1, S2: VAR pred[[T, T]]
    m, n: VAR nat
    p: VAR posnat
    x, y, z: VAR T

    comp_equal_r: LEMMA
      R o =[T] = R

    comp_equal_l: LEMMA
      =[T] o R = R

    iterate(R, n): RECURSIVE pred[[T, T]] =
      IF n = 0 THEN =[T] ELSE iterate(R, n - 1) o R ENDIF
    MEASURE n

    iterate_add: LEMMA
      iterate(R, m + n) = iterate(R, m) o iterate(R, n)

    iterate_add_applied: LEMMA 
      iterate(R, m)(x,y) & iterate(R, n)(y,z) => iterate(R, m + n)(x,z)

    iterate_1: LEMMA
      iterate(R, 1) = R

    iterate_add_one: LEMMA 
      iterate(R, n + 1) = R o iterate(R, n)

    iterate_mult: LEMMA
      iterate(iterate(R, m), n) = iterate(R, m * n)

    converse_equal: LEMMA
      converse(=[T]) = =[T]

    converse_comp: LEMMA
      converse(R1 o R2) = converse(R2) o converse(R1)

    iterate_converse: LEMMA
      iterate(converse(R), n) = converse(iterate(R, n))

    comp_is_monotone: LEMMA
      subset?(R1, R2) & subset?(S1, S2) => subset?(R1 o S1, R2 o S2)

    iterate_is_monotone: LEMMA
      subset?(R1, R2) => subset?(iterate(R1, n), iterate(R2, n))

  END relation_iterate

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

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

  % Termination TCC generated (at line 25, column 28) for  iterate(R, n - 1)
  iterate_TCC2: OBLIGATION FORALL (n: nat): NOT n = 0 IMPLIES n - 1 < n;


body:
  % reflexive, symmetric, and transitive closures of a binary relation
  % and their properties
  %
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Dec 2004 / Jan 2005
  %
  % Rewriting identities added 19 Jan 2005, and generalization to order? added
  % 24 Feb 2005 by Jerry James (jamesj@acm.org), University of Kansas.

  closure_ops[T: TYPE]: THEORY

  BEGIN

    IMPORTING
      relation_iterate[T],
      indexed_sets_extra

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

    % closures, i.e., least super-relations that satisfy a certain property
    % kernels, i.e., greatest sub-relations that satisfy a certain property

    reflexive_closure(R): (reflexive?) = union(R, =)
    irreflexive_kernel(R): (irreflexive?) = difference(R, =)
    symmetric_closure(R): (symmetric?) = union(R, converse(R))
    symmetric_kernel(R): (symmetric?) = intersection(R, converse(R))
    asymmetric_kernel(R): (asymmetric?) = difference(R, converse(R))
    transitive_closure(R): (transitive?) = IUnion(LAMBDA p: iterate(R, p))
    preorder_closure(R): (preorder?) = IUnion(LAMBDA n: iterate(R, n))

    reflexive_irreflexive: LEMMA
      FORALL (R: (reflexive?)): reflexive_closure(irreflexive_kernel(R)) = R

    irreflexive_reflexive: LEMMA
      FORALL (R: (irreflexive?)): irreflexive_kernel(reflexive_closure(R)) = R

    reflexive_closure_preserves_transitive: JUDGEMENT
      reflexive_closure(R: (transitive?)) HAS_TYPE (preorder?)

    reflexive_closure_preserves_antisymmetric: JUDGEMENT
      reflexive_closure(R: (antisymmetric?)) HAS_TYPE (antisymmetric?)

    order_to_partial_order: JUDGEMENT
      reflexive_closure(R: (order?)) HAS_TYPE (partial_order?)

    reflexive_closure_dichotomous: JUDGEMENT
      reflexive_closure(R: (trichotomous?)) HAS_TYPE (dichotomous?)

    linear_order_to_total_order: JUDGEMENT
      reflexive_closure(R: (linear_order?)) HAS_TYPE (total_order?)

    order_to_strict_order: JUDGEMENT
      irreflexive_kernel(R: (order?)) HAS_TYPE (strict_order?)

    irreflexive_kernel_of_antisymmetric: JUDGEMENT
      irreflexive_kernel(R: (antisymmetric?)) HAS_TYPE (asymmetric?)

    irreflexive_kernel_trichotomous: JUDGEMENT
      irreflexive_kernel(R: (dichotomous?)) HAS_TYPE (trichotomous?)

    linear_order_to_strict_total_order: JUDGEMENT
      irreflexive_kernel(R: (total_order?)) HAS_TYPE (strict_total_order?)

    symmetric_kernel_of_preorder: JUDGEMENT
      symmetric_kernel(R: (preorder?)) HAS_TYPE (equivalence?)

    asymmetric_kernel_of_preorder: JUDGEMENT
      asymmetric_kernel(R: (preorder?)) HAS_TYPE (strict_order?)

    preorder_closure_converse: LEMMA
      preorder_closure(converse(R)) = converse(preorder_closure(R))

    symmetry_char: LEMMA
      symmetric?[T](R) <=> subset?(R, converse(R))

    transitive_closure_of_reflexive: JUDGEMENT
      transitive_closure(R: (reflexive?)) HAS_TYPE (preorder?)

    transitive_closure_is_monotone: LEMMA
      subset?(R1, R2) => subset?(transitive_closure(R1), transitive_closure(R2))

    preorder_closure_is_monotone: LEMMA
      subset?(R1, R2) => subset?(preorder_closure(R1), preorder_closure(R2))

    preorder_closure_preserves_symmetry: JUDGEMENT
      preorder_closure(R: (symmetric?)) HAS_TYPE (equivalence?)

    equivalence_closure(R): (equivalence?) =
      preorder_closure(symmetric_closure(R))

    transitive_closure_step_r: THEOREM
      transitive_closure(R) = preorder_closure(R) o R

    transitive_closure_step_l: THEOREM
      transitive_closure(R) = R o preorder_closure(R)

    preorder_closure_reflexive_transitive: THEOREM
      preorder_closure(R) = reflexive_closure(transitive_closure(R))

    preorder_closure_transitive_reflexive: THEOREM
      preorder_closure(R) = transitive_closure(reflexive_closure(R))

    %% Rewriting identities / idempotency of the operators

    reflexive_closure_identity: LEMMA
      FORALL (<: (reflexive?)): reflexive_closure(<) = <

    irreflexive_kernel_identity: LEMMA
      FORALL (<: (irreflexive?)): irreflexive_kernel(<) = <

    symmetric_closure_identity: LEMMA
      FORALL (<: (symmetric?)): symmetric_closure(<) = <

    symmetric_kernel_identity: LEMMA
      FORALL (<: (symmetric?)): symmetric_kernel(<) = <

    asymmetric_kernel_identity: LEMMA
      FORALL (<: (asymmetric?)): asymmetric_kernel(<) = <

    transitive_closure_identity: LEMMA
      FORALL (<: (transitive?)): transitive_closure(<) = <

    preorder_closure_identity: LEMMA
      FORALL (<: (preorder?)): preorder_closure(<) = <

    preorder_closure_reflexive: LEMMA
      FORALL (<: (order?)): preorder_closure(<) = reflexive_closure(<)

    equivalence_closure_identity: LEMMA
      FORALL (<: (equivalence?)): equivalence_closure(<) = <

  END closure_ops

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

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

  % Subtype TCC generated (at line 26, column 42) for  difference(R, =)
      % expected type  (irreflexive?)
  irreflexive_kernel_TCC1: OBLIGATION
    FORALL (R: pred[[T, T]]): irreflexive?[T](difference[[T, T]](R, =));

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

  % Subtype TCC generated (at line 28, column 38) for
      % intersection(R, converse(R))
      % expected type  (symmetric?)
  symmetric_kernel_TCC1: OBLIGATION
    FORALL (R: pred[[T, T]]):
      symmetric?[T](intersection[[T, T]](R, converse[T, T](R)));

  % Subtype TCC generated (at line 29, column 40) for
      % difference(R, converse(R))
      % expected type  (asymmetric?)
  asymmetric_kernel_TCC1: OBLIGATION
    FORALL (R: pred[[T, T]]):
      asymmetric?[T](difference[[T, T]](R, converse[T, T](R)));

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

  % Subtype TCC generated (at line 31, column 37) for
      % IUnion(LAMBDA n: iterate(R, n))
      % expected type  (preorder?)
  preorder_closure_TCC1: OBLIGATION
    FORALL (R: pred[[T, T]]):
      preorder?[T](IUnion[nat, [T, T]](LAMBDA n: iterate[T](R, n)));

  % Judgement subtype TCC generated (at line 40, column 4) for
      % reflexive_closure(R)
      % expected type  (preorder?)
  reflexive_closure_preserves_transitive: OBLIGATION
    FORALL (R: (transitive?)): preorder?[T](reflexive_closure(R));

  % Judgement subtype TCC generated (at line 43, column 4) for
      % reflexive_closure(R)
      % expected type  (antisymmetric?)
  reflexive_closure_preserves_antisymmetric: OBLIGATION
    FORALL (R: (antisymmetric?)): antisymmetric?[T](reflexive_closure(R));

  % Judgement subtype TCC generated (at line 46, column 4) for
      % reflexive_closure(R)
      % expected type  (partial_order?)
  order_to_partial_order: OBLIGATION
    FORALL (R: (order?)): partial_order?[T](reflexive_closure(R));

  % Judgement subtype TCC generated (at line 49, column 4) for
      % reflexive_closure(R)
      % expected type  (dichotomous?)
  reflexive_closure_dichotomous: OBLIGATION
    FORALL (R: (trichotomous?)): dichotomous?[T](reflexive_closure(R));

  % Judgement subtype TCC generated (at line 52, column 4) for
      % reflexive_closure(R)
      % expected type  (total_order?)
  linear_order_to_total_order: OBLIGATION
    FORALL (R: (linear_order?)): total_order?[T](reflexive_closure(R));

  % Judgement subtype TCC generated (at line 55, column 4) for
      % irreflexive_kernel(R)
      % expected type  (strict_order?)
  order_to_strict_order: OBLIGATION
    FORALL (R: (order?)): strict_order?[T](irreflexive_kernel(R));

  % Judgement subtype TCC generated (at line 58, column 4) for
      % irreflexive_kernel(R)
      % expected type  (asymmetric?)
  irreflexive_kernel_of_antisymmetric: OBLIGATION
    FORALL (R: (antisymmetric?)): asymmetric?[T](irreflexive_kernel(R));

  % Judgement subtype TCC generated (at line 61, column 4) for
      % irreflexive_kernel(R)
      % expected type  (trichotomous?)
  irreflexive_kernel_trichotomous: OBLIGATION
    FORALL (R: (dichotomous?)): trichotomous?[T](irreflexive_kernel(R));

  % Judgement subtype TCC generated (at line 64, column 4) for
      % irreflexive_kernel(R)
      % expected type  (strict_total_order?)
  linear_order_to_strict_total_order: OBLIGATION
    FORALL (R: (total_order?)): strict_total_order?[T](irreflexive_kernel(R));

  % Judgement subtype TCC generated (at line 67, column 4) for
      % symmetric_kernel(R)
      % expected type  (equivalence?)
  symmetric_kernel_of_preorder: OBLIGATION
    FORALL (R: (preorder?)): equivalence?[T](symmetric_kernel(R));

  % Judgement subtype TCC generated (at line 70, column 4) for
      % asymmetric_kernel(R)
      % expected type  (strict_order?)
  asymmetric_kernel_of_preorder: OBLIGATION
    FORALL (R: (preorder?)): strict_order?[T](asymmetric_kernel(R));

  % Judgement subtype TCC generated (at line 79, column 4) for
      % transitive_closure(R)
      % expected type  (preorder?)
  transitive_closure_of_reflexive: OBLIGATION
    FORALL (R: (reflexive?)): preorder?[T](transitive_closure(R));

  % Judgement subtype TCC generated (at line 88, column 4) for
      % preorder_closure(R)
      % expected type  (equivalence?)
  preorder_closure_preserves_symmetry: OBLIGATION
    FORALL (R: (symmetric?)): equivalence?[T](preorder_closure(R));


body:
  %-------------------------------------------------------------------------
  %
  %  Sets that pivot about an element.  This includes prefixes and suffixes,
  %  as well as generalizations of upto, below, upfrom, and above sets.
  %
  %  For PVS version 3.2.  February 28, 2005
  %  ---------------------------------------------------------------------
  %      Author: Jerry James (jamesj@acm.org), University of Kansas
  %
  %  EXPORTS
  %  -------
  %  prelude: orders[T], relation_props2[T, T, T, T], relations[T], sets[T]
  %  orders: closure_ops[T], indexed_sets_extra, ordered_subset[T],
  %    relation_iterate[T], relations_extra[T]
  %
  %-------------------------------------------------------------------------
  ordered_subset[T: TYPE]: THEORY
   BEGIN

    IMPORTING sets[T], closure_ops[T]

    ord: VAR (order?)
    t, r: VAR T
    S, R: VAR set
    <: VAR pred[[T, T]]


    % ==========================================================================
    % Prefixes and suffixes
    % ==========================================================================

    prefix?(S, <): bool = FORALL t, (r: (S)): t < r => member(t, S)
    prefix?(<)(S): MACRO bool = prefix?(S, <)

    emptyset_is_prefix: LEMMA FORALL <: prefix?(emptyset, <)

    fullset_is_prefix: LEMMA FORALL <: prefix?(fullset, <)

    suffix?(S, <): bool = FORALL t, (r: (S)): r < t => member(t, S)
    suffix?(<)(S): MACRO bool = suffix?(S, <)

    emptyset_is_suffix: LEMMA FORALL <: suffix?(emptyset, <)

    fullset_is_suffix: LEMMA FORALL <: suffix?(fullset, <)


    % ==========================================================================
    % Pivot sets
    % ==========================================================================

    upto(t, ord):   (prefix?(ord)) = {r | reflexive_closure(ord)(r, t)}
    below(t, ord):  (prefix?(ord)) = {r | irreflexive_kernel(ord)(r, t)}
    upfrom(t, ord): (suffix?(ord)) = {r | reflexive_closure(ord)(t, r)}
    above(t, ord):  (suffix?(ord)) = {r | irreflexive_kernel(ord)(t, r)}
    unrelated(t, ord): set[T] = {r | NOT (ord(r, t) OR ord(t, r) OR t = r)}

    add_below_is_upto: LEMMA
      FORALL t, ord: add(t, below(t, ord)) = upto(t, ord)

    remove_upto_is_below: LEMMA
      FORALL t, ord: remove(t, upto(t, ord)) = below(t, ord)

    add_above_is_upfrom: LEMMA
      FORALL t, ord: add(t, above(t, ord)) = upfrom(t, ord)

    remove_upfrom_is_above: LEMMA
      FORALL t, ord: remove(t, upfrom(t, ord)) = above(t, ord)

    upto_above_related: LEMMA
      FORALL t, ord:
        union(upto(t, ord), above(t, ord)) = complement(unrelated(t, ord))

    below_upfrom_related: LEMMA
      FORALL t, ord:
        union(below(t, ord), upfrom(t, ord)) = complement(unrelated(t, ord))

  % --------- New Content Provided By David Lester

    tr:   VAR (transitive?[T])

    % ==========================================================================
    % Alternative Names
    % ==========================================================================

    lower_set?(<)(S): MACRO bool = prefix?(<)(S)
    upper_set?(<)(S): MACRO bool = suffix?(<)(S)

    % Ideally, we'd write the following as:
    %   down(tr)(t): MACRO (lower_set?(tr)) = upto(t,tr)
    %   up(tr)(t):   MACRO (upper_set?(tr)) = upfrom(t,tr)
    % But upto and upfrom have been given overly restrictive types (i.e. they
    % are only defined on order relations not merely transitive relations).

    down(tr)(t): MACRO (lower_set?(tr)) = {r | reflexive_closure(tr)(r, t)}
    up(tr)(t):   MACRO (upper_set?(tr)) = {r | reflexive_closure(tr)(t, r)}

    % ==========================================================================
    % Additional Properties
    % ==========================================================================

    x,y: VAR T
    X,Y: VAR set[T]
    U:   VAR setofsets[T]

    down_subset: LEMMA tr(x,y) IMPLIES subset?(down(tr)(x),down(tr)(y))
    up_subset:   LEMMA tr(x,y) IMPLIES subset?(up(tr)(y),up(tr)(x))

    complement_lower_set: LEMMA FORALL (X:(lower_set?(<))):
                                                  upper_set?(<)(complement(X))

    complement_upper_set: LEMMA FORALL (X:(upper_set?(<))):
                                                  lower_set?(<)(complement(X))

    lower_set_def: LEMMA lower_set?(tr)(X) IFF X = Union(image(down(tr),X))

    upper_set_def: LEMMA upper_set?(tr)(X) IFF X = Union(image(up(tr),X))

    Union_lower_set: LEMMA every(lower_set?(tr),U)
                                                IMPLIES lower_set?(tr)(Union(U))

    Union_upper_set: LEMMA every(upper_set?(<),U) IMPLIES upper_set?(<)(Union(U))

    union_lower_set: LEMMA FORALL (X,Y:(lower_set?(tr))):
                                                      lower_set?(tr)(union(X,Y))

    union_upper_set: LEMMA FORALL (X,Y:(upper_set?(<))):
                                                      upper_set?(<)(union(X,Y))

    Intersection_lower_set: LEMMA every(lower_set?(<),U) IMPLIES
                                  lower_set?(<)(Intersection(U))

    Intersection_upper_set: LEMMA every(upper_set?(tr),U) IMPLIES
                                  upper_set?(tr)(Intersection(U))

    intersection_lower_set: LEMMA FORALL (X,Y:(lower_set?(<))):
                                                lower_set?(<)(intersection(X,Y))

    intersection_upper_set: LEMMA FORALL (X,Y:(upper_set?(tr))):
                                                upper_set?(tr)(intersection(X,Y))

   END ordered_subset

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

  % Subtype TCC generated (at line 51, column 35) for
      % {r | reflexive_closure(ord)(r, t)}
      % expected type  (LAMBDA (S): prefix?(S, ord))
  upto_TCC1: OBLIGATION
    FORALL (t: T, ord: (order?[T])):
      prefix?({r | reflexive_closure[T](ord)(r, t)}, ord);

  % Subtype TCC generated (at line 52, column 35) for
      % {r | irreflexive_kernel(ord)(r, t)}
      % expected type  (LAMBDA (S): prefix?(S, ord))
  below_TCC1: OBLIGATION
    FORALL (t: T, ord: (order?[T])):
      prefix?({r | irreflexive_kernel[T](ord)(r, t)}, ord);

  % Subtype TCC generated (at line 53, column 35) for
      % {r | reflexive_closure(ord)(t, r)}
      % expected type  (LAMBDA (S): suffix?(S, ord))
  upfrom_TCC1: OBLIGATION
    FORALL (t: T, ord: (order?[T])):
      suffix?({r | reflexive_closure[T](ord)(t, r)}, ord);

  % Subtype TCC generated (at line 54, column 35) for
      % {r | irreflexive_kernel(ord)(t, r)}
      % expected type  (LAMBDA (S): suffix?(S, ord))
  above_TCC1: OBLIGATION
    FORALL (t: T, ord: (order?[T])):
      suffix?({r | irreflexive_kernel[T](ord)(t, r)}, ord);

  % Subtype TCC generated (at line 94, column 40) for
      % {r | reflexive_closure(tr)(r, t)}
      % expected type  (LAMBDA (S): prefix?(S, tr))
  down_TCC1: OBLIGATION
    FORALL (tr: (transitive?[T]), t: T):
      prefix?({r | reflexive_closure[T](tr)(r, t)}, tr);

  % Subtype TCC generated (at line 95, column 40) for
      % {r | reflexive_closure(tr)(t, r)}
      % expected type  (LAMBDA (S): suffix?(S, tr))
  up_TCC1: OBLIGATION
    FORALL (tr: (transitive?[T]), t: T):
      suffix?({r | reflexive_closure[T](tr)(t, r)}, tr);


body:
  %-------------------------------------------------------------------------
  %
  %  Chains (totally ordered subsets of a poset).
  %
  %  For PVS version 3.2.  January 14, 2005
  %  ---------------------------------------------------------------------
  %      Author: Jerry James (jamesj@acm.org), University of Kansas
  %
  %  EXPORTS
  %  -------
  %  prelude: orders[chain], orders[T], sets[T]
  %  orders: chain[T, <=]
  %
  %-------------------------------------------------------------------------
  chain[T: TYPE, <=: (partial_order?[T])]: THEORY
   BEGIN

    IMPORTING orders[T], sets[T]

    S: VAR set

    % The chain type
    chain?(S): bool = total_order?(restrict[[T, T], [(S), (S)], bool](<=))

    chain: TYPE+ = (chain?) CONTAINING emptyset

    ch, ch1, ch2: VAR chain

    % Maximal chains
    maximal_chain?(ch): bool = NOT (EXISTS ch1: strict_subset?(ch, ch1))

    % Chain properties
    subset_chain: THEOREM FORALL ch, S: subset?(S, ch) => chain?(S)

    intersection_chain: JUDGEMENT intersection(ch1, ch2) HAS_TYPE chain

    % Chain order
    IMPORTING orders[chain]

    chain_order(ch1, ch2): bool = subset?(ch1, ch2)

    chain_order_partial: JUDGEMENT
      chain_order HAS_TYPE (partial_order?[chain])

   END chain

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

  % Subtype TCC generated (at line 25, column 37) for  emptyset
      % expected type  chain
  chain_TCC1: OBLIGATION chain?(emptyset[T]);

  % Judgement subtype TCC generated (at line 35, column 32) for
      % intersection(ch1, ch2)
      % expected type  chain
  intersection_chain: OBLIGATION
    FORALL (ch1, ch2): chain?(intersection[T](ch1, ch2));

  % Judgement subtype TCC generated (at line 43, column 4) for  chain_order
      % expected type  (partial_order?[chain])
  chain_order_partial: OBLIGATION partial_order?[chain](chain_order);


body:
  %------------------------------------------------------------------------------
  % Definitions and subtype properties of directed complete partial orders
  %
  %       Author: David Lester <dlester@cs.man.ac.uk> Manchester University
  %
  %       Version 1.0          02/09/06 
  %------------------------------------------------------------------------------

  directed_orders[T:TYPE]: THEORY

  BEGIN

    IMPORTING relations_extra[T]

    x,y,z: VAR T
    p:     VAR pred[[T,T]]
    <=:    VAR (partial_order?[T])
    S:     VAR (nonempty?[T])
    X:     VAR set[T]

    IMPORTING bounded_orders[T], chain, ordered_subset[T]

    trivial_partial_order?(p):bool = FORALL x,y: p(x,y) IFF x = y

    directed?(<=)(S):bool
      = FORALL x,y: S(x) AND S(y) IMPLIES EXISTS (z:(S)): x <= z AND y <= z

    directed?(<=,S):MACRO bool = directed?(<=)(S)

    directed_def: LEMMA FORALL (D:(directed?(<=))):
        FORALL X: is_finite(X) AND subset?(X,D) IMPLIES
           EXISTS (x:(D)): bounded_orders.upper_bound?(x,X,<=)

    directed_complete?(<=):bool
      = FORALL (D:(directed?(<=))): least_bounded_above?(<=)(D)

    directed_complete_partial_order?(p):bool
      = partial_order?(p) AND directed_complete?(p)

    chain_complete?(<=):bool
      = FORALL (C:(chain?[T,(<=)])): least_bounded_above?(<=)(C)

    chain_complete_partial_order?(p):bool
      = partial_order?(p) AND chain_complete?(p)

    directed_least_bounded_above: LEMMA
      FORALL (<=:(directed_complete_partial_order?), D:(directed?(<=))):
              least_bounded_above?(<=)(D)

    dcpo_is_po: JUDGEMENT (directed_complete_partial_order?) SUBTYPE_OF
                                                               (partial_order?)

    complete_upper_semilattice_is_dcpo:
                JUDGEMENT (complete_upper_semilattice?) SUBTYPE_OF
                          (directed_complete_partial_order?)

    IMPORTING minmax_orders[T]

    pointed_directed_complete_partial_order?(p): bool
      = directed_complete_partial_order?(p) AND has_least?(p)(fullset[T])

    pdcpo_is_dcpo: JUDGEMENT (pointed_directed_complete_partial_order?)
                                   SUBTYPE_OF (directed_complete_partial_order?)

    pdcpo_is_ccpo: JUDGEMENT (pointed_directed_complete_partial_order?)
                                   SUBTYPE_OF (chain_complete_partial_order?)

  END directed_orders

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

  % Judgement subtype TCC generated (at line 50, column 24) for  x
      % expected type  (partial_order?)
  dcpo_is_po: OBLIGATION
    FORALL (x: (directed_complete_partial_order?)): partial_order?[T](x);

  % Judgement subtype TCC generated (at line 54, column 24) for  x
      % expected type  (directed_complete_partial_order?)
  complete_upper_semilattice_is_dcpo: OBLIGATION
    FORALL (x: (complete_upper_semilattice?)):
      directed_complete_partial_order?(x);

  % Judgement subtype TCC generated (at line 62, column 27) for  x
      % expected type  (directed_complete_partial_order?)
  pdcpo_is_dcpo: OBLIGATION
    FORALL (x: (pointed_directed_complete_partial_order?)):
      directed_complete_partial_order?(x);

  % Judgement subtype TCC generated (at line 65, column 27) for  x
      % expected type  (chain_complete_partial_order?)
  pdcpo_is_ccpo: OBLIGATION
    FORALL (x: (pointed_directed_complete_partial_order?)):
      chain_complete_partial_order?(x);


body:
  %------------------------------------------------------------------------------
  % Pointwise Ordering in Product Types
  %
  %       Author: David Lester <dlester@cs.man.ac.uk> Manchester University
  %
  %       Version 1.0          03/30/06
  %------------------------------------------------------------------------------

  product_orders[T1,T2:TYPE]: THEORY

  BEGIN

    rel1:  VAR pred[[T1,T1]]
    rel2:  VAR pred[[T2,T2]]
    x,y: VAR [[T1,T2]]

    ; % syntax

    *(rel1,rel2)(x,y):bool = rel1(x`1,y`1) AND rel2(x`2,y`2)

    product_preserves_reflexive: JUDGEMENT
     *(r1:(reflexive?[T1]),r2:(reflexive?[T2])) HAS_TYPE (reflexive?[[T1,T2]])

    product_preserves_transitive: JUDGEMENT
     *(r1:(transitive?[T1]),r2:(transitive?[T2])) HAS_TYPE (transitive?[[T1,T2]])

    product_preserves_antisymmetric: JUDGEMENT
     *(r1:(antisymmetric?[T1]),r2:(antisymmetric?[T2]))
                                               HAS_TYPE (antisymmetric?[[T1,T2]])

    product_preserves_preorder: JUDGEMENT
     *(r1:(preorder?[T1]),r2:(preorder?[T2])) HAS_TYPE (preorder?[[T1,T2]])

    product_preserves_partial_order: JUDGEMENT
     *(r1:(partial_order?[T1]),r2:(partial_order?[T2]))
                                               HAS_TYPE (partial_order?[[T1,T2]])

    IMPORTING directed_orders[T1], directed_orders[T2], directed_orders[[T1,T2]]

    product_preserves_directed_complete: JUDGEMENT
     *(r1:(directed_complete?[T1]),r2:(directed_complete?[T2]))
                                           HAS_TYPE (directed_complete?[[T1,T2]])

    product_preserves_directed_complete_partial_order: JUDGEMENT
     *(r1:(directed_complete_partial_order?[T1]),
       r2:(directed_complete_partial_order?[T2]))
                             HAS_TYPE (directed_complete_partial_order?[[T1,T2]])

    product_lub: LEMMA FORALL (r1:(directed_complete_partial_order?[T1]),
                               r2:(directed_complete_partial_order?[T2]),
                               D :(directed?(r1*r2))):
          lub(r1*r2)(D) = (lub(r1)({x:T1| EXISTS (z:(D)): z`1=x}),
                           lub(r2)({y:T2| EXISTS (z:(D)): z`2=y}))

    product_preserves_has_least: LEMMA
      has_least?(rel1)(fullset[T1]) AND has_least?(rel2)(fullset[T2]) IMPLIES
       has_least?(*(rel1,rel2))(fullset[[T1,T2]])

    product_preserves_pointed_directed_complete_partial_order: JUDGEMENT
     *(r1:(pointed_directed_complete_partial_order?[T1]),
       r2:(pointed_directed_complete_partial_order?[T2]))
                     HAS_TYPE (pointed_directed_complete_partial_order?[[T1,T2]])

    product_least: LEMMA
                     FORALL (r1:(pointed_directed_complete_partial_order?[T1]),
                             r2:(pointed_directed_complete_partial_order?[T2])):
     least(r1*r2)(fullset[[T1,T2]])
                            = (least(r1)(fullset[T1]),least(r2)(fullset[T2]))

  END product_orders

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

  % Judgement subtype TCC generated (at line 22, column 3) for  r1 * r2
      % expected type  (reflexive?[[T1, T2]])
  product_preserves_reflexive: OBLIGATION
    FORALL (r1: (reflexive?[T1]), r2: (reflexive?[T2])):
      reflexive?[[T1, T2]](r1 * r2);

  % Judgement subtype TCC generated (at line 25, column 3) for  r1 * r2
      % expected type  (transitive?[[T1, T2]])
  product_preserves_transitive: OBLIGATION
    FORALL (r1: (transitive?[T1]), r2: (transitive?[T2])):
      transitive?[[T1, T2]](r1 * r2);

  % Judgement subtype TCC generated (at line 28, column 3) for  r1 * r2
      % expected type  (antisymmetric?[[T1, T2]])
  product_preserves_antisymmetric: OBLIGATION
    FORALL (r1: (antisymmetric?[T1]), r2: (antisymmetric?[T2])):
      antisymmetric?[[T1, T2]](r1 * r2);

  % Judgement subtype TCC generated (at line 32, column 3) for  r1 * r2
      % expected type  (preorder?[[T1, T2]])
  product_preserves_preorder: OBLIGATION
    FORALL (r1: (preorder?[T1]), r2: (preorder?[T2])):
      preorder?[[T1, T2]](r1 * r2);

  % Judgement subtype TCC generated (at line 35, column 3) for  r1 * r2
      % expected type  (partial_order?[[T1, T2]])
  product_preserves_partial_order: OBLIGATION
    FORALL (r1: (partial_order?[T1]), r2: (partial_order?[T2])):
      partial_order?[[T1, T2]](r1 * r2);

  % Judgement subtype TCC generated (at line 41, column 3) for  r1 * r2
      % expected type  (directed_complete?[[T1, T2]])
  product_preserves_directed_complete: OBLIGATION
    FORALL (r1: (directed_complete?[T1]), r2: (directed_complete?[T2])):
      directed_complete?[[T1, T2]](r1 * r2);

  % Judgement subtype TCC generated (at line 45, column 3) for  r1 * r2
      % expected type  (directed_complete_partial_order?[[T1, T2]])
  product_preserves_directed_complete_partial_order: OBLIGATION
    FORALL (r1: (directed_complete_partial_order?[T1]),
            r2: (directed_complete_partial_order?[T2])):
      directed_complete_partial_order?[[T1, T2]](r1 * r2);

  % Subtype TCC generated (at line 52, column 19) for  D
      % expected type  S:
                     %   (LAMBDA (S: set[[T1, T2]]):
                     %      least_bounded_above?(S, r1 * r2))
  product_lub_TCC1: OBLIGATION
    FORALL (r1: (directed_complete_partial_order?[T1]),
            r2: (directed_complete_partial_order?[T2]),
            D: (directed?[[T1, T2]](r1 * r2))):
      least_bounded_above?[[T1, T2]](D, r1 * r2);

  % Subtype TCC generated (at line 52, column 33) for
      % {x: T1 | EXISTS (z: (D)): z`1 = x}
      % expected type  S: (LAMBDA (S: set[T1]): least_bounded_above?(S, r1))
  product_lub_TCC2: OBLIGATION
    FORALL (r1: (directed_complete_partial_order?[T1]),
            r2: (directed_complete_partial_order?[T2]),
            D: (directed?[[T1, T2]](r1 * r2))):
      least_bounded_above?[T1]({x: T1 | EXISTS (z: (D)): z`1 = x}, r1);

  % Subtype TCC generated (at line 53, column 33) for
      % {y: T2 | EXISTS (z: (D)): z`2 = y}
      % expected type  S: (LAMBDA (S: set[T2]): least_bounded_above?(S, r2))
  product_lub_TCC3: OBLIGATION
    FORALL (r1: (directed_complete_partial_order?[T1]),
            r2: (directed_complete_partial_order?[T2]),
            D: (directed?[[T1, T2]](r1 * r2))):
      least_bounded_above?[T2]({y: T2 | EXISTS (z: (D)): z`2 = y}, r2);

  % Judgement subtype TCC generated (at line 60, column 3) for  r1 * r2
      % expected type  (pointed_directed_complete_partial_order?[[T1, T2]])
  product_preserves_pointed_directed_complete_partial_order: OBLIGATION
    FORALL (r1: (pointed_directed_complete_partial_order?[T1]),
            r2: (pointed_directed_complete_partial_order?[T2])):
      pointed_directed_complete_partial_order?[[T1, T2]](r1 * r2);

  % Subtype TCC generated (at line 67, column 16) for  fullset[[T1, T2]]
      % expected type  S: (LAMBDA (S: set[[T1, T2]]): has_least?(S, r1 * r2))
  product_least_TCC1: OBLIGATION
    FORALL (r1: (pointed_directed_complete_partial_order?[T1]),
            r2: (pointed_directed_complete_partial_order?[T2])):
      has_least?[[T1, T2]](fullset[[T1, T2]], r1 * r2);

  % Subtype TCC generated (at line 68, column 39) for  fullset[T1]
      % expected type  S: (LAMBDA (S: set[T1]): has_least?(S, r1))
  product_least_TCC2: OBLIGATION
    FORALL (r1: (pointed_directed_complete_partial_order?[T1]),
            r2: (pointed_directed_complete_partial_order?[T2])):
      has_least?[T1](fullset[T1], r1);

  % Subtype TCC generated (at line 68, column 62) for  fullset[T2]
      % expected type  S: (LAMBDA (S: set[T2]): has_least?(S, r2))
  product_least_TCC3: OBLIGATION
    FORALL (r1: (pointed_directed_complete_partial_order?[T1]),
            r2: (pointed_directed_complete_partial_order?[T2])):
      has_least?[T2](fullset[T2], r2);


body:
  %------------------------------------------------------------------------------
  % Pointwise Ordering in Disjoint Union types
  %
  %       Author: David Lester <dlester@cs.man.ac.uk> Manchester University
  %
  %       Version 1.0          03/30/06
  %------------------------------------------------------------------------------

  sum_orders[T1,T2:TYPE]: THEORY

  BEGIN

    r1:  VAR pred[[T1,T1]]
    r2:  VAR pred[[T2,T2]]
    x,y: VAR union[T1,T2]

    ; % syntax

    +(r1,r2)(x,y):bool = (inl?(x) AND inl?(y) AND r1(left(x), left(y))) OR
                         (inr?(x) AND inr?(y) AND r2(right(x),right(y)))

    sum_preserves_reflexive: JUDGEMENT
     +(r1:(reflexive?[T1]),r2:(reflexive?[T2]))
                                             HAS_TYPE (reflexive?[union[T1,T2]])

    sum_preserves_transitive: JUDGEMENT
     +(r1:(transitive?[T1]),r2:(transitive?[T2]))
                                             HAS_TYPE (transitive?[union[T1,T2]])

    sum_preserves_antisymmetric: JUDGEMENT
     +(r1:(antisymmetric?[T1]),r2:(antisymmetric?[T2]))
                                          HAS_TYPE (antisymmetric?[union[T1,T2]])

    sum_preserves_preorder: JUDGEMENT
     +(r1:(preorder?[T1]),r2:(preorder?[T2]))
                             HAS_TYPE (preorder?[union[T1,T2]])

    sum_preserves_partial_order: JUDGEMENT
     +(r1:(partial_order?[T1]),r2:(partial_order?[T2]))
                                          HAS_TYPE (partial_order?[union[T1,T2]])

    IMPORTING directed_orders[T1], directed_orders[T2],
              directed_orders[union[T1,T2]]

    sum_preserves_directed_complete: JUDGEMENT
     +(r1:(directed_complete?[T1]),r2:(directed_complete?[T2]))
                     HAS_TYPE (directed_complete?[union[T1,T2]])

    sum_preserves_directed_complete_partial_order: JUDGEMENT
     +(r1:(directed_complete_partial_order?[T1]),
       r2:(directed_complete_partial_order?[T2]))
                     HAS_TYPE (directed_complete_partial_order?[union[T1,T2]])

  END sum_orders

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

  % Judgement subtype TCC generated (at line 23, column 3) for  r1 + r2
      % expected type  (reflexive?[union[T1, T2]])
  sum_preserves_reflexive: OBLIGATION
    FORALL (r1: (reflexive?[T1]), r2: (reflexive?[T2])):
      reflexive?[union[T1, T2]](r1 + r2);

  % Judgement subtype TCC generated (at line 27, column 3) for  r1 + r2
      % expected type  (transitive?[union[T1, T2]])
  sum_preserves_transitive: OBLIGATION
    FORALL (r1: (transitive?[T1]), r2: (transitive?[T2])):
      transitive?[union[T1, T2]](r1 + r2);

  % Judgement subtype TCC generated (at line 31, column 3) for  r1 + r2
      % expected type  (antisymmetric?[union[T1, T2]])
  sum_preserves_antisymmetric: OBLIGATION
    FORALL (r1: (antisymmetric?[T1]), r2: (antisymmetric?[T2])):
      antisymmetric?[union[T1, T2]](r1 + r2);

  % Judgement subtype TCC generated (at line 35, column 3) for  r1 + r2
      % expected type  (preorder?[union[T1, T2]])
  sum_preserves_preorder: OBLIGATION
    FORALL (r1: (preorder?[T1]), r2: (preorder?[T2])):
      preorder?[union[T1, T2]](r1 + r2);

  % Judgement subtype TCC generated (at line 39, column 3) for  r1 + r2
      % expected type  (partial_order?[union[T1, T2]])
  sum_preserves_partial_order: OBLIGATION
    FORALL (r1: (partial_order?[T1]), r2: (partial_order?[T2])):
      partial_order?[union[T1, T2]](r1 + r2);

  % Judgement subtype TCC generated (at line 46, column 3) for  r1 + r2
      % expected type  (directed_complete?[union[T1, T2]])
  sum_preserves_directed_complete: OBLIGATION
    FORALL (r1: (directed_complete?[T1]), r2: (directed_complete?[T2])):
      directed_complete?[union[T1, T2]](r1 + r2);

  % Judgement subtype TCC generated (at line 50, column 3) for  r1 + r2
      % expected type  (directed_complete_partial_order?[union[T1, T2]])
  sum_preserves_directed_complete_partial_order: OBLIGATION
    FORALL (r1: (directed_complete_partial_order?[T1]),
            r2: (directed_complete_partial_order?[T2])):
      directed_complete_partial_order?[union[T1, T2]](r1 + r2);


body:
  %------------------------------------------------------------------------------
  % Properties of lift
  %
  %       Author: David Lester <dlester@cs.man.ac.uk> Manchester University
  %
  %       Version 1.0          03/30/06
  %------------------------------------------------------------------------------

  lift_props[T:TYPE]: THEORY

  BEGIN

    x,x1,x2: VAR T
    y,y1,y2: VAR lift[T]

    down_up:    LEMMA down(up(x)) = x
    up_down:    LEMMA up?(y) IMPLIES up(down(y)) = y
    down_equal: LEMMA up?(y1) & up?(y2) IMPLIES (down(y1) = down(y2) IFF y1 = y2)
    up_equal:   LEMMA up(x1) = up(x2) IFF x1 = x2

  END lift_props


body:
  partial_order_lift[T:TYPE]: THEORY

  BEGIN

    IMPORTING lift_props[T],
              directed_orders[T],
              directed_orders[lift[T]]

    <=: VAR (directed_complete_partial_order?[T])

    lift(<=):(pointed_directed_complete_partial_order?[lift[T]])
      = (LAMBDA (x,y:lift[T]):
          x = bottom OR (y /= bottom AND down(x) <= down(y)))

  END partial_order_lift

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

  % Subtype TCC generated (at line 13, column 44) for  x
      % expected type  (up?[T])
  lift_TCC1: OBLIGATION
    FORALL (<=: (directed_complete_partial_order?[T]), x, y: lift[T]):
      y /= bottom AND NOT x = bottom IMPLIES up?[T](x);

  % Subtype TCC generated (at line 13, column 55) for  y
      % expected type  (up?[T])
  lift_TCC2: OBLIGATION
    FORALL (<=: (directed_complete_partial_order?[T]), x, y: lift[T]):
      y /= bottom AND NOT x = bottom IMPLIES up?[T](y);

  % Subtype TCC generated (at line 12, column 7) for
      % (LAMBDA (x, y: lift[T]):
      %    x = bottom OR (y /= bottom AND down(x) <= down(y)))
      % expected type  (pointed_directed_complete_partial_order?[lift[T]])
  lift_TCC3: OBLIGATION
    FORALL (<=: (directed_complete_partial_order?[T])):
      pointed_directed_complete_partial_order?[lift[T]]
          (LAMBDA (x, y: lift[T]):
             x = bottom[T] OR (y /= bottom[T] AND down[T](x) <= down[T](y)));


body:
  %------------------------------------------------------------------------------
  % Properties of Lifted Orders
  %
  %       Author: David Lester <dlester@cs.man.ac.uk> Manchester University
  %
  % We define a lifting operator on relations, and show that this operation
  % preserves directed completeness and pointedness.
  %
  %       Version 1.0          03/30/06
  %------------------------------------------------------------------------------

  lifted_orders[T:TYPE]: THEORY

  BEGIN

    rel: VAR pred[[T,T]]
    x,y: VAR lift[T]

    IMPORTING lift_props[T]

    lift(rel)(x,y):bool = (NOT up?(x)) OR (up?(y) AND rel(down(x),down(y)))

    lift_preserves_reflexive: JUDGEMENT
     lift(r:(reflexive?[T])) HAS_TYPE (reflexive?[lift[T]])

    lift_preserves_transitive: JUDGEMENT
     lift(r:(transitive?[T])) HAS_TYPE (transitive?[lift[T]])

    lift_preserves_antisymmetric: JUDGEMENT
     lift(r:(antisymmetric?[T]))  HAS_TYPE (antisymmetric?[lift[T]])

    lift_preserves_preorder: JUDGEMENT
     lift(r:(preorder?[T])) HAS_TYPE (preorder?[lift[T]])

    lift_preserves_partial_order: JUDGEMENT
     lift(r:(partial_order?[T])) HAS_TYPE (partial_order?[lift[T]])

    IMPORTING directed_orders[T], directed_orders[lift[T]]

    lift_lub_emptyset: LEMMA lub(lift(rel))(emptyset[lift[T]]) = bottom

    lift_lub_bounded:  LEMMA FORALL (rel:(antisymmetric?[T]),
                                     S:(nonempty_least_bounded_above?(rel))):
         lub(lift(rel))(image[T,lift[T]](up,S)) = up(lub(rel)(S))

    lift_preserves_directed_complete: JUDGEMENT
     lift(r:(directed_complete?[T]))      HAS_TYPE (directed_complete?[lift[T]])

    lift_preserves_directed_complete_partial_order: JUDGEMENT
     lift(r:(directed_complete_partial_order?[T]))
                     HAS_TYPE (pointed_directed_complete_partial_order?[lift[T]])

  END lifted_orders

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

  % Judgement subtype TCC generated (at line 24, column 3) for  lift(r)
      % expected type  (reflexive?[lift[T]])
  lift_preserves_reflexive: OBLIGATION
    FORALL (r: (reflexive?[T])): reflexive?[lift[T]](lift(r));

  % Judgement subtype TCC generated (at line 27, column 3) for  lift(r)
      % expected type  (transitive?[lift[T]])
  lift_preserves_transitive: OBLIGATION
    FORALL (r: (transitive?[T])): transitive?[lift[T]](lift(r));

  % Judgement subtype TCC generated (at line 30, column 3) for  lift(r)
      % expected type  (antisymmetric?[lift[T]])
  lift_preserves_antisymmetric: OBLIGATION
    FORALL (r: (antisymmetric?[T])): antisymmetric?[lift[T]](lift(r));

  % Judgement subtype TCC generated (at line 33, column 3) for  lift(r)
      % expected type  (preorder?[lift[T]])
  lift_preserves_preorder: OBLIGATION
    FORALL (r: (preorder?[T])): preorder?[lift[T]](lift(r));

  % Judgement subtype TCC generated (at line 36, column 3) for  lift(r)
      % expected type  (partial_order?[lift[T]])
  lift_preserves_partial_order: OBLIGATION
    FORALL (r: (partial_order?[T])): partial_order?[lift[T]](lift(r));

  % Subtype TCC generated (at line 40, column 42) for  emptyset[lift[T]]
      % expected type  S:
                     %   (LAMBDA (S: set[lift[T]]):
                     %      least_bounded_above?(S, lift(rel)))
  lift_lub_emptyset_TCC1: OBLIGATION
    FORALL (rel: pred[[T, T]]):
      least_bounded_above?[lift[T]](emptyset[lift[T]], lift(rel));

  % Subtype TCC generated (at line 44, column 22) for
      % image[T, lift[T]](up, S)
      % expected type  S:
                     %   (LAMBDA (S: set[lift[T]]):
                     %      least_bounded_above?(S, lift(rel)))
  lift_lub_bounded_TCC1: OBLIGATION
    FORALL (rel: (antisymmetric?[T]),
            S: (nonempty_least_bounded_above?[T](rel))):
      least_bounded_above?[lift[T]](image[T, lift[T]](up[T], S), lift(rel));

  % Subtype TCC generated (at line 44, column 60) for  S
      % expected type  S: (LAMBDA (S: set[T]): least_bounded_above?(S, rel))
  lift_lub_bounded_TCC2: OBLIGATION
    FORALL (rel: (antisymmetric?[T]),
            S: (nonempty_least_bounded_above?[T](rel))):
      least_bounded_above?[T](S, rel);

  % Judgement subtype TCC generated (at line 47, column 3) for  lift(r)
      % expected type  (directed_complete?[lift[T]])
  lift_preserves_directed_complete: OBLIGATION
    FORALL (r: (directed_complete?[T])): directed_complete?[lift[T]](lift(r));

  % Judgement subtype TCC generated (at line 50, column 3) for  lift(r)
      % expected type  (pointed_directed_complete_partial_order?[lift[T]])
  lift_preserves_directed_complete_partial_order: OBLIGATION
    FORALL (r: (directed_complete_partial_order?[T])):
      pointed_directed_complete_partial_order?[lift[T]](lift(r));


body:
  % Properties and definitions for ordered sets.

  partial_order_props[T:TYPE,<=:(partial_order?[T])]: THEORY

  BEGIN

    x,y,z: VAR T
    S:     VAR set[T]
    XS:    VAR setofsets[T]

    partial_order_reflexive:     LEMMA x <= x
    partial_order_antisymmetric: LEMMA x <= y AND y <= x IMPLIES x = y
    partial_order_transitive:    LEMMA x <= y AND y <= z IMPLIES x <= z

    AUTO_REWRITE+  partial_order_reflexive
    AUTO_REWRITE+  partial_order_antisymmetric
    AUTO_REWRITE+  partial_order_transitive

    lower_set?(S)  :bool = FORALL x,y: member(x,S) AND y <= x IMPLIES member(y,S)
    upper_set?(S)  :bool = FORALL x,y: member(x,S) AND x <= y IMPLIES member(y,S)
    lower_sets?(XS):bool = every(lower_set?,XS)
    upper_sets?(XS):bool = every(upper_set?,XS)

    lower_set:  TYPE+ = (lower_set?)  CONTAINING emptyset[T]
    upper_set:  TYPE+ = (upper_set?)  CONTAINING emptyset[T]
    lower_sets: TYPE+ = (lower_sets?) CONTAINING emptyset[set[T]]
    upper_sets: TYPE+ = (upper_sets?) CONTAINING emptyset[set[T]]

    L,L1,L2:  VAR lower_set
    U,U1,U2:  VAR upper_set
    LS:       VAR lower_sets
    US:       VAR upper_sets

    complement_lower_set:  JUDGEMENT complement(L)  HAS_TYPE upper_set
    complement_upper_set:  JUDGEMENT complement(U)  HAS_TYPE lower_set
    Complement_lower_sets: JUDGEMENT Complement(LS) HAS_TYPE upper_sets
    Complement_upper_sets: JUDGEMENT Complement(US) HAS_TYPE lower_sets

    down(x): lower_set = {y | y <= x}
    up(x):   upper_set = {y | x <= y}

    down_subset: LEMMA x <= y IMPLIES subset?(down(x),down(y))
    up_subset:   LEMMA x <= y IMPLIES subset?(up(y),up(x))

    lower_set_def: LEMMA lower_set?(S) IFF S = Union(image(down,S))
    upper_set_def: LEMMA upper_set?(S) IFF S = Union(image(up,S))

    Union_lower_set:        JUDGEMENT Union(LS)           HAS_TYPE lower_set
    Union_upper_set:        JUDGEMENT Union(US)           HAS_TYPE upper_set
    Intersection_lower_set: JUDGEMENT Intersection(LS)    HAS_TYPE lower_set
    Intersection_upper_set: JUDGEMENT Intersection(US)    HAS_TYPE upper_set
    union_lower_set:        JUDGEMENT union(L1,L2)        HAS_TYPE lower_set
    union_upper_set:        JUDGEMENT union(U1,U2)        HAS_TYPE upper_set
    intersection_lower_set: JUDGEMENT intersection(L1,L2) HAS_TYPE lower_set
    intersection_upper_set: JUDGEMENT intersection(U1,U2) HAS_TYPE upper_set

  END partial_order_props

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

  % Subtype TCC generated (at line 24, column 47) for  emptyset[T]
      % expected type  lower_set
  lower_set_TCC1: OBLIGATION lower_set?(emptyset[T]);

  % Subtype TCC generated (at line 25, column 47) for  emptyset[T]
      % expected type  upper_set
  upper_set_TCC1: OBLIGATION upper_set?(emptyset[T]);

  % Subtype TCC generated (at line 26, column 47) for  emptyset[set[T]]
      % expected type  lower_sets
  lower_sets_TCC1: OBLIGATION lower_sets?(emptyset[set[T]]);

  % Subtype TCC generated (at line 27, column 47) for  emptyset[set[T]]
      % expected type  upper_sets
  upper_sets_TCC1: OBLIGATION upper_sets?(emptyset[set[T]]);

  % Judgement subtype TCC generated (at line 34, column 35) for  complement(L)
      % expected type  upper_set
  complement_lower_set: OBLIGATION FORALL (L): upper_set?(complement[T](L));

  % Judgement subtype TCC generated (at line 35, column 35) for  complement(U)
      % expected type  lower_set
  complement_upper_set: OBLIGATION FORALL (U): lower_set?(complement[T](U));

  % Judgement subtype TCC generated (at line 36, column 35) for  Complement(LS)
      % expected type  upper_sets
  Complement_lower_sets: OBLIGATION
    FORALL (LS): upper_sets?(Complement[T](LS));

  % Judgement subtype TCC generated (at line 37, column 35) for  Complement(US)
      % expected type  lower_sets
  Complement_upper_sets: OBLIGATION
    FORALL (US): lower_sets?(Complement[T](US));

  % Subtype TCC generated (at line 39, column 23) for  {y | y <= x}
      % expected type  lower_set
  down_TCC1: OBLIGATION FORALL (x: T): lower_set?({y | y <= x});

  % Subtype TCC generated (at line 40, column 23) for  {y | x <= y}
      % expected type  upper_set
  up_TCC1: OBLIGATION FORALL (x: T): upper_set?({y | x <= y});

  % Judgement subtype TCC generated (at line 48, column 36) for  Union(LS)
      % expected type  lower_set
  Union_lower_set: OBLIGATION FORALL (LS): lower_set?(Union[T](LS));

  % Judgement subtype TCC generated (at line 49, column 36) for  Union(US)
      % expected type  upper_set
  Union_upper_set: OBLIGATION FORALL (US): upper_set?(Union[T](US));

  % Judgement subtype TCC generated (at line 50, column 36) for
      % Intersection(LS)
      % expected type  lower_set
  Intersection_lower_set: OBLIGATION
    FORALL (LS): lower_set?(Intersection[T](LS));

  % Judgement subtype TCC generated (at line 51, column 36) for
      % Intersection(US)
      % expected type  upper_set
  Intersection_upper_set: OBLIGATION
    FORALL (US): upper_set?(Intersection[T](US));

  % Judgement subtype TCC generated (at line 52, column 36) for  union(L1, L2)
      % expected type  lower_set
  union_lower_set: OBLIGATION FORALL (L1, L2): lower_set?(union[T](L1, L2));

  % Judgement subtype TCC generated (at line 53, column 36) for  union(U1, U2)
      % expected type  upper_set
  union_upper_set: OBLIGATION FORALL (U1, U2): upper_set?(union[T](U1, U2));

  % Judgement subtype TCC generated (at line 54, column 36) for
      % intersection(L1, L2)
      % expected type  lower_set
  intersection_lower_set: OBLIGATION
    FORALL (L1, L2): lower_set?(intersection[T](L1, L2));

  % Judgement subtype TCC generated (at line 55, column 36) for
      % intersection(U1, U2)
      % expected type  upper_set
  intersection_upper_set: OBLIGATION
    FORALL (U1, U2): upper_set?(intersection[T](U1, U2));


body:
  %------------------------------------------------------------------------------
  %
  % These are properties of bounded partial orders. Because we're importing the
  % the partial order, it needn't clutter up the theories.
  %
  % We're defining the least_upper_bound and greatest_lower_bound operators
  % (lub(S) and glb(S) respectively) for all suitable sets S. Notice that they
  % needn't be nonempty.
  %
  %------------------------------------------------------------------------------

  bounded_order_props[T:TYPE,<=:(partial_order?[T])]: THEORY

  BEGIN

    IMPORTING sets[T], bounded_orders[T]

    x,y:   VAR T
    S,A,B: VAR set[T]

    above?(A,B): bool = FORALL (x:(B)): EXISTS (y:(A)): x <= y
    below?(A,B): bool = FORALL (x:(B)): EXISTS (y:(A)): y <= x

    lub_set?(S):bool = least_bounded_above?(<=)(S)

    singleton_is_lub_set: JUDGEMENT (singleton?) SUBTYPE_OF (lub_set?)

    SA,XA,YA: VAR (lub_set?)

    lub(SA): {x | bounded_orders[T].least_upper_bound?(x,SA,<=)}

    lub_rew: LEMMA lub(SA) = lub(<=)(SA)

    lub_singleton: LEMMA lub(singleton(x)) = x

    lub_lem: LEMMA lub(SA) = x IFF bounded_orders[T].least_upper_bound?(x,SA,<=)

    above_lub: LEMMA above?(XA,YA) IMPLIES lub(YA) <= lub(XA)

    glb_set?(S):bool = bounded_orders[T].greatest_bounded_below?(<=)(S)

    singleton_is_glb_set: JUDGEMENT (singleton?) SUBTYPE_OF (glb_set?)

    SB,XB,YB: VAR (glb_set?)

    glb(SB): {x | bounded_orders[T].greatest_lower_bound?(x,SB,<=)}

    glb_rew: LEMMA glb(SB) = glb(<=)(SB)

    glb_singleton: LEMMA glb(singleton(x)) = x

    glb_lem: LEMMA glb(SB) = x IFF
                             bounded_orders[T].greatest_lower_bound?(x,SB,<=)

    below_glb: LEMMA below?(XB,YB) IMPLIES glb(XB) <= glb(YB)

  END bounded_order_props

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

  % Judgement subtype TCC generated (at line 26, column 34) for  x
      % expected type  (lub_set?)
  singleton_is_lub_set: OBLIGATION FORALL (x: (singleton?)): lub_set?(x);

  % Existence TCC generated (at line 30, column 2) for
      % lub(SA): {x | bounded_orders[T].least_upper_bound?(x, SA, <=)}
  lub_TCC1: OBLIGATION
    EXISTS (x1:
              [SA: (lub_set?) ->
                 {x | bounded_orders[T].least_upper_bound?(x, SA, <=)}]):
      TRUE;

  % Subtype TCC generated (at line 32, column 35) for  SA
      % expected type  S: (LAMBDA (S: set[T]): least_bounded_above?(S, <=))
  lub_rew_TCC1: OBLIGATION
    FORALL (SA: (lub_set?)): least_bounded_above?[T](SA, <=);

  % Judgement subtype TCC generated (at line 42, column 34) for  x
      % expected type  (glb_set?)
  singleton_is_glb_set: OBLIGATION FORALL (x: (singleton?)): glb_set?(x);

  % Existence TCC generated (at line 46, column 2) for
      % glb(SB): {x | bounded_orders[T].greatest_lower_bound?(x, SB, <=)}
  glb_TCC1: OBLIGATION
    EXISTS (x1:
              [SB: (glb_set?) ->
                 {x | bounded_orders[T].greatest_lower_bound?(x, SB, <=)}]):
      TRUE;

  % Subtype TCC generated (at line 48, column 35) for  SB
      % expected type  S: (LAMBDA (S: set[T]): greatest_bounded_below?(S, <=))
  glb_rew_TCC1: OBLIGATION
    FORALL (SB: (glb_set?)): greatest_bounded_below?[T](SB, <=);


body:
  directed_order_props[T:TYPE,(IMPORTING directed_orders[T])
                       <=:(directed_complete_partial_order?[T])]: THEORY

  BEGIN

    IMPORTING partial_order_props[T,<=],
              bounded_order_props[T,<=]

    S: VAR (nonempty?[T])

    directed?(S):bool = directed?(<=)(S)

    directed: TYPE    = (directed?)

    x,y,z:   VAR T
    D:       VAR directed
    U:       VAR upper_set
    L,L1,L2: VAR lower_set

    directed_is_lub_set: JUDGEMENT directed     SUBTYPE_OF (lub_set?)
    directed_singleton:  JUDGEMENT singleton(x) HAS_TYPE directed

    intersection_directed_upper:
         LEMMA nonempty?(intersection(U,D)) IMPLIES directed?(intersection(U,D))

    split_directed_lower: LEMMA
         member(x,D) AND member(y,D) AND member(x,L) AND NOT member(y,L) IMPLIES
            EXISTS z: x <= z AND y <= z AND member(z,D) AND NOT member(z,L)

    directed_union_lower: LEMMA
      subset?(D,union(L1,L2)) IMPLIES (subset?(D,L1) OR subset?(D,L2))


  END directed_order_props

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

  % Judgement subtype TCC generated (at line 20, column 33) for  x
      % expected type  (lub_set?)
  directed_is_lub_set: OBLIGATION FORALL (x: directed): lub_set?[T, <=](x);

  % Judgement subtype TCC generated (at line 21, column 33) for  singleton(x)
      % expected type  directed
  directed_singleton: OBLIGATION FORALL (x): directed?(singleton[T](x));


body:
  % two rewrite rules that allow to do skolemization, i.e., to exchange
  % quantifiers. These rules come in handy when the outermost quantifier has
  % the wrong polarity.
  %
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Dec 2004

  skolemization[D, R: TYPE]: THEORY

  BEGIN

    d: VAR D
    r: VAR R
    f: VAR [D -> R]
    p: VAR pred[[D, R]]

    skolemize_exists: THEOREM
      (FORALL d: EXISTS r: p(d,r)) <=> (EXISTS f: FORALL d: p(d,f(d)))

    skolemize_forall: THEOREM
      (EXISTS d: FORALL r: p(d,r)) <=> (FORALL f: EXISTS d: p(d,f(d)))

  END skolemization


body:
  % proof that a function from an infinite domain to a finite range
  % has an infinite mono-chromatic subdomain
  %
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Dec 2004

  infinite_pigeonhole[D, R: TYPE]: THEORY

  BEGIN

  ASSUMING

    domain_infiniteness: ASSUMPTION NOT is_finite_type[D]

    range_finiteness: ASSUMPTION is_finite_type[R]

  ENDASSUMING

    CONVERSION+ singleton

    d: VAR D
    r: VAR R
    f: VAR [D -> R]

    % the domain of a function can be represented as the disjoint union of
    % the inverse images of every range element
    Union_inverse_image: LEMMA
      FORALL f: fullset[D] = IUnion[R, D](inverse_image(f))

    infinite_pigeonhole: LEMMA
      EXISTS r: is_infinite(inverse_image(f, r))

  END infinite_pigeonhole


body:
  % two rewrite rules missing in function_image
  %
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Jan 2005

  function_image_extra[D, R: TYPE]: THEORY

  BEGIN

    f: VAR [D -> R]
    x: VAR D
    X: VAR set[D]

    image_singleton: LEMMA
      image(f, singleton(x)) = singleton(f(x))

    image_add: LEMMA
      image(f, add(x, X)) = add(f(x), image(f, X))

  END function_image_extra


body:
  % if the type T is finite then all sets over T are finite sets.
  %
  % Author: Alfons Geser, National Institute of Aerospace
  % Date: Dec 2004

  finite_types[T: TYPE+]: THEORY

  BEGIN

  ASSUMING

    finite_type: ASSUMPTION is_finite_type[T]

  ENDASSUMING

    every_set_is_finite: JUDGEMENT
      set[T] SUBTYPE_OF finite_set[T]

    every_non_empty_set_is_non_empty_finite: JUDGEMENT
      (nonempty?[T]) SUBTYPE_OF non_empty_finite_set[T]

    fullset_is_nonempty_finite: JUDGEMENT
      fullset[T] HAS_TYPE non_empty_finite_set[T]

  END finite_types

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

  % Judgement subtype TCC generated (at line 17, column 4) for  x
      % expected type  finite_set[T]
  every_set_is_finite: OBLIGATION FORALL (x: set[T]): is_finite[T](x);

  % Judgement subtype TCC generated (at line 20, column 4) for  x
      % expected type  non_empty_finite_set[T]
  every_non_empty_set_is_non_empty_finite: OBLIGATION
    FORALL (x: (nonempty?[T])): NOT empty?[T](x);

  % Judgement subtype TCC generated (at line 23, column 4) for  fullset[T]
      % expected type  non_empty_finite_set[T]
  fullset_is_nonempty_finite: OBLIGATION NOT empty?[T](fullset[T]);


body:
  % some judgements about boundedness properties of sets
  %
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Oct 2004
  %
  % added preservation by set operators (other than remove). Alfons Geser, Jan 2005

  bounded_sets[T: TYPE, R: pred[[T, T]]]: THEORY

  BEGIN

    IMPORTING bounded_orders[T]

    s: VAR T
    Su: VAR (bounded_above?[T](R))
    Sl: VAR (bounded_below?[T](R))
    Sb: VAR (bounded?[T](R))

    least_bounded_above_is_bounded_above: JUDGEMENT
      (least_bounded_above?(R)) SUBTYPE_OF (bounded_above?(R))

    greatest_bounded_below_is_bounded_below: JUDGEMENT
      (greatest_bounded_below?(R)) SUBTYPE_OF (bounded_below?(R))

    bounded_is_bounded_above: JUDGEMENT
      (bounded?(R)) SUBTYPE_OF (bounded_above?(R))
   
    bounded_is_bounded_below: JUDGEMENT
      (bounded?(R)) SUBTYPE_OF (bounded_below?(R))
   
    tightly_bounded_is_bounded: JUDGEMENT
      (tightly_bounded?(R)) SUBTYPE_OF (bounded?(R))

    tightly_bounded_above: JUDGEMENT
      (tightly_bounded?(R)) SUBTYPE_OF (least_bounded_above?(R))
   
    tightly_bounded_below: JUDGEMENT
      (tightly_bounded?(R)) SUBTYPE_OF (greatest_bounded_below?(R))

    % preservation by set operators

    intersection1_preserves_bounded_above: JUDGEMENT
      intersection(Su, (S: set[T])) HAS_TYPE (bounded_above?[T](R))

    intersection2_preserves_bounded_above: JUDGEMENT
      intersection((S: set[T]), Su) HAS_TYPE (bounded_above?[T](R))

    difference_preserves_bounded_above: JUDGEMENT
      difference(Su: (bounded_above?[T](R)), S: set[T]) HAS_TYPE
        (bounded_above?[T](R))

    remove_preserves_bounded_above: JUDGEMENT
      remove[T](s, Su) HAS_TYPE (bounded_above?[T](R))

    intersection1_preserves_bounded_below: JUDGEMENT
      intersection(Sl, (S: set[T])) HAS_TYPE (bounded_below?[T](R))

    intersection2_preserves_bounded_below: JUDGEMENT
      intersection((S: set[T]), Sl) HAS_TYPE (bounded_below?[T](R))

    difference_preserves_bounded_below: JUDGEMENT
      difference(Sl, (S: set[T])) HAS_TYPE
        (bounded_below?[T](R))

    remove_preserves_bounded_below: JUDGEMENT
      remove[T](s, Sl) HAS_TYPE (bounded_below?[T](R))

    intersection1_preserves_bounded: JUDGEMENT
      intersection(Sb, (S: set[T])) HAS_TYPE (bounded?[T](R))

    intersection2_preserves_bounded: JUDGEMENT
      intersection((S: set[T]), Sb) HAS_TYPE (bounded?[T](R))

    difference_preserves_bounded: JUDGEMENT
      difference(Sb, (S: set[T])) HAS_TYPE (bounded?[T](R))

    remove_preserves_bounded: JUDGEMENT
      remove[T](s, Sb) HAS_TYPE (bounded?[T](R))

  END bounded_sets

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

  % Judgement subtype TCC generated (at line 20, column 4) for  x
      % expected type  (LAMBDA (S: set[T]): bounded_above?(S, R))
  least_bounded_above_is_bounded_above: OBLIGATION
    FORALL (x: (LAMBDA (S: set[T]): least_bounded_above?(S, R))):
      bounded_above?[T](x, R);

  % Judgement subtype TCC generated (at line 23, column 4) for  x
      % expected type  (LAMBDA (S: set[T]): bounded_below?(S, R))
  greatest_bounded_below_is_bounded_below: OBLIGATION
    FORALL (x: (LAMBDA (S: set[T]): greatest_bounded_below?(S, R))):
      bounded_below?[T](x, R);

  % Judgement subtype TCC generated (at line 26, column 4) for  x
      % expected type  (LAMBDA (S: set[T]): bounded_above?(S, R))
  bounded_is_bounded_above: OBLIGATION
    FORALL (x: (LAMBDA (S: set[T]): bounded?(S, R))): bounded_above?[T](x, R);

  % Judgement subtype TCC generated (at line 29, column 4) for  x
      % expected type  (LAMBDA (S: set[T]): bounded_below?(S, R))
  bounded_is_bounded_below: OBLIGATION
    FORALL (x: (LAMBDA (S: set[T]): bounded?(S, R))): bounded_below?[T](x, R);

  % Judgement subtype TCC generated (at line 32, column 4) for  x
      % expected type  (LAMBDA (S: set[T]): bounded?(S, R))
  tightly_bounded_is_bounded: OBLIGATION
    FORALL (x: (LAMBDA (S: set[T]): tightly_bounded?(S, R))):
      bounded?[T](x, R);

  % Judgement subtype TCC generated (at line 35, column 4) for  x
      % expected type  (LAMBDA (S: set[T]): least_bounded_above?(S, R))
  tightly_bounded_above: OBLIGATION
    FORALL (x: (LAMBDA (S: set[T]): tightly_bounded?(S, R))):
      least_bounded_above?[T](x, R);

  % Judgement subtype TCC generated (at line 38, column 4) for  x
      % expected type  (LAMBDA (S: set[T]): greatest_bounded_below?(S, R))
  tightly_bounded_below: OBLIGATION
    FORALL (x: (LAMBDA (S: set[T]): tightly_bounded?(S, R))):
      greatest_bounded_below?[T](x, R);

  % Judgement subtype TCC generated (at line 43, column 4) for
      % intersection(Su, S)
      % expected type  (LAMBDA (S: set[T]): bounded_above?(S, R))
  intersection1_preserves_bounded_above: OBLIGATION
    FORALL ((S: set[T]), Su): bounded_above?[T](intersection[T](Su, S), R);

  % Judgement subtype TCC generated (at line 46, column 4) for
      % intersection(S, Su)
      % expected type  (LAMBDA (S: set[T]): bounded_above?(S, R))
  intersection2_preserves_bounded_above: OBLIGATION
    FORALL ((S: set[T]), Su): bounded_above?[T](intersection[T](S, Su), R);

  % Judgement subtype TCC generated (at line 49, column 4) for
      % difference(Su, S)
      % expected type  (LAMBDA (S: set[T]): bounded_above?(S, R))
  difference_preserves_bounded_above: OBLIGATION
    FORALL (S: set[T], Su: (LAMBDA (S: set[T]): bounded_above?(S, R))):
      bounded_above?[T](difference[T](Su, S), R);

  % Judgement subtype TCC generated (at line 53, column 4) for
      % remove[T](s, Su)
      % expected type  (LAMBDA (S: set[T]): bounded_above?(S, R))
  remove_preserves_bounded_above: OBLIGATION
    FORALL (Su, s): bounded_above?[T](remove[T](s, Su), R);

  % Judgement subtype TCC generated (at line 56, column 4) for
      % intersection(Sl, S)
      % expected type  (LAMBDA (S: set[T]): bounded_below?(S, R))
  intersection1_preserves_bounded_below: OBLIGATION
    FORALL ((S: set[T]), Sl): bounded_below?[T](intersection[T](Sl, S), R);

  % Judgement subtype TCC generated (at line 59, column 4) for
      % intersection(S, Sl)
      % expected type  (LAMBDA (S: set[T]): bounded_below?(S, R))
  intersection2_preserves_bounded_below: OBLIGATION
    FORALL ((S: set[T]), Sl): bounded_below?[T](intersection[T](S, Sl), R);

  % Judgement subtype TCC generated (at line 62, column 4) for
      % difference(Sl, S)
      % expected type  (LAMBDA (S: set[T]): bounded_below?(S, R))
  difference_preserves_bounded_below: OBLIGATION
    FORALL ((S: set[T]), Sl): bounded_below?[T](difference[T](Sl, S), R);

  % Judgement subtype TCC generated (at line 66, column 4) for
      % remove[T](s, Sl)
      % expected type  (LAMBDA (S: set[T]): bounded_below?(S, R))
  remove_preserves_bounded_below: OBLIGATION
    FORALL (Sl, s): bounded_below?[T](remove[T](s, Sl), R);

  % Judgement subtype TCC generated (at line 69, column 4) for
      % intersection(Sb, S)
      % expected type  (LAMBDA (S: set[T]): bounded?(S, R))
  intersection1_preserves_bounded: OBLIGATION
    FORALL ((S: set[T]), Sb): bounded?[T](intersection[T](Sb, S), R);

  % Judgement subtype TCC generated (at line 72, column 4) for
      % intersection(S, Sb)
      % expected type  (LAMBDA (S: set[T]): bounded?(S, R))
  intersection2_preserves_bounded: OBLIGATION
    FORALL ((S: set[T]), Sb): bounded?[T](intersection[T](S, Sb), R);

  % Judgement subtype TCC generated (at line 75, column 4) for
      % difference(Sb, S)
      % expected type  (LAMBDA (S: set[T]): bounded?(S, R))
  difference_preserves_bounded: OBLIGATION
    FORALL ((S: set[T]), Sb): bounded?[T](difference[T](Sb, S), R);

  % Judgement subtype TCC generated (at line 78, column 4) for
      % remove[T](s, Sb)
      % expected type  (LAMBDA (S: set[T]): bounded?(S, R))
  remove_preserves_bounded: OBLIGATION
    FORALL (Sb, s): bounded?[T](remove[T](s, Sb), R);


body:
  % upper semilattices; binary lub function
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Oct 2004

  upper_semilattices[
    T: TYPE,
    (IMPORTING bounded_orders[T])
    <=: (upper_semilattice?[T])
  ]: THEORY

  BEGIN

    IMPORTING bounded_sets[T, <=]

    s, t, u, t1, t2: VAR T
    S, S1, S2: VAR (least_bounded_above?[T](<=))

    finite_set_is_least_bounded_above: JUDGEMENT
      non_empty_finite_set[T] SUBTYPE_OF (least_bounded_above?(<=))

    least_upper_bound_singleton: LEMMA
      least_upper_bound?[T](t, singleton(t), <=)

    lub_singleton: LEMMA
      lub(<=)(singleton(t)) = t

    lub(t, u): T = lub[T](<=)(union(singleton(t), singleton(u)))

    lub_le: LEMMA lub(t, u) <= s IFF t <= s AND u <= s
    le_lub_1: LEMMA s <= t => s <= lub(t, u)
    le_lub_2: LEMMA s <= u => s <= lub(t, u)

    union_preserves_bounded_above: JUDGEMENT
      union(S1, S2: (bounded_above?[T](<=))) HAS_TYPE (bounded_above?[T](<=))

    add_preserves_bounded_above: JUDGEMENT
      add(s: T, S: (bounded_above?[T](<=))) HAS_TYPE (bounded_above?[T](<=))

    least_upper_bound_union: LEMMA
      least_upper_bound?[T](t1, S1, <=) &
      least_upper_bound?[T](t2, S2, <=) =>
        least_upper_bound?[T](lub(t1, t2), union(S1, S2), <=)

    least_upper_bound_add: LEMMA
      least_upper_bound?[T](t, S, <=) =>
        least_upper_bound?[T](lub(t, s), add(s, S), <=)

    union_preserves_least_bounded_above: JUDGEMENT
      union(S1, S2) HAS_TYPE (least_bounded_above?[T](<=))

    add_preserves_least_bounded_above: JUDGEMENT
      add(s, S) HAS_TYPE (least_bounded_above?[T](<=))

    lub_union: LEMMA
      lub[T](<=)(union(S1, S2)) = lub(lub[T](<=)(S1), lub[T](<=)(S2))

    lub_add: LEMMA
      lub[T](<=)(add(s, S)) = lub(lub[T](<=)(S), s)

  END upper_semilattices

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

  % Judgement subtype TCC generated (at line 19, column 4) for  x
      % expected type  (LAMBDA (S: set[T]): least_bounded_above?(S, <=))
  finite_set_is_least_bounded_above: OBLIGATION
    FORALL (x: non_empty_finite_set[T]): least_bounded_above?[T](x, <=);

  % Judgement subtype TCC generated (at line 34, column 4) for  union(S1, S2)
      % expected type  (LAMBDA (S: set[T]): bounded_above?(S, <=))
  union_preserves_bounded_above: OBLIGATION
    FORALL (S1, S2: (LAMBDA (S: set[T]): bounded_above?(S, <=))):
      bounded_above?[T](union[T](S1, S2), <=);

  % Judgement subtype TCC generated (at line 37, column 4) for  add(s, S)
      % expected type  (LAMBDA (S: set[T]): bounded_above?(S, <=))
  add_preserves_bounded_above: OBLIGATION
    FORALL (S: (LAMBDA (S: set[T]): bounded_above?(S, <=)), s: T):
      bounded_above?[T](add[T](s, S), <=);

  % Judgement subtype TCC generated (at line 49, column 4) for  union(S1, S2)
      % expected type  (LAMBDA (S: set[T]): least_bounded_above?(S, <=))
  union_preserves_least_bounded_above: OBLIGATION
    FORALL (S1, S2): least_bounded_above?[T](union[T](S1, S2), <=);

  % Judgement subtype TCC generated (at line 52, column 4) for  add(s, S)
      % expected type  (LAMBDA (S: set[T]): least_bounded_above?(S, <=))
  add_preserves_least_bounded_above: OBLIGATION
    FORALL (S, s): least_bounded_above?[T](add[T](s, S), <=);


body:
  % lower semilattices; binary glb function
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Oct 2004 / Jan 2005

  lower_semilattices[
    T: TYPE,
    (IMPORTING bounded_orders[T])
    <=: (lower_semilattice?[T])
  ]: THEORY

  BEGIN

    IMPORTING bounded_sets[T, <=]

    s, t, u, t1, t2: VAR T
    S, S1, S2: VAR (greatest_bounded_below?[T](<=))

    finite_set_is_greatest_bounded_below: JUDGEMENT
      non_empty_finite_set[T] SUBTYPE_OF (greatest_bounded_below?(<=))

    greatest_lower_bound_singleton: LEMMA
      greatest_lower_bound?[T](t, singleton(t), <=)

    glb_singleton: LEMMA
      glb(<=)(singleton(t)) = t

    glb(t, u): T = glb[T](<=)(union(singleton(t), singleton(u)))

    le_glb: LEMMA s <= glb(t, u) IFF s <= t AND s <= u
    glb_le_1: LEMMA t <= s => glb(t, u) <= s
    glb_le_2: LEMMA u <= s => glb(t, u) <= s

    union_preserves_bounded_below: JUDGEMENT
      union(S1, S2: (bounded_below?[T](<=))) HAS_TYPE (bounded_below?[T](<=))

    add_preserves_bounded_below: JUDGEMENT
      add(s: T, S: (bounded_below?[T](<=))) HAS_TYPE (bounded_below?[T](<=))

    greatest_lower_bound_union: LEMMA
      greatest_lower_bound?[T](t1, S1, <=) &
      greatest_lower_bound?[T](t2, S2, <=) =>
        greatest_lower_bound?[T](glb(t1, t2), union(S1, S2), <=)

    greatest_lower_bound_add: LEMMA
      greatest_lower_bound?[T](t, S, <=) =>
        greatest_lower_bound?[T](glb(t, s), add(s, S), <=)

    union_preserves_greatest_bounded_below: JUDGEMENT
      union(S1, S2) HAS_TYPE (greatest_bounded_below?[T](<=))

    add_preserves_greatest_bounded_below: JUDGEMENT
      add(s, S) HAS_TYPE (greatest_bounded_below?[T](<=))

    glb_union: LEMMA
      glb[T](<=)(union(S1, S2)) = glb(glb[T](<=)(S1), glb[T](<=)(S2))

    glb_add: LEMMA
      glb[T](<=)(add(s, S)) = glb(glb[T](<=)(S), s)

  END lower_semilattices

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

  % Judgement subtype TCC generated (at line 19, column 4) for  x
      % expected type  (LAMBDA (S: set[T]): greatest_bounded_below?(S, <=))
  finite_set_is_greatest_bounded_below: OBLIGATION
    FORALL (x: non_empty_finite_set[T]): greatest_bounded_below?[T](x, <=);

  % Judgement subtype TCC generated (at line 34, column 4) for  union(S1, S2)
      % expected type  (LAMBDA (S: set[T]): bounded_below?(S, <=))
  union_preserves_bounded_below: OBLIGATION
    FORALL (S1, S2: (LAMBDA (S: set[T]): bounded_below?(S, <=))):
      bounded_below?[T](union[T](S1, S2), <=);

  % Judgement subtype TCC generated (at line 37, column 4) for  add(s, S)
      % expected type  (LAMBDA (S: set[T]): bounded_below?(S, <=))
  add_preserves_bounded_below: OBLIGATION
    FORALL (S: (LAMBDA (S: set[T]): bounded_below?(S, <=)), s: T):
      bounded_below?[T](add[T](s, S), <=);

  % Judgement subtype TCC generated (at line 49, column 4) for  union(S1, S2)
      % expected type  (LAMBDA (S: set[T]): greatest_bounded_below?(S, <=))
  union_preserves_greatest_bounded_below: OBLIGATION
    FORALL (S1, S2): greatest_bounded_below?[T](union[T](S1, S2), <=);

  % Judgement subtype TCC generated (at line 52, column 4) for  add(s, S)
      % expected type  (LAMBDA (S: set[T]): greatest_bounded_below?(S, <=))
  add_preserves_greatest_bounded_below: OBLIGATION
    FORALL (S, s): greatest_bounded_below?[T](add[T](s, S), <=);


body:
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Oct 2004
  %
  % add_preserves_tightly_bounded and union_preserves_tightly_bounded added
  % 13 Jan 2005 by Jerry James (jamesj@acm.org)

  lattices[
    T: TYPE,
    (IMPORTING bounded_orders[T])
    <=: (lattice?[T])
  ]: THEORY

  BEGIN

    IMPORTING
      lower_semilattices[T, <=],
      upper_semilattices[T, <=]

    t: VAR T
    tb, tb2: VAR (tightly_bounded?(<=))

    finite_set_is_tightly_bounded: JUDGEMENT
      non_empty_finite_set[T] SUBTYPE_OF (tightly_bounded?(<=))

    add_preserves_tightly_bounded: JUDGEMENT
      add(t, tb) HAS_TYPE (tightly_bounded?(<=))

    union_preserves_tightly_bounded: JUDGEMENT
      union(tb, tb2) HAS_TYPE (tightly_bounded?(<=))

  END lattices

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

  % Judgement subtype TCC generated (at line 23, column 4) for  x
      % expected type  (LAMBDA (S: set[T]): tightly_bounded?(S, <=))
  finite_set_is_tightly_bounded: OBLIGATION
    FORALL (x: non_empty_finite_set[T]): tightly_bounded?[T](x, <=);

  % Judgement subtype TCC generated (at line 26, column 4) for  add(t, tb)
      % expected type  (LAMBDA (S: set[T]): tightly_bounded?(S, <=))
  add_preserves_tightly_bounded: OBLIGATION
    FORALL (t, tb): tightly_bounded?[T](add[T](t, tb), <=);

  % Judgement subtype TCC generated (at line 29, column 4) for  union(tb, tb2)
      % expected type  (LAMBDA (S: set[T]): tightly_bounded?(S, <=))
  union_preserves_tightly_bounded: OBLIGATION
    FORALL (tb, tb2): tightly_bounded?[T](union[T](tb, tb2), <=);


body:
  % lattices formed by a total order.
  %
  % Author: Alfons Geser (geser@nianet.org), National Institute of Aerospace
  % Date: Dec 2004
  %
  % 8 Feb 2005, Jerry James added singleton_has_X, union_preserves_has_X,
  %   add_preserves_has_X, X_singleton, X_union, and X_add, where
  %   X ranges over {greatest, least}.

  total_lattices[T: TYPE, <=: (total_order?[T])]: THEORY

  BEGIN

    IMPORTING minmax_orders[T], lattices[T, <=]

    G, G1, G2: VAR (has_greatest?(<=))
    L, L1, L2: VAR (has_least?(<=))
    t: VAR T

    singleton_has_greatest: JUDGEMENT
      singleton(t) HAS_TYPE (has_greatest?(<=))

    union_preserves_has_greatest: JUDGEMENT
      union(G1, G2) HAS_TYPE (has_greatest?(<=))

    add_preserves_has_greatest: JUDGEMENT
      add(t, G) HAS_TYPE (has_greatest?(<=))

    greatest_singleton: LEMMA FORALL t: greatest(<=)(singleton(t)) = t

    greatest_union: LEMMA
      FORALL G1, G2:
        greatest(<=)(union(G1, G2)) =
         IF greatest(<=)(G1) <= greatest(<=)(G2) THEN greatest(<=)(G2)
         ELSE greatest(<=)(G1)
         ENDIF

    greatest_add: LEMMA
      FORALL G, t:
        greatest(<=)(add(t, G)) =
         IF greatest(<=)(G) <= t THEN t ELSE greatest(<=)(G) ENDIF

    singleton_has_least: JUDGEMENT singleton(t) HAS_TYPE (has_least?(<=))

    union_preserves_has_least: JUDGEMENT
      union(L1, L2) HAS_TYPE (has_least?(<=))

    add_preserves_has_least: JUDGEMENT add(t, L) HAS_TYPE (has_least?(<=))

    least_singleton: LEMMA FORALL t: least(<=)(singleton(t)) = t

    least_union: LEMMA
      FORALL L1, L2:
        least(<=)(union(L1, L2)) =
         IF least(<=)(L1) <= least(<=)(L2) THEN least(<=)(L1)
         ELSE least(<=)(L2)
         ENDIF

    least_add: LEMMA
      FORALL L, t:
        least(<=)(add(t, L)) =
         IF least(<=)(L) <= t THEN least(<=)(L) ELSE t ENDIF

  END total_lattices

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

  % Judgement subtype TCC generated (at line 21, column 4) for  singleton(t)
      % expected type  (LAMBDA (S: set[T]): has_greatest?(S, <=))
  singleton_has_greatest: OBLIGATION
    FORALL (t): has_greatest?[T](singleton[T](t), <=);

  % Judgement subtype TCC generated (at line 24, column 4) for  union(G1, G2)
      % expected type  (LAMBDA (S: set[T]): has_greatest?(S, <=))
  union_preserves_has_greatest: OBLIGATION
    FORALL (G1, G2): has_greatest?[T](union[T](G1, G2), <=);

  % Judgement subtype TCC generated (at line 27, column 4) for  add(t, G)
      % expected type  (LAMBDA (S: set[T]): has_greatest?(S, <=))
  add_preserves_has_greatest: OBLIGATION
    FORALL (G, t): has_greatest?[T](add[T](t, G), <=);

  % Judgement subtype TCC generated (at line 43, column 33) for  singleton(t)
      % expected type  (LAMBDA (S: set[T]): has_least?(S, <=))
  singleton_has_least: OBLIGATION
    FORALL (t): has_least?[T](singleton[T](t), <=);

  % Judgement subtype TCC generated (at line 46, column 4) for  union(L1, L2)
      % expected type  (LAMBDA (S: set[T]): has_least?(S, <=))
  union_preserves_has_least: OBLIGATION
    FORALL (L1, L2): has_least?[T](union[T](L1, L2), <=);

  % Judgement subtype TCC generated (at line 48, column 37) for  add(t, L)
      % expected type  (LAMBDA (S: set[T]): has_least?(S, <=))
  add_preserves_has_least: OBLIGATION
    FORALL (L, t): has_least?[T](add[T](t, L), <=);


body:
  % orders on a finite type have special properties:
  % e.g., every lattice is complete; every strict-order is well-founded.
  %
  % Author: Alfons Geser, National Institute of Aerospace
  % Date: Dec 2004/Jan 2005

  finite_orders[T: TYPE+]: THEORY

  BEGIN

  ASSUMING

    finite_type: ASSUMPTION is_finite_type[T]

  ENDASSUMING

    IMPORTING bounded_orders[T], finite_types[T]

    R: VAR pred[[T, T]]
    S: VAR (nonempty?[T])  % used in proofs

    % lattice properties

    finite_lower_semilattice_is_complete: LEMMA
      greatest_bounded_below?(R)(emptyset) & lower_semilattice?(R) =>
        complete_lower_semilattice?(R)

    finite_upper_semilattice_is_complete: LEMMA
      least_bounded_above?(R)(emptyset) & upper_semilattice?(R) =>
        complete_upper_semilattice?(R)

    finite_lattice_is_complete: JUDGEMENT
      (lattice?) SUBTYPE_OF (complete_lattice?)

    % well-foundedness properties

    finite_strict_order_is_well_founded: JUDGEMENT
      (strict_order?) SUBTYPE_OF (well_founded?[T])

    finite_strict_total_order_is_well_ordered: JUDGEMENT
      (strict_total_order?) SUBTYPE_OF (well_ordered?[T])

  END finite_orders

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

  % Assuming TCC generated (at line 17, column 31) for  finite_types[T]
      % generated from assumption finite_types.finite_type
  IMP_finite_types_TCC1: OBLIGATION is_finite_type[T];

  % Judgement subtype TCC generated (at line 33, column 4) for  x
      % expected type  (complete_lattice?)
  finite_lattice_is_complete: OBLIGATION
    FORALL (x: (lattice?)): complete_lattice?[T](x);

  % Judgement subtype TCC generated (at line 38, column 4) for  x
      % expected type  (well_founded?[T])
  finite_strict_order_is_well_founded: OBLIGATION
    FORALL (x: (strict_order?)): well_founded?[T](x);

  % Judgement subtype TCC generated (at line 41, column 4) for  x
      % expected type  (well_ordered?[T])
  finite_strict_total_order_is_well_ordered: OBLIGATION
    FORALL (x: (strict_total_order?)): well_ordered?[T](x);


body:
  finite_total_orders[T: TYPE+, <=: (total_order?[T])]: THEORY

  BEGIN

  ASSUMING

    finite_type: ASSUMPTION is_finite_type[T]

  ENDASSUMING

    IMPORTING finite_orders[T], total_lattices[T, <=]

  % subsumed :)
  %   leq_is_a_complete_lattice: JUDGEMENT
  %     <= HAS_TYPE (complete_lattice?[T])

  END finite_total_orders

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

  % Assuming TCC generated (at line 11, column 12) for  finite_orders[T]
      % generated from assumption finite_orders.finite_type
  IMP_finite_orders_TCC1: OBLIGATION is_finite_type[T];


body:
  % the booleans are a finite type.
  % this theory is useful to discharge TCCs from finiteness proofs for
  % composed types such as set[T] = [T -> bool]
  %
  % Author: Alfons Geser, National Institute of Aerospace
  % Date: Jan 2005

  booleans_are_finite: THEORY

  BEGIN

    bool_is_finite_type: LEMMA
      is_finite_type[bool]

    implies_is_total_order: JUDGEMENT
      IMPLIES HAS_TYPE (total_order?[bool])

    IMPORTING finite_types[bool], finite_total_orders[bool, IMPLIES]

  END booleans_are_finite

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

  % Judgement subtype TCC generated (at line 16, column 4) for  IMPLIES
      % expected type  (total_order?[bool])
  implies_is_total_order: OBLIGATION total_order?[bool](IMPLIES);

  % Assuming TCC generated (at line 18, column 12) for  finite_types[bool]
      % generated from assumption finite_types.finite_type
  IMP_finite_types_TCC1: OBLIGATION is_finite_type[bool];


body:
  %-------------------------------------------------------------------------
  %
  %  Subset chains: sets that are totally ordered by the subset relation.
  %
  %  For PVS version 3.2.  January 14, 2005
  %  ---------------------------------------------------------------------
  %      Author: Jerry James (jamesj@acm.org), University of Kansas
  %
  %  EXPORTS
  %  -------
  %  prelude: orders[chain], orders[set[T]], sets[set[T]], sets_lemmas[T]
  %  orders: chain[set[T], subset?], subset_chain[T]
  %
  %-------------------------------------------------------------------------
  subset_chain[T: TYPE]: THEORY
   BEGIN

    IMPORTING sets_lemmas[T], chain[set[T], subset?]

    C: VAR chain

    subset_chain_min: THEOREM FORALL C, (S: (C)): subset?(Intersection(C), S)

    subset_chain_intersection: THEOREM
      FORALL C: maximal_chain?(C) => member(Intersection(C), C)

   END subset_chain


body:
  %-------------------------------------------------------------------------
  %
  %  Chain chains: chains of Ts ordered by inclusion.
  %
  %  For PVS version 3.2.  January 14, 2005
  %  ---------------------------------------------------------------------
  %      Author: Jerry James (jamesj@acm.org), University of Kansas
  %
  %  EXPORTS
  %  -------
  %  prelude: finite_sets[subchain], orders[chain_chain], orders[subchain],
  %    orders[T], relations[subchain], sets[subchain], sets[T]
  %  orders: bounded_orders[subchain], chain[subchain,chain_incl],
  %    chain[T,<=], chain_chain[T,<=], relations_extra[subchain]
  %
  %-------------------------------------------------------------------------
  chain_chain[T: TYPE, <=: (partial_order?[T])]: THEORY
   BEGIN

    % ==========================================================================
    % The lower level chains
    % ==========================================================================

    IMPORTING chain[T, <=]

    subchain: TYPE+ = chain[T, <=]

    subc1, subc2: VAR subchain


    % ==========================================================================
    % The higher level chains
    % ==========================================================================

    chain_incl(subc1, subc2): bool = subset?(subc1, subc2)

    chain_incl_partial_order: JUDGEMENT
      chain_incl HAS_TYPE (partial_order?[subchain])

    IMPORTING bounded_orders[subchain], chain[subchain, chain_incl]

    chain_chain: TYPE+ = chain[subchain, chain_incl]

    C: VAR chain_chain

    chain_union(C): subchain = Union(extend[set[T], subchain, bool, FALSE](C))

    chain_union_upper_bound: LEMMA
      FORALL (C: chain_chain):
        bounded_orders.upper_bound?(chain_union(C), C, chain_incl)

   END chain_chain

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

  % Judgement subtype TCC generated (at line 38, column 4) for  chain_incl
      % expected type  (partial_order?[subchain])
  chain_incl_partial_order: OBLIGATION partial_order?[subchain](chain_incl);

  % Subtype TCC generated (at line 46, column 29) for
      % Union(extend[set[T], subchain, bool, FALSE](C))
      % expected type  subchain
  chain_union_TCC1: OBLIGATION
    FORALL (C: chain_chain):
      chain?[T, <=](Union[T](extend[set[T], subchain, bool, FALSE](C)));


body:
  %-------------------------------------------------------------------------
  %
  %  Zorn's lemma: if every chain in a partially ordered set has an upper
  %  bound, then the set has a maximal element.
  %
  %  For PVS version 3.2.  January 14, 2005
  %  ---------------------------------------------------------------------
  %      Author: Jerry James (jamesj@acm.org), University of Kansas
  %
  %  EXPORTS
  %  -------
  %  prelude: orders[T], relations[T], sets[T]
  %  orders: bounded_orders[T], chain[T,<=], minmax_orders[T],
  %    relations_extra[T], zorn[T,<=]
  %
  %-------------------------------------------------------------------------
  zorn[T: TYPE, <=: (partial_order?[T])]: THEORY

   % Hide the technical lemmas and supporting theories from public view
   EXPORTING zorn WITH orders[T], relations[T], sets[T], bounded_orders[T],
     minmax_orders[T], relations_extra[T], chain[T, <=]

   BEGIN

    IMPORTING chain_chain[T, <=], subset_chain[T], ordered_subset[T]
    IMPORTING minmax_orders[T], minmax_orders[subchain]

    t, r: VAR T
    ch, ch1, ch2: VAR subchain
    CH: VAR chain_chain

    % An alternative characterization of a maximal element
    maximal_upto_subset: LEMMA
      FORALL t:
        (FORALL r: subset?(upto(t, <=), upto(r, <=)) IMPLIES t = r) IFF
         maximal?[T](t, fullset[T], <=)

    % If every chain of Ts is bounded above, then for each chain of Ts, there
    % exists some T that is that bound; its upto set then includes the chain
    bounded_chain_upto: LEMMA
      (FORALL ch: bounded_above?[T](ch, <=)) IMPLIES
       (FORALL ch: EXISTS t: subset?(ch, upto(t, <=)))

    % The set of all Ts that, when added to ch, produce a (longer) chain
    add_set(ch): set[T] =
        {t | NOT member(t, ch) AND chain?[T, <=](add(t, ch))}

    % Given a maximal chain, return it; otherwise, increase the length of the
    % chain by one
    succ(ch): subchain =
        IF empty?(add_set(ch)) THEN ch ELSE add(choose(add_set(ch)), ch) ENDIF

    % If the add set is empty, then succ doesn't add anything
    empty_succ: LEMMA FORALL ch: empty?(add_set(ch)) IFF ch = succ(ch)

    % If the add set is empty, then the chain is maximal
    maximal_chain_add_set: LEMMA
      FORALL ch:
        empty?(add_set(ch)) IFF
         maximal?[subchain[T, <=]](ch, fullset[subchain], chain_incl)

    % A tower is a set of chains of Ts containing the emptyset, and closed
    % under succ and chain_union
    tower?(tow: set[subchain]): bool =
        member(emptyset[T], tow) AND
         (FORALL (ch: (tow)): member(succ(ch), tow)) AND
          (FORALL CH:
             (FORALL (ch: (CH)): member(ch, tow)) IMPLIES
              member(chain_union(CH), tow))

    % The intersection of a set of towers is also a tower
    tower_intersection: LEMMA
      FORALL (Tow: set[set[subchain]]):
        (FORALL (t: (Tow)): tower?(t)) IMPLIES
         tower?(Intersection[subchain](Tow))

    % The smallest tower
    T0: (tower?) = Intersection[subchain]({CH: set[subchain] | tower?(CH)})

    % An element of T0 is T0_comparable? if it is related by set inclusion to
    % all other elements of T0
    T0_comparable?(ch1: (T0)): bool =
        FORALL (ch2: (T0)): subset?(ch1, ch2) OR subset?(ch2, ch1)

    % A proof that T0 is the smallest tower
    T0_smallest: LEMMA FORALL (tow: (tower?)): subset?(T0, tow)

    % Construct a tower from some element ch1 of T0 by taking all elements of T0
    % that are included in ch1, and all those that include ch1's sucessor
    make_tower(ch1: (T0_comparable?)): (tower?) =
        {ch2 | T0(ch2) AND (subset?(ch2, ch1) OR subset?(succ(ch1), ch2))}

    % Every T0_comparable? element of T0 constructs T0 via make_tower
    T0_construct: LEMMA FORALL (ch: (T0_comparable?)): T0 = make_tower(ch)

    % Every successor of a T0_comparable? element is also T0_comparable?
    T0_comparable: JUDGEMENT
      succ(ch: (T0_comparable?)) HAS_TYPE (T0_comparable?)

    % Every element of T0 is T0_comparable?
    T0_all_comparable: LEMMA FORALL (ch: (T0)): T0_comparable?(ch)

    % T0 is a chain of chains
    T0_chain: JUDGEMENT T0 HAS_TYPE chain_chain

    % Zorn's Lemma
    zorn: THEOREM
      (FORALL (ch: chain[T, <=]): bounded_above?[T](ch, <=)) IMPLIES
       (EXISTS t: maximal?[T](t, fullset[T], <=))

   END zorn

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

  % Subtype TCC generated (at line 51, column 53) for  add_set(ch)
      % expected type  p: (nonempty?)
  succ_TCC1: OBLIGATION
    FORALL (ch: subchain[T, <=]):
      NOT empty?(add_set(ch)) IMPLIES nonempty?[T](add_set(ch));

  % Subtype TCC generated (at line 51, column 42) for
      % add(choose(add_set(ch)), ch)
      % expected type  subchain[T, <=]
  succ_TCC2: OBLIGATION
    FORALL (ch: subchain[T, <=]):
      NOT empty?(add_set(ch)) IMPLIES
       chain?[T, <=](add[T](choose[T](add_set(ch)), ch));

  % Subtype TCC generated (at line 65, column 13) for  emptyset[T]
      % expected type  subchain[T, <=]
  tower?_TCC1: OBLIGATION chain?[T, <=](emptyset[T]);

  % Subtype TCC generated (at line 78, column 17) for
      % Intersection[subchain]({CH: set[subchain] | tower?(CH)})
      % expected type  (tower?)
  T0_TCC1: OBLIGATION
    tower?(Intersection[subchain[T, <=]]
               ({CH: set[subchain[T, <=]] | tower?(CH)}));

  % Subtype TCC generated (at line 91, column 6) for
      % {ch2 | T0(ch2) AND (subset?(ch2, ch1) OR subset?(succ(ch1), ch2))}
      % expected type  (tower?)
  make_tower_TCC1: OBLIGATION
    FORALL (ch1: (T0_comparable?)):
      tower?({ch2 |
                T0(ch2) AND
                 (subset?[T](ch2, ch1) OR subset?[T](succ(ch1), ch2))});

  % Judgement subtype TCC generated (at line 98, column 4) for  succ(ch)
      % expected type  (T0_comparable?)
  T0_comparable: OBLIGATION
    FORALL (ch: (T0_comparable?)): T0(succ(ch)) AND T0_comparable?(succ(ch));

  % Judgement subtype TCC generated (at line 104, column 22) for  T0
      % expected type  chain_chain[T, <=]
  T0_chain: OBLIGATION chain?[subchain[T, <=], chain_incl[T, <=]](T0);


body:
  %-------------------------------------------------------------------------
  %
  %  The Well-Ordering Principle: every set can be well-ordered.  This is
  %  equivalent to the Axiom of Choice, Zorn's Lemma, and Kuratowski's Lemma.
  %
  %  For PVS version 3.2.  February 28, 2005
  %  ---------------------------------------------------------------------
  %      Author: Jerry James (jamesj@acm.org), University of Kansas
  %
  %  EXPORTS
  %  -------
  %  prelude: finite_sets[T], orders[T], relations[T], sets[T]
  %  orders: bounded_orders[T], relations_extra[T], well_ordering[T]
  %
  %-------------------------------------------------------------------------
  well_ordering[T: TYPE]: THEORY

   % Hide all the technical details from public view
   EXPORTING well_ordering WITH bounded_orders[T], finite_sets[T], orders[T],
                                relations_extra[T], relations[T], sets[T]

   BEGIN

    IMPORTING bounded_orders


    % ==========================================================================
    % A partial order on well-ordered sets
    % ==========================================================================

    %% Types
    ordered_set: TYPE = [A: set[T], (well_ordered?[(A)])]

    %% Variables
    t: VAR T
    <: VAR pred[[T, T]]
    ord1, ord2: VAR ordered_set

    %% Functions
    ordered_set_order(ord1, ord2): bool =
        subset?(ord1`1, ord2`1) AND
         (FORALL (t, r: (ord1`1)): ord1`2(t, r) IFF ord2`2(t, r)) AND
          (FORALL (t: (difference(ord2`1, ord1`1))):
             upper_bound?[(ord2`1)](t, ord1`1, ord2`2))

    partial_ordered_set: JUDGEMENT
      ordered_set_order HAS_TYPE (partial_order?[ordered_set])

    IMPORTING zorn[ordered_set, ordered_set_order]

    C: VAR chain

    ordered_set_union(C): ordered_set =
        ({t | EXISTS (S: (C)): S`1(t)},
         LAMBDA (t, r: ({t | EXISTS (S: (C)): S`1(t)})):
           EXISTS (ord: (C)): ord`1(t) AND ord`1(r) AND ord`2(t, r))

    chain_upper_bound: LEMMA
      FORALL C: bounded_above?[ordered_set](C, ordered_set_order)


    % ==========================================================================
    % The well-ordering theorem
    % ==========================================================================

    well_ordering: THEOREM EXISTS <: well_ordered?(<)

   END well_ordering

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

  % Subtype TCC generated (at line 42, column 57) for  t
      % expected type  (ord2`1)
  ordered_set_order_TCC1: OBLIGATION
    FORALL (ord1: ordered_set, ord2: ordered_set):
      subset?(ord1`1, ord2`1) IMPLIES (FORALL (t, r: (ord1`1)): ord2`1(t));

  % Subtype TCC generated (at line 42, column 60) for  r
      % expected type  (ord2`1)
  ordered_set_order_TCC2: OBLIGATION
    FORALL (ord1: ordered_set, ord2: ordered_set):
      subset?(ord1`1, ord2`1) IMPLIES (FORALL (t, r: (ord1`1)): ord2`1(r));

  % Subtype TCC generated (at line 44, column 34) for  t
      % expected type  (ord2`1)
  ordered_set_order_TCC3: OBLIGATION
    FORALL (ord1: ordered_set, ord2: ordered_set):
      (FORALL (t, r: (ord1`1)): ord1`2(t, r) IFF ord2`2(t, r)) AND
       subset?(ord1`1, ord2`1)
       IMPLIES (FORALL (t1: (difference[T](ord2`1, ord1`1))): (ord2`1)(t1));

  % Judgement subtype TCC generated (at line 47, column 4) for
      % ordered_set_order
      % expected type  (partial_order?[ordered_set])
  partial_ordered_set: OBLIGATION
    partial_order?[ordered_set](ordered_set_order);

  % Subtype TCC generated (at line 55, column 7) for
      % LAMBDA (t, r: ({t | EXISTS (S: (C)): S`1(t)})):
      %   EXISTS (ord: (C)): ord`1(t) AND ord`1(r) AND ord`2(t, r)
      % expected type  (well_ordered?[({t | EXISTS (S: (C)): S`1(t)})])
  ordered_set_union_TCC1: OBLIGATION
    FORALL (C: chain[ordered_set, ordered_set_order]):
      well_ordered?[({t | EXISTS (S: (C)): S`1(t)})]
          (LAMBDA (t, r: ({t | EXISTS (S: (C)): S`1(t)})):
             EXISTS (ord: (C)): ord`1(t) AND ord`1(r) AND ord`2(t, r));


body:
  %-------------------------------------------------------------------------
  %
  %  Functions for traversing a well-ordered set.  In particular, these
  %  functions yield the first, last, and next elements of such a set.  See
  %  below for an explanation of the fairly useless function for yielding
  %  the previous element of such a set.
  %
  %  For PVS version 3.2.  February 28, 2005
  %  ---------------------------------------------------------------------
  %      Author: Jerry James (jamesj@acm.org), University of Kansas
  %
  %  EXPORTS
  %  -------
  %  prelude: orders[T], relation_props2[T, T, T, T], relations[T], sets[T]
  %  finite_sets: finite_sets_inductions, finite_sets_minmax
  %  orders: bounded_orders[T], closure_ops[T], indexed_sets_extra,
  %    minmax_orders[T], ordered_subset[T], relation_iterate[T],
  %    relations_extra[T], well_ordered_traversal[T]
  %
  %-------------------------------------------------------------------------
  well_ordered_traversal[T: TYPE]: THEORY
   BEGIN

    IMPORTING ordered_subset[T], minmax_orders[T]

    t, r, s: VAR T
    <: VAR (well_ordered?)


    % ==========================================================================
    % The first element of a well-ordering
    % ==========================================================================

    has_first?(<): bool = EXISTS t: TRUE

    well_ordering_has_first: LEMMA
      FORALL <:
        has_first?(<) IMPLIES has_least?(fullset[T], reflexive_closure(<))

    first(<: (has_first?)): (least?(fullset[T], reflexive_closure(<))) =
        least(reflexive_closure(<))(fullset[T])

    % All but the first element.  This is often useful for stating the elements
    % which have a prev.  See below.
    nonfirst(<): set[T] =
        IF has_first?(<) THEN {t | t /= first(<)} ELSE emptyset[T] ENDIF


    % ==========================================================================
    % The last element of a well-ordering
    % ==========================================================================

    has_last?(<): bool = has_greatest?(fullset[T], reflexive_closure(<))

    last(<: (has_last?)): (greatest?(fullset[T], reflexive_closure(<))) =
        greatest(reflexive_closure(<))(fullset[T])

    % All but the last element.  This is often useful for stating the elements
    % which have a next.
    nonlast(<): set[T] =
        IF has_last?(<) THEN {t | t /= last(<)} ELSE fullset[T] ENDIF


    % ==========================================================================
    % The successor of a given element
    % ==========================================================================

    has_next?(<)(t): bool = nonempty?(above(t, <))

    well_ordering_has_next: LEMMA
      FORALL <, t:
        has_next?(<)(t) IMPLIES has_least?(above(t, <), reflexive_closure(<))

    next(<)(t: (has_next?(<))): (least?(above(t, <), reflexive_closure(<))) =
        least(reflexive_closure(<))(above(t, <))

    last_no_next: LEMMA FORALL <: has_last?(<) => NOT has_next?(<)(last(<))

    last_is_last: LEMMA FORALL <: has_last?(<) => full?(upto(last(<), <))


    % ==========================================================================
    % The predecessor of a given element
    % ==========================================================================

    % The prev operator is defined in such a way that it is almost useless.
    % This is because prev is not well-defined for arbitrary well-ordered sets.
    % For example, consider the set of all even natural numbers, and the set of
    % all odd natural numbers.  Both sets are well-ordered by <.  Now consider
    % the set of all natural numbers, ordered as follows:
    %
    % order(x, y) = x < y if x and y are both even, or both odd
    %               FALSE if x is odd and y is even
    %               TRUE  if x is even and y is odd
    %
    % One can easily show that that order is a well-ordering of the natural
    % numbers.  Any given natural number has a well-defined next element in this
    % ordering.  However, there is no well-defined previous element of 1.
    %
    % The following definitions are really placeholders.  For any given well
    % ordering, give a JUDGEMENT stating the elements for which has_prev? is
    % satisfied.

    has_prev?(<)(t): bool = EXISTS (r: (has_next?(<))): next(<)(r) = t

    well_ordering_has_prev: LEMMA
      FORALL <, t:
        has_prev?(<)(t) IMPLIES
         has_greatest?(below(t, <), reflexive_closure(<))

    prev(<)(t: (has_prev?(<))): (greatest?(below(t, <), reflexive_closure(<))) =
        greatest(reflexive_closure(<))(below(t, <))

   END well_ordered_traversal

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

  % Subtype TCC generated (at line 41, column 34) for  fullset[T]
      % expected type  S:
                     %   (LAMBDA (S: set[T]):
                     %      has_least?(S, reflexive_closure(<)))
  first_TCC1: OBLIGATION
    FORALL (<: (has_first?)):
      has_least?[T](fullset[T], reflexive_closure[T](<));

  % Subtype TCC generated (at line 56, column 37) for  fullset[T]
      % expected type  S:
                     %   (LAMBDA (S: set[T]):
                     %      has_greatest?(S, reflexive_closure(<)))
  last_TCC1: OBLIGATION
    FORALL (<: (has_last?)):
      has_greatest?[T](fullset[T], reflexive_closure[T](<));

  % Subtype TCC generated (at line 75, column 34) for  above(t, <)
      % expected type  S:
                     %   (LAMBDA (S: set[T]):
                     %      has_least?(S, reflexive_closure(<)))
  next_TCC1: OBLIGATION
    FORALL (<: (well_ordered?[T]), t: (has_next?(<))):
      has_least?[T](above[T](t, <), reflexive_closure[T](<));

  % Subtype TCC generated (at line 112, column 37) for  below(t, <)
      % expected type  S:
                     %   (LAMBDA (S: set[T]):
                     %      has_greatest?(S, reflexive_closure(<)))
  prev_TCC1: OBLIGATION
    FORALL (<: (well_ordered?[T]), t: (has_prev?(<))):
      has_greatest?[T](below[T](t, <), reflexive_closure[T](<));


body:
  %-------------------------------------------------------------------------
  %
  %  Isomorphisms between ordered sets.  This is different than the
  %  isomorphism? predicate of relation_defs; that version says that a
  %  relation between two types is an isomorphism if it is a bijective
  %  function.  This version says that a bijective function is an
  %  isomorphism with respect to relations on its domain and range types
  %  if it preserves those relations.
  %
  %  For PVS version 3.2.  February 24, 2005
  %  ---------------------------------------------------------------------
  %      Author: Jerry James (jamesj@acm.org), University of Kansas
  %
  %  EXPORTS
  %  -------
  %  prelude: orders[D], orders[R], relations[D], relations[R]
  %  orders: isomorphism[D,R], relations_extra[D], relations_extra[R]
  %
  %-------------------------------------------------------------------------
  isomorphism[D: TYPE, R: TYPE]: THEORY
   BEGIN

    IMPORTING relations_extra[D], relations_extra[R]

    Drel: VAR pred[[D, D]]
    Rrel: VAR pred[[R, R]]
    d1, d2: VAR D
    f: VAR (bijective?[D, R])

    isomorphism?(Drel, Rrel)(f): bool =
        FORALL d1, d2: Drel(d1, d2) IFF Rrel(f(d1), f(d2))

    isomorphic?(Drel, Rrel): bool = EXISTS f: isomorphism?(Drel, Rrel)(f)

    isomorphism_implication: LEMMA
      FORALL Drel, Rrel, f:
        trichotomous?(Drel) AND
         irreflexive?(Rrel) AND
          antisymmetric?(Rrel) AND preserves(f, Drel, Rrel)
         IMPLIES isomorphism?(Drel, Rrel)(f)

    isomorphism_preserves_reflexive: LEMMA
      FORALL Drel, Rrel:
        isomorphic?(Drel, Rrel) =>
         (reflexive?[D](Drel) IFF reflexive?[R](Rrel))

    isomorphism_preserves_irreflexive: LEMMA
      FORALL Drel, Rrel:
        isomorphic?(Drel, Rrel) =>
         (irreflexive?[D](Drel) IFF irreflexive?[R](Rrel))

    isomorphism_preserves_symmetric: LEMMA
      FORALL Drel, Rrel:
        isomorphic?(Drel, Rrel) =>
         (symmetric?[D](Drel) IFF symmetric?[R](Rrel))

    isomorphism_preserves_antisymmetric: LEMMA
      FORALL Drel, Rrel:
        isomorphic?(Drel, Rrel) =>
         (antisymmetric?[D](Drel) IFF antisymmetric?[R](Rrel))

    isomorphism_preserves_asymmetric: LEMMA
      FORALL Drel, Rrel:
        isomorphic?(Drel, Rrel) =>
         (asymmetric?[D](Drel) IFF asymmetric?[R](Rrel))

    % connected is the same as trichotomous

    isomorphism_preserves_transitive: LEMMA
      FORALL Drel, Rrel:
        isomorphic?(Drel, Rrel) =>
         (transitive?[D](Drel) IFF transitive?[R](Rrel))

    isomorphism_preserves_dichotomous: LEMMA
      FORALL Drel, Rrel:
        isomorphic?(Drel, Rrel) =>
         (dichotomous?[D](Drel) IFF dichotomous?[R](Rrel))

    isomorphism_preserves_trichotomous: LEMMA
      FORALL Drel, Rrel:
        isomorphic?(Drel, Rrel) =>
         (trichotomous?[D](Drel) IFF trichotomous?[R](Rrel))

    isomorphism_preserves_well_founded: LEMMA
      FORALL Drel, Rrel:
        isomorphic?(Drel, Rrel) =>
         (well_founded?[D](Drel) IFF well_founded?[R](Rrel))

    isomorphism_inverse: LEMMA
      FORALL Drel, Rrel, f:
        isomorphism?(Drel, Rrel)(f) IFF
         preserves(f, Drel, Rrel) AND preserves(inverse_alt(f), Rrel, Drel)

   END isomorphism

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

  % Assuming TCC generated (at line 1370, column 3) for
      % function_inverse_alt[D, R]
      % generated from assumption function_inverse_alt.inverse_types
  isomorphism_inverse_TCC1: OBLIGATION
    FORALL (Drel, Rrel, f):
      preserves(f, Drel, Rrel) IMPLIES
       (EXISTS (d: D): TRUE) OR (FORALL (r: R): FALSE);


