# TheoryBodies

body:
  series_lems: THEORY
  %------------------------------------------------------------------------------
  % Extra properties of series. To be added to series@series
  %
  %     Author: David Lester, Manchester University 12/12/07
  %
  %------------------------------------------------------------------------------
  BEGIN

     IMPORTING series,
               orders@well_nat    % proof only

     i: VAR int
     n,m,N: VAR nat
     pn: VAR posnat
     x,l1,l2,c: VAR real
     nnx: VAR nnreal

     a,b: VAR sequence[real]
     nna: VAR sequence[nnreal]
     phi: VAR (bijective?[nat,nat])


     zero_tail_series_conv:  LEMMA (FORALL m: n < m => a(m) = 0) =>
                                    convergent?(series(a))

     zero_tail_series_limit: LEMMA (FORALL m: n < m => a(m) = 0) =>
                                   limit(series(a)) = series(a)(n)

     zero_tail_series:       LEMMA (FORALL m: n < m => a(m) = 0) =>
                                   convergence(series(a), series(a)(n))

     single_nz_series_conv:  LEMMA (FORALL m: n /= m => a(m) = 0) =>
                                    convergent?(series(a))

     single_nz_series_limit: LEMMA (FORALL m: n /= m => a(m) = 0) =>
                                   limit(series(a)) = a(n)

     single_nz_series:       LEMMA (FORALL m: n /= m => a(m) = 0) =>
                                   convergence(series(a), a(n))

     limit_nonneg:           LEMMA convergent?(nna) => limit(nna) >= 0

     convergence_nonneg:     LEMMA convergence(series(nna),nnx) =>
                                   FORALL n: series(nna)(n) <= nnx

     nonneg_series_bij:      LEMMA convergence(series(nna),nnx) =>  
                                   convergence(series(nna o phi),nnx)

     nonneg_series_bij_conv: LEMMA convergent?(series(nna)) =>
                                   convergent?(series(nna o phi))

     nonneg_series_bij_limit:LEMMA convergent?(series(nna)) =>
                                   limit(series(nna)) = limit(series(nna o phi))

     abs_series_bij:         LEMMA convergent?(series(abs(a))) AND
                                    convergence(series(a),x) =>
                                      convergence(series(a o phi),x)

     abs_series_bij_conv:    LEMMA convergent?(series(abs(a))) =>
                                     convergent?(series(a o phi))

     abs_series_bij_limit:   LEMMA convergent?(series(abs(a))) =>
                                   limit(series(a)) = limit(series(a o phi))

  END series_lems

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

  % Subtype TCC generated (at line 28, column 39) for  series(a)
      % expected type  (convergent?)
  zero_tail_series_limit_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat):
      (FORALL m: n < m => a(m) = 0) IMPLIES convergent?(series(a));

  % Subtype TCC generated (at line 37, column 39) for  series(a)
      % expected type  (convergent?)
  single_nz_series_limit_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat):
      (FORALL m: n /= m => a(m) = 0) IMPLIES convergent?(series(a));

  % Subtype TCC generated (at line 54, column 60) for  series(nna o phi)
      % expected type  (convergent?)
  nonneg_series_bij_limit_TCC1: OBLIGATION
    FORALL (nna: sequence[nnreal], phi: (bijective?[nat, nat])):
      convergent?(series(nna)) IMPLIES
       convergent?(series(o[nat, nat, nnreal](nna, phi)));

  % Subtype TCC generated (at line 64, column 39) for  series(a)
      % expected type  (convergent?)
  abs_series_bij_limit_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      convergent?(series(abs(a))) IMPLIES convergent?(series(a));

  % Subtype TCC generated (at line 64, column 58) for  series(a o phi)
      % expected type  (convergent?)
  abs_series_bij_limit_TCC2: OBLIGATION
    FORALL (a: sequence[real], phi: (bijective?[nat, nat])):
      convergent?(series(abs(a))) IMPLIES
       convergent?(series(o[nat, nat, real](a, phi)));


body:
  %----------------------------------------------------------------------------
  %
  % Absolutely Convergent Series
  %
  % Author: David Lester (Manchester University)          22/04/05
  % 
  %----------------------------------------------------------------------------
  absconv_series: THEORY

  BEGIN

    IMPORTING series_lems

    n,m:     VAR nat
    x:       VAR real
    nnx,nny: VAR nnreal
    f:       VAR extraction
    a,b:     VAR sequence[real]
    nna,nnb: VAR sequence[nnreal]
    phi:     VAR (bijective?[nat,nat])
    inj:     VAR (injective?[nat,nat])

    Convergent_Series: TYPE+ = {s: sequence[real] | convergent?(series(s))}
                               CONTAINING (LAMBDA n: 0)

    absconvergent?(a):bool = convergent?(series(abs(a)))

    absconvergent_series: TYPE+ = (absconvergent?)

    absconvergent_series_is_convergent:
          JUDGEMENT absconvergent_series SUBTYPE_OF Convergent_Series

    aa,bb: VAR absconvergent_series

    abs_series_bij_abs: LEMMA
           convergence(series(aa o phi),x) IFF convergence(series(aa),x)

    abs_series_bij_conv_abs: LEMMA
           convergent?(series(aa o phi)) IFF convergent?(series(aa))

    abs_series_bij_limit_abs: LEMMA
           limit(series(aa o phi)) = limit(series(aa))


  % extractions of sequences ...

    extract_convergent: LEMMA convergent?(series(a)) => convergent?(series(a) o f)

    extract_comp: LEMMA series(a o f)
          = series(lambda n: IF (EXISTS m: n = f(m)) THEN a(n) ELSE 0 ENDIF) o f

    subseq_absconvergent: LEMMA subseq(a,bb) => absconvergent?(a)

    nonneg_subseq:      LEMMA subseq(nna,nnb) AND convergence(series(nnb),nny) =>
                              EXISTS nnx:
                                  convergence(series(nna),nnx) AND nnx <= nny


    sum_absconvergent:  LEMMA absconvergent?(aa+bb)
   
    opp_absconvergent:  LEMMA absconvergent?(-aa)

    diff_absconvergent: LEMMA absconvergent?(aa-bb)

    scal_absconvergent: LEMMA absconvergent?(x*aa)


  END absconv_series

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

  % Subtype TCC generated (at line 24, column 41) for  (LAMBDA n: 0)
      % expected type  Convergent_Series
  Convergent_Series_TCC1: OBLIGATION convergent?(series((LAMBDA n: 0)));

  % Existence TCC generated (at line 28, column 2) for
      % absconvergent_series: TYPE+ = (absconvergent?)
  absconvergent_series_TCC1: OBLIGATION
    EXISTS (x: {x: sequence[real] | absconvergent?(x)}): TRUE;

  % Judgement subtype TCC generated (at line 31, column 18) for  x
      % expected type  Convergent_Series
  absconvergent_series_is_convergent: OBLIGATION
    FORALL (x: absconvergent_series): convergent?(series(x));

  % Subtype TCC generated (at line 42, column 15) for  series(aa o phi)
      % expected type  (convergent?)
  abs_series_bij_limit_abs_TCC1: OBLIGATION
    FORALL (aa: absconvergent_series, phi: (bijective?[nat, nat])):
      convergent?(series(o[nat, nat, real](aa, phi)));


body:
  %------------------------------------------------------------------------------
  % Extra properties of series. 
  %
  %  MODIFICATIONS:
  %
  %     Author: David Lester, Manchester University 12/12/07
  %
  %------------------------------------------------------------------------------
  series_aux: THEORY

  BEGIN

     IMPORTING series,
               orders@well_nat    % proof only

     i: VAR int
     n,m,N: VAR nat
     pn: VAR posnat
     x,l1,l2,c: VAR real
     nnx: VAR nnreal

     a,b: VAR sequence[real]
     nna: VAR sequence[nnreal]
     phi: VAR (bijective?[nat,nat])


     zero_tail_series_conv:  LEMMA (FORALL m: n < m => a(m) = 0) =>
                                    convergent?(series(a))

     zero_tail_series_limit: LEMMA (FORALL m: n < m => a(m) = 0) =>
                                   limit(series(a)) = series(a)(n)

     zero_tail_series:       LEMMA (FORALL m: n < m => a(m) = 0) =>
                                   convergence(series(a), series(a)(n))

     single_nz_series_conv:  LEMMA (FORALL m: n /= m => a(m) = 0) =>
                                    convergent?(series(a))

     single_nz_series_limit: LEMMA (FORALL m: n /= m => a(m) = 0) =>
                                   limit(series(a)) = a(n)

     single_nz_series:       LEMMA (FORALL m: n /= m => a(m) = 0) =>
                                   convergence(series(a), a(n))

     limit_nonneg:           LEMMA convergent?(nna) => limit(nna) >= 0

     convergence_nonneg:     LEMMA convergence(series(nna),nnx) =>
                                   FORALL n: series(nna)(n) <= nnx

     nonneg_series_bij:      LEMMA convergence(series(nna),nnx) =>
                                   convergence(series(nna o phi),nnx)

     nonneg_series_bij_conv: LEMMA convergent?(series(nna)) =>
                                   convergent?(series(nna o phi))

     nonneg_series_bij_limit:LEMMA convergent?(series(nna)) =>
                                   limit(series(nna)) = limit(series(nna o phi))

     abs_series_bij:         LEMMA convergent?(series(abs(a))) AND
                                    convergence(series(a),x) =>
                                      convergence(series(a o phi),x)

     abs_series_bij_conv:    LEMMA convergent?(series(abs(a))) =>
                                     convergent?(series(a o phi))

     abs_series_bij_limit:   LEMMA convergent?(series(abs(a))) =>
                                   limit(series(a)) = limit(series(a o phi))

  END series_aux

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

  % Subtype TCC generated (at line 31, column 39) for  series(a)
      % expected type  (convergent?)
  zero_tail_series_limit_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat):
      (FORALL m: n < m => a(m) = 0) IMPLIES convergent?(series(a));

  % Subtype TCC generated (at line 40, column 39) for  series(a)
      % expected type  (convergent?)
  single_nz_series_limit_TCC1: OBLIGATION
    FORALL (a: sequence[real], n: nat):
      (FORALL m: n /= m => a(m) = 0) IMPLIES convergent?(series(a));

  % Subtype TCC generated (at line 57, column 60) for  series(nna o phi)
      % expected type  (convergent?)
  nonneg_series_bij_limit_TCC1: OBLIGATION
    FORALL (nna: sequence[nnreal], phi: (bijective?[nat, nat])):
      convergent?(series(nna)) IMPLIES
       convergent?(series(o[nat, nat, nnreal](nna, phi)));

  % Subtype TCC generated (at line 67, column 39) for  series(a)
      % expected type  (convergent?)
  abs_series_bij_limit_TCC1: OBLIGATION
    FORALL (a: sequence[real]):
      convergent?(series(abs(a))) IMPLIES convergent?(series(a));

  % Subtype TCC generated (at line 67, column 58) for  series(a o phi)
      % expected type  (convergent?)
  abs_series_bij_limit_TCC2: OBLIGATION
    FORALL (a: sequence[real], phi: (bijective?[nat, nat])):
      convergent?(series(abs(a))) IMPLIES
       convergent?(series(o[nat, nat, real](a, phi)));


body:
  %------------------------------------------------------------------------------
  % Top file for sums over sets
  %
  %  MODIFICATIONS:
  %
  %     Author: David Lester, Manchester University 12/12/07
  %
  %------------------------------------------------------------------------------
  top: THEORY

  BEGIN

    IMPORTING
      absconv_series_aux,      % properties of absolutely convergent series
      finite_enumeration,      % enumerate a finite set
      denumerable_enumeration, % enumerate a countably infinite set
      sigma_bijection,         % re-ordering of finite sums
      sigma_bijection_nat,     % re-ordering of finite sums

      countable_convergence,   % convergence properties for countable sums
      sigma_countable,         % countable sums
      convergence_set,         % convergence properties for uncountable sums
      sigma_set                % sums of uncountable sets


  END top


body:
  %----------------------------------------------------------------------------
  %
  % Absolutely Convergent Series
  %
  % Author: David Lester (Manchester University)          22/04/05
  % 
  %----------------------------------------------------------------------------
  absconv_series_aux: THEORY

  BEGIN

    IMPORTING series@series_aux,
              series@absconv_series,
              sets_aux@infinite_image,
              sets_aux@countable_props,
              sets_aux@countable_image,
              analysis@convergence_ops       % proof only

    n,m:     VAR nat
    x:       VAR real
    nnx,nny: VAR nnreal
    f:       VAR extraction
    a,b:     VAR sequence[real]
    nna,nnb: VAR sequence[nnreal]
    phi:     VAR (bijective?[nat,nat])
    inj:     VAR (injective?[nat,nat])

  % Following should probably be in analysis@sequence_props.pvs:

    extract_bij:        LEMMA bijective?[nat,(image(f,fullset[nat]))](f)

    subseq_def:         LEMMA subseq(a,b) IFF EXISTS f: FORALL n: a(n) = b(f(n))


    S: VAR countably_infinite_set[nat]

    IMPORTING orders@integer_enumerations[nat]

    inj_is_bij_extract:      LEMMA EXISTS phi,f: inj = phi o f

    nonneg_series_inj_conv:  LEMMA convergent?(series(nna)) =>
                                   convergent?(series(nna o inj))

    nonneg_series_inj_limit: LEMMA convergent?(series(nna)) =>
                                   limit(series(nna)) >= limit(series(nna o inj))

  % Any absolutely convergent series can be arbitrarily rearranged omitting
  % terms.

    aa: VAR absconvergent_series

    abs_series_inj_conv: LEMMA convergent?(series(aa o inj))

  END absconv_series_aux

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

  % Subtype TCC generated (at line 30, column 68) for  f
      % expected type  [nat -> (image(f, fullset[nat]))]
  extract_bij_TCC1: OBLIGATION
    FORALL (f: extraction, x1: nat): image[nat, nat](f, fullset[nat])(f(x1));

  % Subtype TCC generated (at line 45, column 61) for  series(nna o inj)
      % expected type  (convergent?)
  nonneg_series_inj_limit_TCC1: OBLIGATION
    FORALL (inj: (injective?[nat, nat]), nna: sequence[nnreal]):
      convergent?(series(nna)) IMPLIES
       convergent?(series(o[nat, nat, nnreal](nna, inj)));


body:
  %------------------------------------------------------------------------------
  % Re-ordering of sums
  %
  %  MODIFICATIONS:
  %
  %     Author: David Lester, Manchester University 12/12/07
  %
  %------------------------------------------------------------------------------
  sigma_bijection[T: TYPE FROM int]: THEORY

  BEGIN

    ASSUMING

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

    ENDASSUMING

    IMPORTING reals@sigma

    low,high, 
    l,h,n,m,i : VAR T
    rng, nn   : VAR nat
    pn        : VAR posnat
    z         : VAR int
    a,x,B     : VAR real
    F         : VAR [T->real]

    subrange_T(n,m): TYPE = {k:T | n <= k AND k <= m}

  % The following theorem shows that we can re-order the summation of
  % any finite sum.

    sigma_bijection: LEMMA
       low <= high IMPLIES
       FORALL (phi:(bijective?[subrange_T(low,high),subrange_T(low,high)])):
         sigma[subrange_T(low,high)](low,high,F)
                 = sigma[subrange_T(low,high)](low,high,F o phi)

  END sigma_bijection

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

  % Subtype TCC generated (at line 38, column 35) for  low
      % expected type  T_low[subrange_T(low, high)]
  sigma_bijection_TCC1: OBLIGATION
    FORALL (high, low: T):
      low <= high IMPLIES
       (FORALL (phi:
                  (bijective?
                       [subrange_T(low, high), subrange_T(low, high)])):
          T_pred(low) AND low <= low AND low <= high OR
           (EXISTS (j: subrange_T(low, high)): j <= low));

  % Subtype TCC generated (at line 38, column 39) for  high
      % expected type  T_high[subrange_T(low, high)]
  sigma_bijection_TCC2: OBLIGATION
    FORALL (high, low: T):
      low <= high IMPLIES
       (FORALL (phi:
                  (bijective?
                       [subrange_T(low, high), subrange_T(low, high)])):
          T_pred(high) AND low <= high AND high <= high OR
           (EXISTS (j: subrange_T(low, high)): high <= j));

  % Assuming TCC generated (at line 41, column 5) for
      % reals@sigma[subrange_T(low, high)]
      % generated from assumption sigma.connected_domain
  sigma_bijection_TCC3: OBLIGATION
    FORALL (high, low: T):
      low <= high IMPLIES
       (FORALL (phi:
                  (bijective?
                       [subrange_T(low, high), subrange_T(low, high)])):
          FORALL (x, y: subrange_T(low, high)), (z: integer):
            x <= z AND z <= y IMPLIES T_pred(z) AND low <= z AND z <= high);


body:
  %------------------------------------------------------------------------------
  % Re-ordering of series
  %
  %  MODIFICATIONS:
  %
  %     Author: David Lester, Manchester University 12/12/07
  %
  %------------------------------------------------------------------------------
  sigma_bijection_nat: THEORY

  BEGIN

    IMPORTING sigma_bijection,
              series@series

    n: VAR nat
    a: VAR sequence[real]

    series_bijection: LEMMA
        FORALL (phi:(bijective?[below[n+1],below[n+1]])):
           series(a)(n) = series(a o extend[nat,below[n+1],below[n+1],0](phi))(n)

  END sigma_bijection_nat

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

  % Subtype TCC generated (at line 21, column 68) for  0
      % expected type  below[n + 1]
  series_bijection_TCC1: OBLIGATION
    FORALL (n: nat, phi: (bijective?[below[1 + n], below[1 + n]])): 0 < 1 + n;


body:
  %------------------------------------------------------------------------------
  % Enumerations of finite sets
  %
  %  MODIFICATIONS:
  %
  %     Author: David Lester, Manchester University 12/12/07
  %
  %------------------------------------------------------------------------------
  finite_enumeration[T:TYPE]: THEORY

  BEGIN

    finite_enumeration(X:finite_set[T]): [below[card(X)]->(X)]
     = choose({f:[below[card(X)]->(X)] | bijective?[below[card(X)],(X)](f)})

    X: VAR finite_set[T]

    finite_enumeration_bij:   LEMMA
                 bijective?[below[card(X)],(X)](finite_enumeration(X))

    finite_enumeration_image: LEMMA
                 image(finite_enumeration(X),fullset[below[card(X)]]) = X

  END finite_enumeration

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

  % Subtype TCC generated (at line 14, column 12) for
      % {f: [below[card(X)] -> (X)] | bijective?[below[card(X)], (X)](f)}
      % expected type  p: (nonempty?[[below[card(X)] -> (X)]])
  finite_enumeration_TCC1: OBLIGATION
    FORALL (X: finite_set[T]):
      nonempty?[[below[card(X)] -> (X)]]
          ({f: [below[card[T](X)] -> (X)] |
              bijective?[below[card[T](X)], (X)](f)});


body:
  %------------------------------------------------------------------------------
  % Enumerations of countably infinite sets
  %
  %  MODIFICATIONS:
  %
  %     Author: David Lester, Manchester University 12/12/07
  %
  %------------------------------------------------------------------------------
  denumerable_enumeration[T:TYPE]: THEORY

  BEGIN

    IMPORTING sets_aux@countable_props[T]

    denumerable_enumeration(X:countably_infinite_set[T]): [nat->(X)]
     = choose({f:[nat->(X)] | bijective?[nat,(X)](f)})

    X: VAR countably_infinite_set[T]

    denumerable_enumeration_bij:   LEMMA
                 bijective?[nat,(X)](denumerable_enumeration(X))

    denumerable_enumeration_image: LEMMA
                 image(denumerable_enumeration(X),fullset[nat]) = X

  END denumerable_enumeration

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

  % Subtype TCC generated (at line 16, column 12) for
      % {f: [nat -> (X)] | bijective?[nat, (X)](f)}
      % expected type  p: (nonempty?[[nat -> (X)]])
  denumerable_enumeration_TCC1: OBLIGATION
    FORALL (X: countably_infinite_set[T]):
      nonempty?[[nat -> (X)]]({f: [nat -> (X)] | bijective?[nat, (X)](f)});


body:
  countable_convergence[T:TYPE]: THEORY
  %------------------------------------------------------------------------------
  % Convergence properties for countable sums.
  %
  %  MODIFICATIONS:
  %
  %     Author: David Lester, Manchester University 20/4/05
  %
  %------------------------------------------------------------------------------


  BEGIN

    IMPORTING sets_aux@countable_props[T],
              denumerable_enumeration[T],
              finite_enumeration[T],
              sigma_bijection_nat, sigma_bijection,
              analysis@convergence_ops,
              reals@sigma,
              absconv_series_aux,
              series@series

    a:   VAR real
    X,Y: VAR countable_set[T]
    t:   VAR T
    f,g: VAR [T -> real]
    F:   VAR non_empty_finite_set[T]
    n:   VAR nat
    phi: VAR (bijective?[nat,nat])


    convergent?(X)(g): bool
      = is_finite(X) OR absconvergent?(g o denumerable_enumeration(X))

    convergent_zero:   LEMMA convergent?(X)(LAMBDA t: 0)

    convergent_plus:   LEMMA convergent?(X)(f) AND convergent?(X)(g) =>
                             convergent?(X)(f+g)

    convergent_scal:   LEMMA convergent?(X)(f) => convergent?(X)(a*f)

    convergent_opp:    LEMMA convergent?(X)(f) => convergent?(X)(-f)

    convergent_diff:   LEMMA convergent?(X)(f) AND convergent?(X)(g) =>
                             convergent?(X)(f-g)

    convergent_le:     LEMMA (FORALL t: abs(g(t)) <= abs(f(t))) AND
                             convergent?(X)(f) => convergent?(X)(g)

    convergent_zeros:  LEMMA (FORALL (t:(X)): g(t) = 0) => convergent?(X)(g)

    convergent_empty:  LEMMA convergent?(emptyset[T])(g)

    convergent_singleton: LEMMA convergent?(singleton(t))(g)

    convergent_subset: LEMMA subset?(X,Y) AND convergent?(Y)(g) =>
                             convergent?(X)(g)

    convergent_intersection: LEMMA
           convergent?(X)(g) OR convergent?(Y)(g) =>
                             convergent?(intersection(X,Y))(g)

    convergent_difference: LEMMA
           convergent?(X)(g) => convergent?(difference(X,Y))(g)

    convergent_disjoint_union: LEMMA
           disjoint?(X,Y) AND convergent?(X)(g) AND convergent?(Y)(g) =>
                              convergent?(union(X,Y))(g)

    convergent_union: LEMMA
           convergent?(X)(g) AND convergent?(Y)(g) =>
                             convergent?(union(X,Y))(g)

    convergent_add: LEMMA convergent?(X)(g) =>
                             convergent?(add(t,X))(g)

    convergent_remove: LEMMA convergent?(X)(g) =>
                             convergent?(remove(t,X))(g)

    convergent_abs: LEMMA convergent?(X)(g) IFF convergent?(X)(abs(g))

  END countable_convergence

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

  % Subtype TCC generated (at line 33, column 65) for  X
      % expected type  X: countably_infinite_set[T]
  convergent?_TCC1: OBLIGATION
    FORALL (X: countable_set[T]):
      NOT is_finite(X) IMPLIES is_countably_infinite[T](X);


body:
  convergence_set[T:TYPE]: THEORY
  %------------------------------------------------------------------------------
  % Convergence properties for uncountable sets
  %
  %  MODIFICATIONS:
  %
  %     Author: David Lester, Manchester University 20/4/05
  %
  %------------------------------------------------------------------------------


  BEGIN

    IMPORTING countable_convergence[T]

    a:   VAR real
    nz:  VAR nzreal
    X,Y: VAR set[T]
    t:   VAR T
    f,g: VAR [T -> real]

    nonzero_elts(f,X):set[T] = {t | X(t) AND f(t) /= 0}

    convergent?(X)(f): bool
      = is_countable(nonzero_elts(f,X)) AND convergent?(nonzero_elts(f,X))(f)

    convergent_zero:   LEMMA convergent?(X)(LAMBDA t: 0)

    convergent_plus:   LEMMA convergent?(X)(f) AND convergent?(X)(g) =>
                             convergent?(X)(f+g)

    convergent_scal:   LEMMA convergent?(X)(f) => convergent?(X)(a*f)

    convergent_opp:    LEMMA convergent?(X)(f) => convergent?(X)(-f)

    convergent_diff:   LEMMA convergent?(X)(f) AND convergent?(X)(g) =>
                             convergent?(X)(f-g)

    convergent_le:     LEMMA (FORALL t: abs(g(t)) <= abs(f(t))) AND
                             convergent?(X)(f) => convergent?(X)(g)

    convergent_empty:  LEMMA convergent?(emptyset[T])(g)

    convergent_singleton: LEMMA convergent?(singleton(t))(g)

    convergent_subset: LEMMA subset?(X,Y) AND convergent?(Y)(g) =>
                             convergent?(X)(g)

    convergent_intersection: LEMMA
      convergent?(X)(g) OR convergent?(Y)(g) => convergent?(intersection(X,Y))(g)

    convergent_difference: LEMMA
      convergent?(X)(g) => convergent?(difference(X,Y))(g)

    convergent_disjoint_union: LEMMA
      disjoint?(X,Y) AND convergent?(X)(g) AND convergent?(Y)(g) =>
                              convergent?(union(X,Y))(g)

    convergent_union: LEMMA
           convergent?(X)(g) AND convergent?(Y)(g) => convergent?(union(X,Y))(g)

    convergent_add: LEMMA convergent?(X)(g) =>
                          convergence_set.convergent?(add(t,X))(g)

    convergent_remove: LEMMA convergent?(X)(g) => convergent?(remove(t,X))(g)

    convergent_abs: LEMMA convergent?(X)(g) IFF convergent?(X)(abs(g))

  END convergence_set


body:
  sigma_countable[T:TYPE]: THEORY
  %------------------------------------------------------------------------------
  % The sigma_set theory introduces and defines properties of the sigma 
  % function that sums an arbitrary function F: [T -> real] over a countable
  % set of values X. To make this sensible for infinite sets, we will also
  % require that f is absolutely convergent in the infinite case.
  %
  % This notation is a vital simplification for discrete probability theory.
  %
  %                         ----
  %  sigma(X, f)         =  \     f(x)
  %                         /
  %                         ----
  %                      member(x,X)
  %
  %
  %  MODIFICATIONS:
  %
  %     Author: David Lester, Manchester University 20/4/05
  %
  %     Additions 20/1/10 DR Lester
  %
  %------------------------------------------------------------------------------


  BEGIN

    IMPORTING sets_aux@countable_props[T],
              countable_convergence[T]

    a:   VAR real
    X,Y: VAR countable_set
    t:   VAR T
    f,g: VAR [T -> real]
    F:   VAR non_empty_finite_set[T]
    n:   VAR nat
    phi: VAR (bijective?[nat,nat])
    npx: VAR npreal
    nnx: VAR nnreal

    sigma(X:countable_set[T],f:(convergent?(X))):real
      = IF empty?(X)
        THEN 0
        ELSIF is_finite(X)
        THEN sigma[below[card(X)]](0,card(X)-1,f o finite_enumeration(X))
        ELSE limit(series(f o denumerable_enumeration(X)))      ENDIF

    sigma_empty: LEMMA sigma(emptyset[T],g) = 0

    sigma_finite: LEMMA LET n = card(F)-1 IN
                  sigma(F,g) = sigma[below[n+1]](0,n,g o finite_enumeration(F))

    sigma_singleton: LEMMA sigma(singleton(t),g) = g(t)

    sigma_infinite: LEMMA FORALL (X:countably_infinite_set,f:(convergent?(X))):
                    sigma(X,f) = limit(series(f o denumerable_enumeration(X)))

    nonempty_countable?(X:set[T]):bool = nonempty?(X) AND is_countable(X)

    nonempty_countable: TYPE = (nonempty_countable?) 

    nonempty_countable_is_countable:
        JUDGEMENT nonempty_countable SUBTYPE_OF countable_set[T]

    nonempty_countable_is_nonempty:
        JUDGEMENT nonempty_countable SUBTYPE_OF (nonempty?[T])

    sigma_disjoint_union: LEMMA FORALL (f:(convergent?(union(X,Y)))):
      disjoint?(X,Y) => sigma(union(X,Y),f) = sigma(X,f) + sigma(Y,f)

    sigma_union: LEMMA FORALL (f:(convergent?(union(X,Y)))):
      sigma(union(X,Y),f) = sigma(X,f) + sigma(Y,f) - sigma(intersection(X,Y),f)

    sigma_intersection: LEMMA FORALL (f:(convergent?(union(X,Y)))):
      sigma(intersection(X,Y),f) = sigma(X,f) + sigma(Y,f) - sigma(union(X,Y),f)

    sigma_difference: LEMMA FORALL (f:(convergent?(union(X,Y)))):
      sigma(difference(X,Y),f) 
           = sigma(X,f) - sigma(Y,f) + sigma(difference(Y,X),f)

    sigma_subset: LEMMA FORALL (f:(convergent?(Y))):
      subset?(X,Y) => sigma(Y,f) = sigma(X,f) + sigma(difference(Y,X),f)

    sigma_add: LEMMA FORALL (f:(convergent?(X))):
        sigma(add(t,X),f) = IF member(t,X) THEN sigma(X,f)
                                           ELSE f(t) + sigma(X,f) ENDIF

    sigma_remove: LEMMA FORALL (f:(convergent?(X))):
        sigma(remove(t,X),f) = IF member(t,X) THEN sigma(X,f) - f(t)
                                              ELSE sigma(X,f) ENDIF

    sigma_choose_rest: LEMMA FORALL (X:nonempty_countable,f:(convergent?(X))):
                             sigma(X,f) = f(choose(X)) + sigma(rest(X),f)

    sigma_zero: LEMMA sigma(X,LAMBDA t: 0) = 0

    sigma_scal: LEMMA FORALL (f:(convergent?(X))): sigma(X,a*f) = a*sigma(X,f)

    sigma_opp:  LEMMA FORALL (f:(convergent?(X))): sigma(X,-f)  = -sigma(X,f)

    sigma_plus: LEMMA FORALL (f,g:(convergent?(X))):
                                        sigma(X,f+g) = sigma(X,f) + sigma(X,g)

    sigma_diff: LEMMA FORALL (f,g:(convergent?(X))):
                                        sigma(X,f-g) = sigma(X,f) - sigma(X,g)

    sigma_ge_0: LEMMA FORALL (f:(convergent?(X))):
                             (FORALL (t:(X)): f(t) >= 0) => sigma(X,f) >= 0

    sigma_gt_0: LEMMA FORALL (X:nonempty_countable,f:(convergent?(X))):
                             (FORALL (t:(X)): f(t) >  0) => sigma(X,f) > 0

    sigma_abs:  LEMMA FORALL (f:(convergent?(X))):
                                        abs(sigma(X,f)) <= sigma(X,abs(f))

    sigma_eq:   LEMMA FORALL (f,g:(convergent?(X))):
                      (FORALL (t:(X)): f(t) =  g(t)) => sigma(X,f) =  sigma(X,g)
   
    sigma_le:   LEMMA FORALL (f,g:(convergent?(X))):
                      (FORALL (t:(X)): f(t) <= g(t)) => sigma(X,f) <= sigma(X,g)

    sigma_lt:   LEMMA FORALL (X:nonempty_countable,f,g:(convergent?(X))):
                      (FORALL (t:(X)): f(t) <  g(t)) => sigma(X,f) <  sigma(X,g)


    IMPORTING reals@bounded_reals,
              sigma_bijection_nat

    sigma_bij: LEMMA FORALL (f:(convergent?(X)),phi:(bijective?[(X),(X)])):
                     sigma(X,extend[T,(X),real,0](f o phi)) = sigma(X,f)

    sigma_nn_def: LEMMA 
      FORALL (f:(convergent?(X))):
             (FORALL t: X(t) => f(t) >= 0) =>
             sigma(X,f)
                   = sup({nnx | EXISTS (F:finite_set[T]):
                                subset?(F,X) AND nnx = sigma(F,f)})

    sigma_def: LEMMA
      FORALL (f:(convergent?(X))):
             sigma(X,f)
                   = sup({nnx | EXISTS (F:finite_set[T]): subset?(F,X) AND
                                          (FORALL t: F(t) => f(t) >= 0) AND
                                          nnx = sigma(F,f)}) +
                     inf({npx | EXISTS (F:finite_set[T]): subset?(F,X) AND
                                          (FORALL t: F(t) => f(t) <= 0) AND
                                           npx = sigma(F,f)})

  END sigma_countable

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

  % Subtype TCC generated (at line 45, column 33) for  0
      % expected type  T_low[below[card(X)]]
  sigma_TCC1: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X))):
      is_finite(X) AND NOT empty?(X) IMPLIES
       0 >= 0 AND 0 < card[T](X) OR (EXISTS (j: below[card(X)]): j <= 0);

  % Subtype TCC generated (at line 45, column 35) for  card(X) - 1
      % expected type  T_high[below[card(X)]]
  sigma_TCC2: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X))):
      is_finite(X) AND NOT empty?(X) IMPLIES
       card[T](X) - 1 >= 0 AND card[T](X) - 1 < card[T](X) OR
        (EXISTS (j: below[card(X)]): card[T](X) - 1 <= j);

  % Assuming TCC generated (at line 41, column 5) for
      % reals@sigma[below[card(X)]]
      % generated from assumption sigma.connected_domain
  sigma_TCC3: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X))):
      is_finite(X) AND NOT empty?(X) IMPLIES
       (FORALL (x, y: below[card(X)]), (z: integer):
          x <= z AND z <= y IMPLIES z >= 0 AND z < card[T](X));

  % Subtype TCC generated (at line 46, column 52) for  X
      % expected type  X: countably_infinite_set[T]
  sigma_TCC4: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X))):
      NOT is_finite(X) AND NOT empty?(X) IMPLIES is_countably_infinite[T](X);

  % Subtype TCC generated (at line 46, column 17) for
      % series(f o denumerable_enumeration(X))
      % expected type  (convergent?)
  sigma_TCC5: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X))):
      NOT is_finite(X) AND NOT empty?(X) IMPLIES
       convergent?(series(o[nat, T, real](f, denumerable_enumeration[T](X))));

  % Subtype TCC generated (at line 48, column 39) for  g
      % expected type  (convergent?(emptyset[T]))
  sigma_empty_TCC1: OBLIGATION
    FORALL (g: [T -> real]): convergent?[T](emptyset[T])(g);

  % Subtype TCC generated (at line 51, column 24) for  g
      % expected type  (convergent?(F))
  sigma_finite_TCC1: OBLIGATION
    FORALL (F: non_empty_finite_set[T], g: [T -> real], n: int):
      n = card(F) - 1 IMPLIES convergent?[T](F)(g);

  % Subtype TCC generated (at line 51, column 47) for  0
      % expected type  T_low[below[n + 1]]
  sigma_finite_TCC2: OBLIGATION
    FORALL (F: non_empty_finite_set[T], n: int):
      n = card(F) - 1 IMPLIES
       0 >= 0 AND 0 < 1 + n OR (EXISTS (j: below[1 + n]): j <= 0);

  % Subtype TCC generated (at line 51, column 49) for  n
      % expected type  T_high[below[n + 1]]
  sigma_finite_TCC3: OBLIGATION
    FORALL (F: non_empty_finite_set[T], n: int):
      n = card(F) - 1 IMPLIES
       n >= 0 AND n < 1 + n OR (EXISTS (j: below[1 + n]): n <= j);

  % Subtype TCC generated (at line 51, column 51) for
      % g o finite_enumeration(F)
      % expected type  [below[n + 1] -> real]
  sigma_finite_TCC4: OBLIGATION
    FORALL (F: non_empty_finite_set[T], n: int):
      n = card(F) - 1 IMPLIES (FORALL (x: nat): x < card[T](F) IFF x < 1 + n);

  % Assuming TCC generated (at line 41, column 5) for
      % reals@sigma[below[n + 1]]
      % generated from assumption sigma.connected_domain
  sigma_finite_TCC5: OBLIGATION
    FORALL (F: non_empty_finite_set[T], n: int):
      n = card(F) - 1 IMPLIES
       (FORALL (x, y: below[1 + n]), (z: integer):
          x <= z AND z <= y IMPLIES z >= 0 AND z < 1 + n);

  % Subtype TCC generated (at line 53, column 44) for  g
      % expected type  (convergent?(singleton(t)))
  sigma_singleton_TCC1: OBLIGATION
    FORALL (g: [T -> real], t: T): convergent?[T](singleton[T](t))(g);

  % Subtype TCC generated (at line 56, column 37) for
      % series(f o denumerable_enumeration(X))
      % expected type  (convergent?)
  sigma_infinite_TCC1: OBLIGATION
    FORALL (X: countably_infinite_set[T], f: (convergent?[T](X))):
      convergent?(series(o[nat, T, real](f, denumerable_enumeration[T](X))));

  % Judgement subtype TCC generated (at line 63, column 16) for  x
      % expected type  countable_set[T]
  nonempty_countable_is_countable: OBLIGATION
    FORALL (x: nonempty_countable): is_countable[T](x);

  % Judgement subtype TCC generated (at line 66, column 16) for  x
      % expected type  (nonempty?[T])
  nonempty_countable_is_nonempty: OBLIGATION
    FORALL (x: nonempty_countable): nonempty?[T](x);

  % Subtype TCC generated (at line 69, column 52) for  f
      % expected type  (convergent?(X))
  sigma_disjoint_union_TCC1: OBLIGATION
    FORALL (X, Y: countable_set[T], f: (convergent?[T](union[T](X, Y)))):
      disjoint?(X, Y) IMPLIES convergent?[T](X)(f);

  % Subtype TCC generated (at line 69, column 65) for  f
      % expected type  (convergent?(Y))
  sigma_disjoint_union_TCC2: OBLIGATION
    FORALL (X, Y: countable_set[T], f: (convergent?[T](union[T](X, Y)))):
      disjoint?(X, Y) IMPLIES convergent?[T](Y)(f);

  % Subtype TCC generated (at line 72, column 34) for  f
      % expected type  (convergent?(X))
  sigma_union_TCC1: OBLIGATION
    FORALL (X, Y: countable_set[T], f: (convergent?[T](union[T](X, Y)))):
      convergent?[T](X)(f);

  % Subtype TCC generated (at line 72, column 47) for  f
      % expected type  (convergent?(Y))
  sigma_union_TCC2: OBLIGATION
    FORALL (X, Y: countable_set[T], f: (convergent?[T](union[T](X, Y)))):
      convergent?[T](Y)(f);

  % Subtype TCC generated (at line 72, column 76) for  f
      % expected type  (convergent?(intersection(X, Y)))
  sigma_union_TCC3: OBLIGATION
    FORALL (X, Y: countable_set[T], f: (convergent?[T](union[T](X, Y)))):
      convergent?[T](intersection[T](X, Y))(f);

  % Subtype TCC generated (at line 78, column 26) for  f
      % expected type  (convergent?(difference(X, Y)))
  sigma_difference_TCC1: OBLIGATION
    FORALL (X, Y: countable_set[T], f: (convergent?[T](union[T](X, Y)))):
      convergent?[T](difference[T](X, Y))(f);

  % Subtype TCC generated (at line 79, column 59) for  f
      % expected type  (convergent?(difference(Y, X)))
  sigma_difference_TCC2: OBLIGATION
    FORALL (X, Y: countable_set[T], f: (convergent?[T](union[T](X, Y)))):
      convergent?[T](difference[T](Y, X))(f);

  % Subtype TCC generated (at line 82, column 41) for  f
      % expected type  (convergent?(X))
  sigma_subset_TCC1: OBLIGATION
    FORALL (X, Y: countable_set[T], f: (convergent?[T](Y))):
      subset?(X, Y) IMPLIES convergent?[T](X)(f);

  % Subtype TCC generated (at line 82, column 68) for  f
      % expected type  (convergent?(difference(Y, X)))
  sigma_subset_TCC2: OBLIGATION
    FORALL (X, Y: countable_set[T], f: (convergent?[T](Y))):
      subset?(X, Y) IMPLIES convergent?[T](difference[T](Y, X))(f);

  % Subtype TCC generated (at line 85, column 21) for  f
      % expected type  (convergent?(add(t, X)))
  sigma_add_TCC1: OBLIGATION
    FORALL (X: countable_set[T], t: T, f: (convergent?[T](X))):
      convergent?[T](add[T](t, X))(f);

  % Subtype TCC generated (at line 89, column 24) for  f
      % expected type  (convergent?(remove(t, X)))
  sigma_remove_TCC1: OBLIGATION
    FORALL (X: countable_set[T], t: T, f: (convergent?[T](X))):
      convergent?[T](remove[T](t, X))(f);

  % Subtype TCC generated (at line 93, column 69) for  f
      % expected type  (convergent?(rest(X)))
  sigma_choose_rest_TCC1: OBLIGATION
    FORALL (X: nonempty_countable, f: (convergent?[T](X))):
      convergent?[T](rest[T](X))(f);

  % Subtype TCC generated (at line 95, column 28) for  LAMBDA t: 0
      % expected type  (convergent?(X))
  sigma_zero_TCC1: OBLIGATION
    FORALL (X: countable_set[T]): convergent?[T](X)(LAMBDA t: 0);

  % Subtype TCC generated (at line 97, column 57) for  a * f
      % expected type  (convergent?(X))
  sigma_scal_TCC1: OBLIGATION
    FORALL (X: countable_set[T], a: real, f: (convergent?[T](X))):
      convergent?[T](X)(*[T](a, f));

  % Subtype TCC generated (at line 99, column 57) for  -f
      % expected type  (convergent?(X))
  sigma_opp_TCC1: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X))):
      convergent?[T](X)(-f);

  % Subtype TCC generated (at line 102, column 46) for  f + g
      % expected type  (convergent?(X))
  sigma_plus_TCC1: OBLIGATION
    FORALL (X: countable_set[T], f, g: (convergent?[T](X))):
      convergent?[T](X)((+[T])(f, g));

  % Subtype TCC generated (at line 105, column 46) for  f - g
      % expected type  (convergent?(X))
  sigma_diff_TCC1: OBLIGATION
    FORALL (X: countable_set[T], f, g: (convergent?[T](X))):
      convergent?[T](X)((-[T])(f, g));

  % Subtype TCC generated (at line 114, column 65) for  abs(f)
      % expected type  (convergent?(X))
  sigma_abs_TCC1: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X))):
      convergent?[T](X)(abs[T](f));

  % Subtype TCC generated (at line 130, column 27) for
      % extend[T, (X), real, 0](f o phi)
      % expected type  (convergent?(X))
  sigma_bij_TCC1: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X)),
            phi: (bijective?[(X), (X)])):
      convergent?[T](X)(extend[T, (X), real, 0](o[(X), T, real](f, phi)));

  % Subtype TCC generated (at line 137, column 61) for  f
      % expected type  (convergent?(F))
  sigma_nn_def_TCC1: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X))):
      (FORALL t: X(t) => f(t) >= 0) IMPLIES
       (FORALL (F: finite_set[T]):
          subset?(F, X) IMPLIES convergent?[T](F)(f));

  % Subtype TCC generated (at line 136, column 23) for
      % {nnx | EXISTS (F: finite_set[T]): subset?(F, X) AND nnx = sigma(F, f)}
      % expected type  Su: sup_set[nnreal]
  sigma_nn_def_TCC2: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X))):
      (FORALL t: X(t) => f(t) >= 0) IMPLIES
       nonempty?[nnreal]
           ({nnx |
               EXISTS (F: finite_set[T]):
                 subset?[T](F, X) AND nnx = sigma(F, f)})
        AND
        above_bounded[nnreal]
            ({nnx |
                EXISTS (F: finite_set[T]):
                  subset?[T](F, X) AND nnx = sigma(F, f)});

  % Subtype TCC generated (at line 144, column 54) for  f
      % expected type  (convergent?(F))
  sigma_def_TCC1: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X)), F: finite_set[T]):
      (FORALL t: F(t) => f(t) >= 0) AND subset?(F, X) IMPLIES
       convergent?[T](F)(f);

  % Subtype TCC generated (at line 142, column 23) for
      % {nnx |
      %    EXISTS (F: finite_set[T]):
      %      subset?(F, X) AND
      %       (FORALL t: F(t) => f(t) >= 0) AND nnx = sigma(F, f)}
      % expected type  Su: sup_set[nnreal]
  sigma_def_TCC2: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X))):
      nonempty?[nnreal]
          ({nnx |
              EXISTS (F: finite_set[T]):
                subset?[T](F, X) AND
                 (FORALL t: F(t) => f(t) >= 0) AND nnx = sigma(F, f)})
       AND
       above_bounded[nnreal]
           ({nnx |
               EXISTS (F: finite_set[T]):
                 subset?[T](F, X) AND
                  (FORALL t: F(t) => f(t) >= 0) AND nnx = sigma(F, f)});

  % Subtype TCC generated (at line 147, column 55) for  f
      % expected type  (convergent?(F))
  sigma_def_TCC3: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X)), F: finite_set[T]):
      (FORALL t: F(t) => f(t) <= 0) AND subset?(F, X) IMPLIES
       convergent?[T](F)(f);

  % Subtype TCC generated (at line 145, column 23) for
      % {npx |
      %    EXISTS (F: finite_set[T]):
      %      subset?(F, X) AND
      %       (FORALL t: F(t) => f(t) <= 0) AND npx = sigma(F, f)}
      % expected type  Sl: inf_set[npreal]
  sigma_def_TCC4: OBLIGATION
    FORALL (X: countable_set[T], f: (convergent?[T](X))):
      nonempty?[npreal]
          ({npx |
              EXISTS (F: finite_set[T]):
                subset?[T](F, X) AND
                 (FORALL t: F(t) => f(t) <= 0) AND npx = sigma(F, f)})
       AND
       below_bounded[npreal]
           ({npx |
               EXISTS (F: finite_set[T]):
                 subset?[T](F, X) AND
                  (FORALL t: F(t) => f(t) <= 0) AND npx = sigma(F, f)});


body:
  sigma_set[T:TYPE]: THEORY
  %------------------------------------------------------------------------------
  % The sigma_set theory introduces and defines properties of the sigma 
  % function that sums an arbitrary function F: [T -> real] over a
  % set of values X. To make this sensible for infinite sets, we will
  % require that the subset of X for which f(x)/=0 be countable and absolutely
  % convergent in the infinite case.
  %
  % This notation is a vital simplification for Hilbert Space.
  %
  %                         ----
  %  sigma(X, f)         =  \     f(x)
  %                         /
  %                         ----
  %                      member(x,X)
  %
  %
  %  MODIFICATIONS:
  %
  %     Author: David Lester, Manchester University 2/12/07
  %
  %------------------------------------------------------------------------------


  BEGIN

    IMPORTING sigma_countable[T],
              convergence_set[T]

    a:   VAR real
    nz:  VAR nzreal
    X,Y: VAR set[T]
    t:   VAR T
    f,g: VAR [T -> real]
    F:   VAR non_empty_finite_set[T]
    n:   VAR nat
    phi: VAR (bijective?[nat,nat])
    C:   VAR countable_set[T]

    sigma(X:set[T],f:(convergent?(X))):real = sigma(nonzero_elts(f,X),f)

    sigma_countable: LEMMA FORALL (f:(countable_convergence.convergent?(C))):
                           sigma(C,f) = sigma_countable.sigma(C,f)

    sigma_empty: LEMMA sigma(emptyset[T],g) = 0

    sigma_finite: LEMMA sigma(F,g) = sigma_countable.sigma(F,g)

    sigma_singleton: LEMMA sigma(singleton(t),g) = g(t)

    sigma_disjoint_union: LEMMA FORALL (f:(convergent?(union(X,Y)))):
      disjoint?(X,Y) => sigma(union(X,Y),f) = sigma(X,f) + sigma(Y,f)

    sigma_union: LEMMA FORALL (f:(convergent?(union(X,Y)))):
      sigma(union(X,Y),f) = sigma(X,f) + sigma(Y,f) - sigma(intersection(X,Y),f)

    sigma_intersection: LEMMA FORALL (f:(convergent?(union(X,Y)))):
      sigma(intersection(X,Y),f) = sigma(X,f) + sigma(Y,f) - sigma(union(X,Y),f)

    sigma_difference: LEMMA FORALL (f:(convergent?(union(X,Y)))):
      sigma(difference(X,Y),f) 
           = sigma(X,f) - sigma(Y,f) + sigma(difference(Y,X),f)

    sigma_subset: LEMMA FORALL (f:(convergent?(Y))):
      subset?(X,Y) => sigma(Y,f) = sigma(X,f) + sigma(difference(Y,X),f)

    sigma_add: LEMMA FORALL (f:(convergent?(X))):
        sigma(add(t,X),f) = IF member(t,X) THEN sigma(X,f)
                                           ELSE f(t) + sigma(X,f) ENDIF

    sigma_remove: LEMMA FORALL (f:(convergent?(X))):
        sigma(remove(t,X),f) = IF member(t,X) THEN sigma(X,f) - f(t)
                                              ELSE sigma(X,f) ENDIF

    sigma_choose_rest: LEMMA FORALL (X:nonempty_set[T],
                                     f:(convergence_set.convergent?(X))):
                             sigma(X,f) = f(choose(X)) + sigma(rest(X),f)

    sigma_zero: LEMMA sigma(X,LAMBDA t: 0) = 0

    sigma_scal: LEMMA FORALL (f:(convergent?(X))): sigma(X,a*f) = a*sigma(X,f)

    sigma_opp:  LEMMA FORALL (f:(convergent?(X))): sigma(X,-f)  = -sigma(X,f)

    sigma_plus: LEMMA FORALL (f,g:(convergent?(X))):
                                        sigma(X,f+g) = sigma(X,f) + sigma(X,g)

    sigma_diff: LEMMA FORALL (f,g:(convergent?(X))):
                                        sigma(X,f-g) = sigma(X,f) - sigma(X,g)

    sigma_ge_0: LEMMA FORALL (f:(convergent?(X))):
                             (FORALL (t:(X)): f(t) >= 0) => sigma(X,f) >= 0

    sigma_gt_0: LEMMA FORALL (f:(convergent?(X))):
                             (FORALL (t:(X)): f(t) >= 0) AND
                             (EXISTS (t:(X)): f(t) >  0) => sigma(X,f) > 0

    sigma_abs:  LEMMA FORALL (f:(convergent?(X))):
                                        abs(sigma(X,f)) <= sigma(X,abs(f))

    sigma_eq:   LEMMA FORALL (f,g:(convergent?(X))):
                      (FORALL (t:(X)): f(t) =  g(t)) => sigma(X,f) =  sigma(X,g)
   
    sigma_le:   LEMMA FORALL (f,g:(convergent?(X))):
                      (FORALL (t:(X)): f(t) <= g(t)) => sigma(X,f) <= sigma(X,g)

    sigma_lt:   LEMMA FORALL (f,g:(convergent?(X))):
                      (FORALL (t:(X)): f(t) <=  g(t)) AND
                      (EXISTS (t:(X)): f(t) <   g(t)) => sigma(X,f) <  sigma(X,g)

  END sigma_set

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

  % Subtype TCC generated (at line 40, column 50) for  nonzero_elts(f, X)
      % expected type  countable_set[T]
  sigma_TCC1: OBLIGATION
    FORALL (X: set[T], f: (convergent?[T](X))):
      is_countable[T](nonzero_elts[T](f, X));

  % Subtype TCC generated (at line 40, column 68) for  f
      % expected type  (convergent?(nonzero_elts(f, X)))
  sigma_TCC2: OBLIGATION
    FORALL (X: set[T], f: (convergent?[T](X))):
      convergent?[T](nonzero_elts[T](f, X))(f);

  % Subtype TCC generated (at line 43, column 33) for  f
      % expected type  (convergent?(C))
  sigma_countable_TCC1: OBLIGATION
    FORALL (C: countable_set[T],
            f: (countable_convergence[T].convergent?(C))):
      convergent?[T](C)(f);

  % Subtype TCC generated (at line 45, column 39) for  g
      % expected type  (convergent?(emptyset[T]))
  sigma_empty_TCC1: OBLIGATION
    FORALL (g: [T -> real]): convergent?[T](emptyset[T])(g);

  % Subtype TCC generated (at line 47, column 30) for  g
      % expected type  (convergent?(F))
  sigma_finite_TCC1: OBLIGATION
    FORALL (F: non_empty_finite_set[T], g: [T -> real]): convergent?[T](F)(g);

  % Subtype TCC generated (at line 47, column 59) for  g
      % expected type  (convergent?(F))
  sigma_finite_TCC2: OBLIGATION
    FORALL (F: non_empty_finite_set[T], g: [T -> real]): convergent?[T](F)(g);

  % Subtype TCC generated (at line 49, column 44) for  g
      % expected type  (convergent?(singleton(t)))
  sigma_singleton_TCC1: OBLIGATION
    FORALL (g: [T -> real], t: T): convergent?[T](singleton[T](t))(g);

  % Subtype TCC generated (at line 52, column 52) for  f
      % expected type  (convergent?(X))
  sigma_disjoint_union_TCC1: OBLIGATION
    FORALL (X, Y: set[T], f: (convergent?[T](union[T](X, Y)))):
      disjoint?(X, Y) IMPLIES convergent?[T](X)(f);

  % Subtype TCC generated (at line 52, column 65) for  f
      % expected type  (convergent?(Y))
  sigma_disjoint_union_TCC2: OBLIGATION
    FORALL (X, Y: set[T], f: (convergent?[T](union[T](X, Y)))):
      disjoint?(X, Y) IMPLIES convergent?[T](Y)(f);

  % Subtype TCC generated (at line 55, column 34) for  f
      % expected type  (convergent?(X))
  sigma_union_TCC1: OBLIGATION
    FORALL (X, Y: set[T], f: (convergent?[T](union[T](X, Y)))):
      convergent?[T](X)(f);

  % Subtype TCC generated (at line 55, column 47) for  f
      % expected type  (convergent?(Y))
  sigma_union_TCC2: OBLIGATION
    FORALL (X, Y: set[T], f: (convergent?[T](union[T](X, Y)))):
      convergent?[T](Y)(f);

  % Subtype TCC generated (at line 55, column 76) for  f
      % expected type  (convergent?(intersection(X, Y)))
  sigma_union_TCC3: OBLIGATION
    FORALL (X, Y: set[T], f: (convergent?[T](union[T](X, Y)))):
      convergent?[T](intersection[T](X, Y))(f);

  % Subtype TCC generated (at line 61, column 26) for  f
      % expected type  (convergent?(difference(X, Y)))
  sigma_difference_TCC1: OBLIGATION
    FORALL (X, Y: set[T], f: (convergent?[T](union[T](X, Y)))):
      convergent?[T](difference[T](X, Y))(f);

  % Subtype TCC generated (at line 62, column 59) for  f
      % expected type  (convergent?(difference(Y, X)))
  sigma_difference_TCC2: OBLIGATION
    FORALL (X, Y: set[T], f: (convergent?[T](union[T](X, Y)))):
      convergent?[T](difference[T](Y, X))(f);

  % Subtype TCC generated (at line 65, column 41) for  f
      % expected type  (convergent?(X))
  sigma_subset_TCC1: OBLIGATION
    FORALL (X, Y: set[T], f: (convergent?[T](Y))):
      subset?(X, Y) IMPLIES convergent?[T](X)(f);

  % Subtype TCC generated (at line 65, column 68) for  f
      % expected type  (convergent?(difference(Y, X)))
  sigma_subset_TCC2: OBLIGATION
    FORALL (X, Y: set[T], f: (convergent?[T](Y))):
      subset?(X, Y) IMPLIES convergent?[T](difference[T](Y, X))(f);

  % Subtype TCC generated (at line 68, column 21) for  f
      % expected type  (convergent?(add(t, X)))
  sigma_add_TCC1: OBLIGATION
    FORALL (X: set[T], t: T, f: (convergent?[T](X))):
      convergent?[T](add[T](t, X))(f);

  % Subtype TCC generated (at line 72, column 24) for  f
      % expected type  (convergent?(remove(t, X)))
  sigma_remove_TCC1: OBLIGATION
    FORALL (X: set[T], t: T, f: (convergent?[T](X))):
      convergent?[T](remove[T](t, X))(f);

  % Subtype TCC generated (at line 77, column 69) for  f
      % expected type  (convergent?(rest(X)))
  sigma_choose_rest_TCC1: OBLIGATION
    FORALL (X: nonempty_set[T], f: (convergence_set[T].convergent?(X))):
      convergent?[T](rest[T](X))(f);

  % Subtype TCC generated (at line 79, column 28) for  LAMBDA t: 0
      % expected type  (convergent?(X))
  sigma_zero_TCC1: OBLIGATION
    FORALL (X: set[T]): convergent?[T](X)(LAMBDA t: 0);

  % Subtype TCC generated (at line 81, column 57) for  a * f
      % expected type  (convergent?(X))
  sigma_scal_TCC1: OBLIGATION
    FORALL (X: set[T], a: real, f: (convergent?[T](X))):
      convergent?[T](X)(*[T](a, f));

  % Subtype TCC generated (at line 83, column 57) for  -f
      % expected type  (convergent?(X))
  sigma_opp_TCC1: OBLIGATION
    FORALL (X: set[T], f: (convergent?[T](X))): convergent?[T](X)(-f);

  % Subtype TCC generated (at line 86, column 46) for  f + g
      % expected type  (convergent?(X))
  sigma_plus_TCC1: OBLIGATION
    FORALL (X: set[T], f, g: (convergent?[T](X))):
      convergent?[T](X)((+[T])(f, g));

  % Subtype TCC generated (at line 89, column 46) for  f - g
      % expected type  (convergent?(X))
  sigma_diff_TCC1: OBLIGATION
    FORALL (X: set[T], f, g: (convergent?[T](X))):
      convergent?[T](X)((-[T])(f, g));

  % Subtype TCC generated (at line 99, column 65) for  abs(f)
      % expected type  (convergent?(X))
  sigma_abs_TCC1: OBLIGATION
    FORALL (X: set[T], f: (convergent?[T](X))): convergent?[T](X)(abs[T](f));


body:
  %------------------------------------------------------------------------------
  % Topological Spaces
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            1/11/06  Initial Version
  %     Version 1.1            9/14/09
  %------------------------------------------------------------------------------

  top: THEORY

  BEGIN

    IMPORTING top_basic,        % Basic properties
              top_continuity,   % continuity done topologically
              top_homeomorphic, % structure preserving maps (homeomorphisms)
              top_convergence,  % Convergence in topological spaces
              top_connected,    % Connected Topological Spaces
              top_compact       % Compact Topological Spaces

  END top


body:
  %------------------------------------------------------------------------------
  % Topology prelim file
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            8/7/04   Initial Version
  %     Version 1.1            1/12/06  Basis material moved to basis.pvs (DRL)
  %------------------------------------------------------------------------------

  topology_prelim[T:TYPE]: THEORY

  BEGIN

    AUTO_REWRITE+  member

    x,y:   VAR T
    A,B:   VAR set[T]  
    S,U,V: VAR setofsets[T]

    topology_empty?(S):       bool = member(emptyset[T],S)
    topology_full?(S):        bool = member(fullset[T], S)
    topology_Union?(S):       bool = FORALL U: subset?(U,S) =>
                                                       member(Union(U),S)
    topology_intersection?(S):bool = FORALL (A,B:(S)):member(intersection(A,B),S)

  % The following is Sutherland Definition 3.1.1 (except we've permitted
  % the type T to be empty).

    topology?(S):bool = topology_empty?(S) AND topology_full?(S)         AND
                        topology_Union?(S) AND topology_intersection?(S)
                                                                      % Def 3.1.1

    discrete_topology_set  : setofsets[T] = powerset(fullset[T])
    indiscrete_topology_set: setofsets[T] = {A | empty?(A) OR full?(A)}

    discrete_topology_lem  : LEMMA topology?(discrete_topology_set)   % Ex  3.1.4
    indiscrete_topology_lem: LEMMA topology?(indiscrete_topology_set) % Ex  3.1.6

    topology: TYPE+ = (topology?) CONTAINING discrete_topology_set

    discrete_topology  : topology = discrete_topology_set
    indiscrete_topology: topology = indiscrete_topology_set

  % We now define some common separation conditions for topologies.
  % The important one is T2 (or Hausdorff); motto:
  %   "In a Hausdorff Space, every point can be housed off from every
  %    other point by disjoint open sets."
   
    is_T0?(S):bool = FORALL x,y: x /= y => EXISTS (U:(S)):
                            (member(x,U) AND NOT member(y,U)) OR
                            (member(y,U) AND NOT member(x,U))

    is_T1?(S):bool = FORALL x,y: x /= y => EXISTS (U:(S)):
                            (member(x,U) AND NOT member(y,U))

    is_T2?(S):bool = FORALL x,y: x /= y => EXISTS (U,V:(S)):
                            disjoint?(U,V) AND member(x,U) AND member(y,V)

    hausdorff?(S):bool = is_T2?(S)                                    % Def 4.2.1

    T0_space?(S):bool        = topology?(S) AND is_T0?(S)
    T1_space?(S):bool        = topology?(S) AND is_T1?(S)
    T2_space?(S):bool        = topology?(S) AND is_T2?(S)
    hausdorff_space?(S):bool = topology?(S) AND hausdorff?(S)

    T0_topology: TYPE+ = (T0_space?)        CONTAINING discrete_topology
    T1_topology: TYPE+ = (T1_space?)        CONTAINING discrete_topology
    T2_topology: TYPE+ = (T2_space?)        CONTAINING discrete_topology
    hausdorff:   TYPE+ = (hausdorff_space?) CONTAINING discrete_topology

    T0_is_topology:  JUDGEMENT T1_topology SUBTYPE_OF topology
    T1_is_T0:        JUDGEMENT T1_topology SUBTYPE_OF T0_topology
    T2_is_T1:        JUDGEMENT T2_topology SUBTYPE_OF T1_topology
    hausdorff_is_T2: JUDGEMENT hausdorff   SUBTYPE_OF T2_topology
    T2_is_hausdorff: JUDGEMENT T2_topology SUBTYPE_OF hausdorff

  % We now define compactness. Motto:
  %   "If a city is compact, it can be guarded by a finite number of
  %    arbitrarily short-sighted policemen."                  H Weyl.

    cover?(U,A)        : bool = subset?(A,Union(U))                   % Def 5.2.1
    finite_cover?(U,A) : bool = is_finite(U) AND cover?(U,A)          % Def 5.2.1
    subcover?(V,U,A)   : bool = cover?(U,A) AND cover?(V,A) AND
                                subset?(V,U)                          % Def 5.2.1
    open_cover?(U,A,S) : bool = subset?(U,S) AND cover?(U,A)          % Def 5.2.1

    compact_subset?(S,A):bool = FORALL U: open_cover?(U,A,S) =>       % Def 5.2.2
                                EXISTS V: subset?(V,U) AND finite_cover?(V,A)

    compact_space?(S): bool = topology?(S) AND compact_subset?(S,Union(S))

    compact_hausdorff?(S): bool = hausdorff?(S) AND compact_space?(S)

    compact_space:     TYPE+ = (compact_space?) CONTAINING indiscrete_topology
    compact_hausdorff: TYPE  = (compact_hausdorff?)

    compact_space_is_topology: JUDGEMENT compact_space     SUBTYPE_OF topology
    compact_hausdorff_is_topology:
                               JUDGEMENT compact_hausdorff SUBTYPE_OF topology
    compact_hausdorff_is_hausdorff:
                               JUDGEMENT compact_hausdorff SUBTYPE_OF hausdorff
    compact_hausdorff_is_compact_space:
                             JUDGEMENT compact_hausdorff SUBTYPE_OF compact_space

    connected?(S): bool = FORALL (A:(S)): S(complement(A)) =>
                                 (A = emptyset[T] OR A = fullset[T])  % Def 6.2.4

    connected_space?(S): bool = topology?(S) AND connected?(S)

    connected_space: TYPE+ = (connected_space?) CONTAINING indiscrete_topology

    connected_space_is_topology: JUDGEMENT connected_space SUBTYPE_OF topology

  END topology_prelim

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

  % Subtype TCC generated (at line 42, column 43) for  discrete_topology_set
      % expected type  topology
  topology_TCC1: OBLIGATION topology?(discrete_topology_set);

  % Subtype TCC generated (at line 45, column 34) for  indiscrete_topology_set
      % expected type  topology
  indiscrete_topology_TCC1: OBLIGATION topology?(indiscrete_topology_set);

  % Subtype TCC generated (at line 69, column 53) for  discrete_topology
      % expected type  T0_topology
  T0_topology_TCC1: OBLIGATION T0_space?(discrete_topology);

  % Subtype TCC generated (at line 70, column 53) for  discrete_topology
      % expected type  T1_topology
  T1_topology_TCC1: OBLIGATION T1_space?(discrete_topology);

  % Subtype TCC generated (at line 71, column 53) for  discrete_topology
      % expected type  T2_topology
  T2_topology_TCC1: OBLIGATION T2_space?(discrete_topology);

  % Subtype TCC generated (at line 72, column 53) for  discrete_topology
      % expected type  hausdorff
  hausdorff_TCC1: OBLIGATION hausdorff_space?(discrete_topology);

  % Judgement subtype TCC generated (at line 74, column 29) for  x
      % expected type  topology
  T0_is_topology: OBLIGATION FORALL (x: T1_topology): topology?(x);

  % Judgement subtype TCC generated (at line 75, column 29) for  x
      % expected type  T0_topology
  T1_is_T0: OBLIGATION FORALL (x: T1_topology): T0_space?(x);

  % Judgement subtype TCC generated (at line 76, column 29) for  x
      % expected type  T1_topology
  T2_is_T1: OBLIGATION FORALL (x: T2_topology): T1_space?(x);

  % Judgement subtype TCC generated (at line 77, column 29) for  x
      % expected type  T2_topology
  hausdorff_is_T2: OBLIGATION FORALL (x: hausdorff): T2_space?(x);

  % Judgement subtype TCC generated (at line 78, column 29) for  x
      % expected type  hausdorff
  T2_is_hausdorff: OBLIGATION FORALL (x: T2_topology): hausdorff_space?(x);

  % Subtype TCC generated (at line 97, column 57) for  indiscrete_topology
      % expected type  compact_space
  compact_space_TCC1: OBLIGATION compact_space?(indiscrete_topology);

  % Judgement subtype TCC generated (at line 100, column 39) for  x
      % expected type  topology
  compact_space_is_topology: OBLIGATION
    FORALL (x: compact_space): topology?(x);

  % Judgement subtype TCC generated (at line 102, column 39) for  x
      % expected type  topology
  compact_hausdorff_is_topology: OBLIGATION
    FORALL (x: compact_hausdorff): topology?(x);

  % Judgement subtype TCC generated (at line 104, column 39) for  x
      % expected type  hausdorff
  compact_hausdorff_is_hausdorff: OBLIGATION
    FORALL (x: compact_hausdorff): hausdorff_space?(x);

  % Judgement subtype TCC generated (at line 106, column 37) for  x
      % expected type  compact_space
  compact_hausdorff_is_compact_space: OBLIGATION
    FORALL (x: compact_hausdorff): compact_space?(x);

  % Subtype TCC generated (at line 113, column 57) for  indiscrete_topology
      % expected type  connected_space
  connected_space_TCC1: OBLIGATION connected_space?(indiscrete_topology);

  % Judgement subtype TCC generated (at line 115, column 41) for  x
      % expected type  topology
  connected_space_is_topology: OBLIGATION
    FORALL (x: connected_space): topology?(x);


body:
  %------------------------------------------------------------------------------
  % Various odds & ends for prelude libraries
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            9/06/06  Initial Version
  %------------------------------------------------------------------------------

  prelude_sets_aux[T:TYPE]: THEORY

  BEGIN

    finite_setofsets_is_setofsets:
                            JUDGEMENT finite_set[set[T]] SUBTYPE_OF setofsets[T]

    x:   VAR T
    A:   VAR setofsets[T]
    a,b: VAR set[T]
    F:   VAR finite_set[set[T]]
    P:   VAR [set[T]->bool]

    complement_difference: LEMMA
      complement(difference(a,b)) = union(complement(a),b)

    Intersection_member:
               LEMMA member(x,Intersection(A)) IFF (FORALL (a:(A)): member(x,a))

    Intersection_split: LEMMA nonempty?(A) =>
               (Intersection(A) = intersection(choose(A),Intersection(rest(A))))

    Intersection_finite: LEMMA
          P(fullset[T]) AND is_finite(A) AND (FORALL (a:(A)): P(a)) AND
          (FORALL (a,b:set[T]): P(a) AND P(b) => P(intersection(a,b)))
                                  => P(Intersection(A))

    Union_member: LEMMA member(x,Union(A)) IFF (EXISTS (a:(A)): member(x,a)) 

    Union_split: LEMMA nonempty?(A) =>
                       (Union(A) = union(choose(A),Union(rest(A))))

    Union_finite: LEMMA
          P(emptyset[T]) AND is_finite(A) AND (FORALL (a:(A)): P(a)) AND
          (FORALL (a,b:set[T]): P(a) AND P(b) => P(union(a,b))) => P(Union(A))

    finite_Complement: LEMMA is_finite(Complement(F))

  END prelude_sets_aux


body:
  %------------------------------------------------------------------------------
  % Topological Bases

  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % The material presented here comes from Sutherland Chapter 3, Section 2
  %
  %     Version 1.0            1/11/06  Initial Version
  %------------------------------------------------------------------------------

  basis[T:TYPE]: THEORY

  BEGIN

    IMPORTING topology_prelim[T]

    t:     VAR topology
    U,V,W: VAR setofsets[T]
    A:     VAR set[T]

    base?(t)(U):bool = subset?(U,t) AND
                       FORALL (A:(t)): EXISTS V: subset?(V,U) AND Union(V) = A
                                                                      % Def 3.2.1

    base?(t,U):bool = base?(t)(U)

    synthetic_base?(U):bool
     = (EXISTS V: subset?(V,U) AND Union(V) = fullset[T]) AND
       FORALL (B1,B2:(U)): (EXISTS V: subset?(V,U) AND
                                     Union(V) = intersection(B1,B2))  % Def 3.2.2

    synthetic_base: TYPE = (synthetic_base?)

    synthetic_base_is_setofsets: JUDGEMENT synthetic_base SUBTYPE_OF setofsets[T]

    B: VAR synthetic_base

    synthetic_generated_topology_set(B):setofsets[T]
      = {A | EXISTS V: subset?(V,B) AND Union(V) = A}

    synthetic_generated_def: LEMMA
      member(A,synthetic_generated_topology_set(B)) IFF
      EXISTS V: subset?(V,B) AND Union(V) = A

    synthetic_generated_alt_def: LEMMA
      member(A,synthetic_generated_topology_set(B)) IFF
      A = Union({x:(B) | subset?(x,A)})

    synthetic_generated_empty:
         LEMMA member(emptyset[T],synthetic_generated_topology_set(B))

    synthetic_generated_full:
         LEMMA member(fullset[T],synthetic_generated_topology_set(B))

    synthetic_generated_Union:
         LEMMA topology_Union?(synthetic_generated_topology_set(B))

    synthetic_generated_intersection:
         LEMMA topology_intersection?(synthetic_generated_topology_set(B))

    synthetic_generated_topology(B):topology
      = {A | EXISTS V: subset?(V,B) AND Union(V) = A}

    synthetic_basis_is_topology:
         JUDGEMENT synthetic_generated_topology_set(B) HAS_TYPE topology

    base_is_synthetic_base: LEMMA base?(t)(U) => synthetic_base?(U)

    synthetic_base_is_base:
         LEMMA base?(synthetic_generated_topology_set(B))(B)

    subbase?(t)(U):bool
     = subset?(U,t) AND
       base?(t)({A | EXISTS V: is_finite(V) AND subset?(V,U) AND
                               A = Intersection(V)})

    subbase?(t,U):bool = subbase?(t)(U)

    synthetic_subbase?(U):bool
     = synthetic_base?({A | EXISTS V: is_finite(V) AND subset?(V,U) AND
                                      A = Intersection(V)})

    synthetic_subbase: TYPE = (synthetic_subbase?)

    synthetic_subbase_is_setofsets:
                              JUDGEMENT synthetic_subbase SUBTYPE_OF setofsets[T]

    S: VAR synthetic_subbase

  %  synthetic_base_is_synthetic_subbase:
  %                         JUDGEMENT synthetic_base SUBTYPE_OF synthetic_subbase



  END basis

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

  % Subtype TCC generated (at line 65, column 6) for
      % {A | EXISTS V: subset?(V, B) AND Union(V) = A}
      % expected type  topology[T]
  synthetic_generated_topology_TCC1: OBLIGATION
    FORALL (B: synthetic_base):
      topology?[T]
          ({A | EXISTS V: subset?[setof[T]](V, B) AND Union[T](V) = A});

  % Judgement subtype TCC generated (at line 68, column 17) for
      % synthetic_generated_topology_set(B)
      % expected type  topology[T]
  synthetic_basis_is_topology: OBLIGATION
    FORALL (B): topology?[T](synthetic_generated_topology_set(B));


body:
  %------------------------------------------------------------------------------
  % Topology definition file
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            8/7/04   Initial Version
  %     Version 1.1            1/12/06  Basis material moved to basis.pvs (DRL)
  %------------------------------------------------------------------------------

  topology_def[T:TYPE]: THEORY

  BEGIN

    S,B: VAR setofsets[T]

    IMPORTING topology_prelim[T],
              basis[T],
              sets_aux@countability

    has_countable_basis?(S):bool
      = EXISTS B: is_countable(B) AND synthetic_base?(B) AND
                  synthetic_generated_topology_set(B) = S

    second_countable?(S):bool = topology?(S) AND has_countable_basis?(S)

    second_countable: TYPE = (second_countable?)

    second_countable_is_topology: JUDGEMENT second_countable SUBTYPE_OF topology

  END topology_def

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

  % Judgement subtype TCC generated (at line 31, column 42) for  x
      % expected type  topology[T]
  second_countable_is_topology: OBLIGATION
    FORALL (x: second_countable): topology?[T](x);


body:
  %------------------------------------------------------------------------------
  % Topology
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            8/10/04  Initial Version
  %     Version 1.1            1/11/06  Basis material moved to basis.pvs
  %     Version 1.2            6/8/06   open/closed defs & Type Judgements added
  %------------------------------------------------------------------------------

  topology[T:TYPE, (IMPORTING topology_def[T]) S:topology]: THEORY

  BEGIN

    IMPORTING prelude_sets_aux[T],
              topology_prelim[T]

    AUTO_REWRITE+  member

    x:       VAR T
    A,B:     VAR set[T]

    open?(A)   : bool = member(A,S)
    closed?(A) : bool = member(complement(A),S)
    clopen?(A) : bool = closed?(A) AND open?(A)
    compact?(A): bool = compact_subset?(S,A)

    open_set:   TYPE+ = (open?)   CONTAINING emptyset[T]
    closed_set: TYPE+ = (closed?) CONTAINING emptyset[T]
    clopen_set: TYPE+ = (clopen?) CONTAINING emptyset[T]

    open:    TYPE+ = (open?)    CONTAINING emptyset[T]
    closed:  TYPE+ = (closed?)  CONTAINING emptyset[T]
    clopen:  TYPE+ = (clopen?)  CONTAINING emptyset[T]
    compact: TYPE+ = (compact?) CONTAINING emptyset[T]

    open_set_is_open:     JUDGEMENT open_set   SUBTYPE_OF open
    closed_set_is_closed: JUDGEMENT closed_set SUBTYPE_OF closed
    clopen_set_is_open:   JUDGEMENT clopen_set SUBTYPE_OF open
    clopen_set_is_closed: JUDGEMENT clopen_set SUBTYPE_OF closed
    open_is_open_set:     JUDGEMENT open       SUBTYPE_OF open_set
    closed_is_closed_set: JUDGEMENT closed     SUBTYPE_OF closed_set
    clopen_is_open_set:   JUDGEMENT clopen     SUBTYPE_OF open_set
    clopen_is_closed_set: JUDGEMENT clopen     SUBTYPE_OF closed_set

    U,U1,U2: VAR open
    V,V1,V2: VAR closed
    C1,C2:   VAR compact
    Y,Y1,Y2: VAR setofsets[T]

    interior_point?(x,A): bool = EXISTS U: subset?(U,A) AND member(x,U)
    neighbourhood?(A,x) : bool = interior_point?(x,A)
    adherent_point?(x,A): bool = FORALL U: neighbourhood?(U,x) =>
                                           nonempty?(intersection(U,A))
    limit_point?(x,A)   : bool = adherent_point?(x,A) AND NOT member(x,A)

    interior(A)         : set[T] = {x:(A) | interior_point?(x,A)}
    Cl(A)               : set[T] = {x | adherent_point?(x,A)}
    derived_set(A)      : set[T] = {x | limit_point?(x,A)}

    open_complement:     LEMMA open?(complement(A))   IFF closed?(A)
    closed_complement:   LEMMA closed?(complement(A)) IFF open?(A)

    open_emptyset:       LEMMA open?(emptyset[T])
    open_fullset:        LEMMA open?(fullset[T])
    open_Union:          LEMMA every(open?,Y) => open?(Union(Y))
    open_union:          LEMMA open?(union(U1,U2))
    open_intersection:   LEMMA open?(intersection(U1,U2))
    open_Intersection:   LEMMA is_finite(Y) AND every(open?,Y) =>
                               open?(Intersection(Y))
    closed_emptyset:     LEMMA closed?(emptyset[T])
    closed_fullset:      LEMMA closed?(fullset[T])
    closed_Intersection: LEMMA every(closed?,Y) => closed?(Intersection(Y))
    closed_intersection: LEMMA closed?(intersection(V1,V2))
    closed_union:        LEMMA closed?(union(V1,V2))
    closed_Union:        LEMMA is_finite(Y) AND every(closed?,Y) =>
                               closed?(Union(Y))

    complement_open_is_closed: JUDGEMENT complement(U)       HAS_TYPE closed
    complement_closed_is_open: JUDGEMENT complement(V)       HAS_TYPE open

    emptyset_is_open:          JUDGEMENT emptyset[T]         HAS_TYPE open
    fullset_is_open:           JUDGEMENT fullset[T]          HAS_TYPE open
    union_is_open:             JUDGEMENT union(U1,U2)        HAS_TYPE open
    intersection_is_open:      JUDGEMENT intersection(U1,U2) HAS_TYPE open

    emptyset_is_closed:        JUDGEMENT emptyset[T]         HAS_TYPE closed
    fullset_is_closed:         JUDGEMENT fullset[T]          HAS_TYPE closed
    union_is_closed:           JUDGEMENT union(V1,V2)        HAS_TYPE closed
    intersection_is_closed:    JUDGEMENT intersection(V1,V2) HAS_TYPE closed

    emptyset_is_clopen:          JUDGEMENT emptyset[T]       HAS_TYPE clopen
    fullset_is_clopen:           JUDGEMENT fullset[T]        HAS_TYPE clopen

    t: VAR topology[T]

    indiscrete_subset: LEMMA subset?(indiscrete_topology,t)
    discrete_subset:   LEMMA subset?(t,discrete_topology)

    open_def:          LEMMA open?(A) IFF FORALL (x:(A)): neighbourhood?(A,x)
    neighbourhood_intersection: LEMMA neighbourhood?(A,x) AND neighbourhood?(B,x)
                                      => neighbourhood?(intersection(A,B),x)
    neighbourhood_subset: LEMMA neighbourhood?(A,x) AND subset?(A,B) =>
                                neighbourhood?(B,x)
    Cl_split1:      LEMMA union(derived_set(A),A) = Cl(A)
    Cl_split2:      LEMMA disjoint?(derived_set(A),A)

    subset_of_Cl    : LEMMA subset?(A,Cl(A))                            % 3.7.15a
    Cl_subset       : LEMMA subset?(A,B) => subset?(Cl(A),Cl(B))        % 3.7.15b
    Cl_idempotent   : LEMMA Cl(Cl(A)) = Cl(A)                           % 3.7.15c
    eq_Cl_is_closed : LEMMA A = Cl(A) IFF closed?(A)
    Cl_closed       : LEMMA closed?(Cl(A))                              % 3.7.15d
    Cl_subset_closed: LEMMA subset?(A,V) => subset?(Cl(A),V)
    Cl_union        : LEMMA Cl(union(A,B)) = union(Cl(A),Cl(B))
    Cl_Union        : LEMMA is_finite(Y) => Cl(Union(Y)) = Union(image(Cl,Y))
                                                                        % 3.7.18
    Cl_Intersection: LEMMA subset?(Cl(Intersection(Y)),Intersection(image(Cl,Y)))
                                                                        % 3.7.17

    open_difference  : LEMMA open?(difference(U,V))
    closed_difference: LEMMA closed?(difference(V,U))

    Cl_is_closed:               JUDGEMENT Cl(A)           HAS_TYPE closed
    open_diff_closed_is_open:   JUDGEMENT difference(U,V) HAS_TYPE open
    closed_diff_open_is_closed: JUDGEMENT difference(V,U) HAS_TYPE closed

    emptyset_is_compact:        JUDGEMENT emptyset[T]         HAS_TYPE compact
    singleton_is_compact:       JUDGEMENT singleton(x)        HAS_TYPE compact
    union_is_compact:           JUDGEMENT union(C1,C2)        HAS_TYPE compact
    finite_is_compact:          JUDGEMENT finite_set[T]     SUBTYPE_OF compact

    compact_Union: LEMMA is_finite(Y) AND every(compact?,Y) => compact?(Union(Y))

    compact_def: LEMMA
       compact_space?(S) IFF
       FORALL Y: (every(closed?,Y)    AND
                  (FORALL Y1: subset?(Y1,Y) AND is_finite(Y1) =>
                                     nonempty?(Intersection(Y1)))) =>
                 nonempty?(Intersection(Y))

  END topology

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

  % Subtype TCC generated (at line 31, column 43) for  emptyset[T]
      % expected type  open_set
  open_set_TCC1: OBLIGATION open?(emptyset[T]);

  % Subtype TCC generated (at line 32, column 43) for  emptyset[T]
      % expected type  closed_set
  closed_set_TCC1: OBLIGATION closed?(emptyset[T]);

  % Subtype TCC generated (at line 33, column 43) for  emptyset[T]
      % expected type  clopen_set
  clopen_set_TCC1: OBLIGATION clopen?(emptyset[T]);

  % Subtype TCC generated (at line 38, column 41) for  emptyset[T]
      % expected type  compact
  compact_TCC1: OBLIGATION compact?(emptyset[T]);

  % Judgement subtype TCC generated (at line 42, column 34) for  x
      % expected type  open
  clopen_set_is_open: OBLIGATION FORALL (x: clopen_set): open?(x);

  % Judgement subtype TCC generated (at line 43, column 34) for  x
      % expected type  closed
  clopen_set_is_closed: OBLIGATION FORALL (x: clopen_set): closed?(x);

  % Judgement subtype TCC generated (at line 82, column 39) for  complement(U)
      % expected type  closed
  complement_open_is_closed: OBLIGATION FORALL (U): closed?(complement[T](U));

  % Judgement subtype TCC generated (at line 83, column 39) for  complement(V)
      % expected type  open
  complement_closed_is_open: OBLIGATION FORALL (V): open?(complement[T](V));

  % Judgement subtype TCC generated (at line 85, column 39) for  emptyset[T]
      % expected type  open
  emptyset_is_open: OBLIGATION open?(emptyset[T]);

  % Judgement subtype TCC generated (at line 86, column 39) for  fullset[T]
      % expected type  open
  fullset_is_open: OBLIGATION open?(fullset[T]);

  % Judgement subtype TCC generated (at line 87, column 39) for  union(U1, U2)
      % expected type  open
  union_is_open: OBLIGATION FORALL (U1, U2): open?(union[T](U1, U2));

  % Judgement subtype TCC generated (at line 88, column 39) for
      % intersection(U1, U2)
      % expected type  open
  intersection_is_open: OBLIGATION
    FORALL (U1, U2): open?(intersection[T](U1, U2));

  % Judgement subtype TCC generated (at line 90, column 39) for  emptyset[T]
      % expected type  closed
  emptyset_is_closed: OBLIGATION closed?(emptyset[T]);

  % Judgement subtype TCC generated (at line 91, column 39) for  fullset[T]
      % expected type  closed
  fullset_is_closed: OBLIGATION closed?(fullset[T]);

  % Judgement subtype TCC generated (at line 92, column 39) for  union(V1, V2)
      % expected type  closed
  union_is_closed: OBLIGATION FORALL (V1, V2): closed?(union[T](V1, V2));

  % Judgement subtype TCC generated (at line 93, column 39) for
      % intersection(V1, V2)
      % expected type  closed
  intersection_is_closed: OBLIGATION
    FORALL (V1, V2): closed?(intersection[T](V1, V2));

  % Judgement subtype TCC generated (at line 95, column 41) for  emptyset[T]
      % expected type  clopen
  emptyset_is_clopen: OBLIGATION clopen?(emptyset[T]);

  % Judgement subtype TCC generated (at line 96, column 41) for  fullset[T]
      % expected type  clopen
  fullset_is_clopen: OBLIGATION clopen?(fullset[T]);

  % Judgement subtype TCC generated (at line 126, column 40) for  Cl(A)
      % expected type  closed
  Cl_is_closed: OBLIGATION FORALL (A): closed?(Cl(A));

  % Judgement subtype TCC generated (at line 127, column 40) for
      % difference(U, V)
      % expected type  open
  open_diff_closed_is_open: OBLIGATION
    FORALL (U, V): open?(difference[T](U, V));

  % Judgement subtype TCC generated (at line 128, column 40) for
      % difference(V, U)
      % expected type  closed
  closed_diff_open_is_closed: OBLIGATION
    FORALL (U, V): closed?(difference[T](V, U));

  % Judgement subtype TCC generated (at line 130, column 40) for  emptyset[T]
      % expected type  compact
  emptyset_is_compact: OBLIGATION compact?(emptyset[T]);

  % Judgement subtype TCC generated (at line 131, column 40) for  singleton(x)
      % expected type  compact
  singleton_is_compact: OBLIGATION FORALL (x): compact?(singleton[T](x));

  % Judgement subtype TCC generated (at line 132, column 40) for  union(C1, C2)
      % expected type  compact
  union_is_compact: OBLIGATION FORALL (C1, C2): compact?(union[T](C1, C2));

  % Judgement subtype TCC generated (at line 133, column 40) for  x
      % expected type  compact
  finite_is_compact: OBLIGATION FORALL (x: finite_set[T]): compact?(x);


body:
  %------------------------------------------------------------------------------
  % Compact Spaces
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            8/7/04   Initial Version
  %------------------------------------------------------------------------------

  compact_spaces[T:TYPE,(IMPORTING topology_prelim[T]) S:compact_space]: THEORY

  BEGIN

    IMPORTING topology[T,S]

    U,V: VAR setofsets[T]

    compact_closed_def: LEMMA every(closed?,U)    AND                 % SKB 6.1.5
                              (FORALL V: subset?(V,U) AND is_finite(V) =>
                                                nonempty?(Intersection(V))) =>
                              nonempty?(Intersection(U))

  END compact_spaces


body:
  %------------------------------------------------------------------------------
  % Compact Spaces
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            8/7/04   Initial Version
  %------------------------------------------------------------------------------

  top_compact: THEORY

  BEGIN

    IMPORTING compact_spaces

  END top_compact


body:
  %------------------------------------------------------------------------------
  % Connected Spaces
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            1/11/06  Initial Version
  %------------------------------------------------------------------------------

  connected_space[T:TYPE,(IMPORTING topology_def[T]) S:connected_space]: THEORY

  BEGIN

    IMPORTING topology[T,S]

    A: VAR set[T]

    clopen_def: LEMMA clopen?(A) IFF A = emptyset[T] OR A = fullset[T]

    

  END connected_space


body:
  %------------------------------------------------------------------------------
  % Continuity definition file
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            5/12/04  Initial Version
  %     Version 1.1            8/6/06   Interface change
  %------------------------------------------------------------------------------

  continuity_def[T1:Type, (IMPORTING topology_def[T1]) S:topology[T1],
                 T2:Type, (IMPORTING topology_def[T2]) T:topology[T2]]: THEORY

  BEGIN

    IMPORTING topology[T1,S],
              topology[T2,T]

    f: VAR [T1->T2]
    U: VAR set[T2]
    x: VAR T1

    continuous_at?(f,x):bool
      = FORALL U: neighbourhood?[T2,T](U,f(x)) =>
                  neighbourhood?[T1,S](inverse_image(f,U),x)

    tcontinuous_at?(f,x): MACRO bool = continuous_at?(f,x)

    continuous?(f): bool = FORALL x: continuous_at?(f,x)

    tcontinuous?(f): MACRO bool = continuous?(f)

    continuous: TYPE = (continuous?)

  END continuity_def


body:
  %------------------------------------------------------------------------------
  % Continuity
  %
  % All references are to:
  %
  %   WA Sutherland "Introduction to Metric and Topological Spaces", OUP, 1981
  %
  % or
  %
  %   TM Apostol "Mathematical Analysis" 2nd ed, Addison-Wesley, 1974
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            5/12/04  Initial Version
  %     Version 1.1            9/6/06   Changed Interface
  %------------------------------------------------------------------------------

  continuity[T1:Type, (IMPORTING topology_def[T1]) S:topology[T1],
             T2:Type, (IMPORTING topology_def[T2]) T:topology[T2]]: THEORY

  BEGIN

    IMPORTING continuity_def[T1,S,T2,T],
              topology[T1,S],
              topology[T2,T],
              basis[T2]

    X: VAR set[T1]
    Y: VAR set[T2]
    f: VAR [T1->T2]

    % Apostol Theorem 4.23

    continuous_open_sets: THEOREM
      continuous?(f) IFF
      (FORALL Y: open?[T2,T](Y) => open?[T1,S](inverse_image(f,Y)))

    % Apostol Theorem 4.24

    continuous_closed_sets: THEOREM
      continuous?(f) IFF
      (FORALL Y: closed?[T2,T](Y) => closed?[T1,S](inverse_image(f,Y)))

    B: VAR (base?[T2](T))

    continuous_basis: THEOREM
      continuous?(f) IFF FORALL (Y:(B)): open?[T1,S](inverse_image(f,Y))

  END continuity


body:
  %------------------------------------------------------------------------------
  % Connected Spaces Definition
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            1/11/06  Initial Version
  %------------------------------------------------------------------------------

  connected_def[T:TYPE]: THEORY

  BEGIN

    IMPORTING topology_prelim[T],
              topology_prelim[bool],
              topology,
              continuity_def,
              continuity

    U: VAR topology[T]
    f: VAR (surjective?[T,bool])

    connected_def:  LEMMA connected?(U) IFF
                    FORALL (A,B:(U)): nonempty?(A) AND nonempty?(B) =>
                                   NOT (disjoint?(A,B) AND Union(U) = union(A,B))

    connected_def2: LEMMA connected?(U) IFF
                FORALL f: NOT continuous?[T,(U),bool,discrete_topology[bool]](f)

  END connected_def


body:
  %------------------------------------------------------------------------------
  % Connected Topological Spaces
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            1/11/06  Initial Version
  %------------------------------------------------------------------------------

  top_connected: THEORY

  BEGIN

    IMPORTING connected_def,
              connected_space

  END top_connected


body:
  %------------------------------------------------------------------------------
  % Sub-sequence Properties
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            06/09/07  Initial Version
  %------------------------------------------------------------------------------

  subseq[T:TYPE]: THEORY

  BEGIN

    IMPORTING sequences[T],
              reals@real_fun_preds[nat],
              orders[sequence]

    u,v,w: VAR sequence
    i:     VAR nat
    f:     VAR ({f:[nat->nat] | strict_increasing?(f)})

    subseq?(v,u): bool = EXISTS f: FORALL i: v(i) = u(f(i))

    subseq_index: LEMMA f(i) >= i

    reflexive_subseq :  LEMMA subseq?(u, u)
    transitive_subseq : LEMMA subseq?(u, v) AND subseq?(v, w) => subseq?(u, w)

  END subseq


body:
  %------------------------------------------------------------------------------
  % Topological convergence
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            06/09/06  Initial Version
  %------------------------------------------------------------------------------

  topological_convergence[T:TYPE,(IMPORTING topology_def[T])
                          S:topology[T]]: THEORY

  BEGIN

    IMPORTING topology[T,S], sequences[T], reals@real_fun_preds[nat],
              subseq[T]

    U:       VAR open
    u,u1,u2: VAR sequence
    l:       VAR T
    a:       VAR T
    i,n:     VAR nat

    convergence?(u,l):bool
      = FORALL U: U(l) => EXISTS n: FORALL i: i >= n => U(u(i))

    accumulation?(u, a): bool =  FORALL U,n: U(a) => EXISTS i: i >= n AND U(u(i))

    convergent?(u): bool = EXISTS l: convergence?(u, l)

    tconvergent?(u): MACRO bool = convergent?(u)

    convergent: TYPE = (convergent?)

    v : VAR convergent

    limit(v):T = epsilon(LAMBDA l: convergence?(v, l))

    limit_lemma : LEMMA convergence?(v, limit(v))

    limit_accumulation : LEMMA convergence?(u, l) => accumulation?(u, l)

    convergence_subsequence : LEMMA
          convergence?(u1, l) AND subseq?(u2, u1) => convergence?(u2, l)

  END topological_convergence

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

  % Existence TCC generated (at line 39, column 15) for  epsilon
  limit_TCC1: OBLIGATION FORALL (v: convergent): EXISTS (x: T): TRUE;


body:
  %------------------------------------------------------------------------------
  % Hausdorff convergence
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            06/09/06  Initial Version
  %------------------------------------------------------------------------------

  hausdorff_convergence[T:TYPE,(IMPORTING topology_def[T]) S:hausdorff]: THEORY

  BEGIN

    IMPORTING topological_convergence[T,S]

    u:         VAR sequence[T]
    v:         VAR convergent
    x,l,l1,l2: VAR T

    unique_limit: LEMMA convergence?(u,l1) AND convergence?(u,l2) => l1 = l2

    limit_def:    LEMMA limit(v) = l IFF convergence?(v, l)

    singleton_is_closed: JUDGEMENT singleton(x) HAS_TYPE closed

    compact_is_closed:   JUDGEMENT compact SUBTYPE_OF closed              % 5.4.2

  END hausdorff_convergence

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

  % Judgement subtype TCC generated (at line 26, column 33) for  singleton(x)
      % expected type  closed[T, S]
  singleton_is_closed: OBLIGATION FORALL (x): closed?[T, S](singleton[T](x));

  % Judgement subtype TCC generated (at line 28, column 33) for  x
      % expected type  closed[T, S]
  compact_is_closed: OBLIGATION FORALL (x: compact): closed?[T, S](x);


body:
  %------------------------------------------------------------------------------
  % Topological convergence
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            06/09/06  Initial Version
  %------------------------------------------------------------------------------

  top_convergence: THEORY

  BEGIN

    IMPORTING topological_convergence, % General topological convergence
              hausdorff_convergence    % Hausdorff convergence

  END top_convergence


body:
  %------------------------------------------------------------------------------
  % Composition
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            5/12/04  Initial Version
  %     Version 1.1            8/6/06   Judgements added, Interface changed
  %------------------------------------------------------------------------------

  composition_continuity[T1:Type,(IMPORTING topology_def[T1]) S:topology[T1],
                         T2:Type,(IMPORTING topology_def[T2]) T:topology[T2],
                         T3:Type,(IMPORTING topology_def[T3]) U:topology[T3]]:
                                                                           THEORY

  BEGIN

    IMPORTING continuity[T1,S,T2,T],
              continuity[T2,T,T3,U],
              continuity[T1,S,T3,U]

    f: VAR [T2->T3]
    g: VAR [T1->T2]
    x: VAR T1

    composition_continuous_at: LEMMA
      continuous_at?(g,x) AND continuous_at?(f,g(x)) => continuous_at?(f o g, x)

    composition_continuous: LEMMA continuous?(g) AND continuous?(f) =>
                                  continuous?(f o g)

    F: VAR continuous[T2,T,T3,U]
    G: VAR continuous[T1,S,T2,T]

    composition_is_continuous: JUDGEMENT o(F,G) HAS_TYPE continuous[T1,S,T3,U]

  END composition_continuity

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

  % Judgement subtype TCC generated (at line 37, column 39) for  F o G
      % expected type  continuous[T1, S, T3, U]
  composition_is_continuous: OBLIGATION
    FORALL (F, G): continuous?[T1, S, T3, U](o[T1, T2, T3](F, G));


body:
  %------------------------------------------------------------------------------
  % Homeomorphism definition file
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            8/7/04  Initial Version
  %     Version 1.1            8/6/06  Interface Change
  %------------------------------------------------------------------------------

  homeomorphism_def[T1:Type, (IMPORTING topology_def[T1]) S:topology[T1],
                    T2:Type, (IMPORTING topology_def[T2]) T:topology[T2]]: THEORY

  BEGIN

    IMPORTING continuity_def,
              continuity[T1,S,T2,T],
              continuity[T2,T,T1,S],
              structures@function_image_bis[T1,T2] % Proof only

    A: VAR topology[T1]
    B: VAR topology[T2]
    X: VAR set[T1]
    f: VAR [T1->T2]

    homeomorphism?(f): bool = bijective?[T1,T2](f) AND
                              continuous?[T1,S,T2,T](f) AND
                              continuous?[T2,T,T1,S](inverse_alt(f))

    homeomorphism: TYPE = (homeomorphism?)

    homeomorphism_def: LEMMA
         homeomorphism?(f) IFF
          (bijective?[T1,T2](f) AND
               (FORALL X: open?[T1,S](X) IFF open?[T2,T](image(f,X))))

    homeomorphic?(A,B): bool = EXISTS f: homeomorphism?(f)

  END homeomorphism_def

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

  % Assuming TCC generated (at line 1370, column 3) for
      % function_inverse_alt[T1, T2]
      % generated from assumption function_inverse_alt.inverse_types
  homeomorphism?_TCC1: OBLIGATION
    FORALL (f: [T1 -> T2]):
      continuous?[T1, S, T2, T](f) AND bijective?[T1, T2](f) IMPLIES
       (EXISTS (d: T1): TRUE) OR (FORALL (r: T2): FALSE);


body:
  %------------------------------------------------------------------------------
  % Homeomorphisms are transitive
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            8/10/04  Initial Version
  %------------------------------------------------------------------------------

  homeomorphic_transitive[T1:TYPE, (IMPORTING topology_def[T1]) S:topology[T1],
                          T2:TYPE, (IMPORTING topology_def[T2]) T:topology[T2],
                          T3:TYPE, (IMPORTING topology_def[T3]) U:topology[T3]
                         ]: THEORY

  BEGIN

    IMPORTING homeomorphism_def,
              composition_continuity,   % For proof only
              structures@function_inverse_alt_aux, % For proof only
              structures@function_props_aux % For proof only

    homeomorphic_transitive: LEMMA homeomorphic?[T1,S,T2,T](S,T) AND
                                   homeomorphic?[T2,T,T3,U](T,U) =>
                                   homeomorphic?[T1,S,T3,U](S,U)

  END homeomorphic_transitive


body:
  %------------------------------------------------------------------------------
  % Homeomorphisms are Symmetric
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            8/7/04  Initial Version
  %------------------------------------------------------------------------------

  homeomorphic_symmetric[T1:TYPE, (IMPORTING topology_def[T1]) S:topology[T1],
                         T2:TYPE, (IMPORTING topology_def[T2]) T:topology[T2]
                        ]: THEORY

  BEGIN

    IMPORTING homeomorphism_def,
              structures@function_inverse_alt_aux % For proof only

    homeomorphic_symmetric: LEMMA homeomorphic?[T1,S,T2,T](S,T) IFF
                                  homeomorphic?[T2,T,T1,S](T,S)

  END homeomorphic_symmetric


body:
  %------------------------------------------------------------------------------
  % Homeomorphisms are Reflexive
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            8/10/04  Initial Version
  %------------------------------------------------------------------------------

  homeomorphic_reflexive[T:TYPE,(IMPORTING topology_def[T]) S:topology[T]]:THEORY

  BEGIN

    IMPORTING homeomorphism_def[T,S,T,S]

    homeomorphic_reflexive: LEMMA homeomorphic?(S,S)

  END homeomorphic_reflexive


body:
  %------------------------------------------------------------------------------
  % Basic properties of homeomorphisms
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            1/12/06  Initial Version
  %------------------------------------------------------------------------------

  top_homeomorphic: THEORY

  BEGIN

    IMPORTING homeomorphism_def,
              homeomorphic_reflexive,
              homeomorphic_symmetric,
              homeomorphic_transitive

  END top_homeomorphic


body:
  %------------------------------------------------------------------------------
  % Topology
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            8/10/04  Initial Version
  %     Version 1.1            9/06/06  Interface change, added type judgement
  %------------------------------------------------------------------------------

  identity_continuity[T:TYPE, (IMPORTING topology_def[T]) S:topology]: THEORY

  BEGIN

    IMPORTING continuity[T,S,T,S]

    x:  VAR T

    id_continuous_at: LEMMA continuous_at?(I[T],x)
    id_continuous   : LEMMA continuous?(I[T])
    I_is_continuous : JUDGEMENT I[T] HAS_TYPE continuous

  END identity_continuity

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

  % Judgement subtype TCC generated (at line 23, column 30) for  I[T]
      % expected type  continuous[T, S, T, S]
  I_is_continuous: OBLIGATION continuous?[T, S, T, S](I[T]);


body:
  %------------------------------------------------------------------------------
  % Constant functions are continuous
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            8/10/04  Initial Version
  %------------------------------------------------------------------------------

  constant_continuity[T1:TYPE, (IMPORTING topology_def[T1]) S:topology[T1],
                      T2:TYPE, (IMPORTING topology_def[T2]) T:topology[T2]]:
                                                                           THEORY

  BEGIN

    IMPORTING structures@const_fun_def[T1,T2],
              continuity[T1,S,T2,T]

    a: VAR T2
    x: VAR T1

    const_continuous_at: LEMMA continuous_at?[T1,S,T2,T](const_fun[T1,T2](a),x)
    const_continuous   : LEMMA continuous?[T1,S,T2,T](const_fun[T1,T2](a))
    const_is_continuous: JUDGEMENT const_fun[T1,T2](a) HAS_TYPE continuous

  END constant_continuity

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

  % Judgement subtype TCC generated (at line 26, column 33) for
      % const_fun[T1, T2](a)
      % expected type  continuous[T1, S, T2, T]
  const_is_continuous: OBLIGATION
    FORALL (a): continuous?[T1, S, T2, T](const_fun[T1, T2](a));


body:
  %------------------------------------------------------------------------------
  % Topological subspaces
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            1/11/06  Initial Version
  %     Version 1.1            8/6/06   Changed Interface, added type judgement
  %------------------------------------------------------------------------------

  subspace[T1:TYPE, (IMPORTING topology_def[T1]) S:topology,
           T2:TYPE FROM T1]: THEORY

  BEGIN

    IMPORTING topology_def[T2]

    induced_topology: setofsets[T2] = image(restrict[T1,T2,bool],S)

    induced_subspace_topology: LEMMA topology?[T2](induced_topology)

    subspace_is_topology: JUDGEMENT induced_topology HAS_TYPE topology[T2]

  END subspace

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

  % Judgement subtype TCC generated (at line 21, column 34) for
      % induced_topology
      % expected type  topology[T2]
  subspace_is_topology: OBLIGATION topology?[T2](induced_topology);


body:
  %------------------------------------------------------------------------------
  % Subspace Continuity
  %
  % Continuity is preserved on subspaces
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            8/10/04  Initial Version
  %     Version 1.1            9/06/06  Changed interface, added Type Judgements
  %------------------------------------------------------------------------------

  continuity_subspace[T1:TYPE, (IMPORTING topology_def[T1]) S:topology[T1],
                      T2:TYPE, (IMPORTING topology_def[T2]) T:topology[T2],
                      T3:TYPE FROM T1]: THEORY

  BEGIN

    IMPORTING subspace[T1,S,T3],
              continuity[T1,S,T2,T],
              continuity

    x: VAR T3
    f: VAR [T1->T2]

    subspace_continuous_at: LEMMA continuous_at?(f,x) =>
                continuous_at?[T3,induced_topology,T2,T](restrict[T1,T3,T2](f),x)

    subspace_continuous: LEMMA continuous?(f) =>
          continuous?[T3,induced_topology,T2,T](restrict[T1,T3,T2](f))

    F: VAR continuous[T1,S,T2,T]

    restrict_is_continuous:
      JUDGEMENT restrict[T1,T3,T2](F) HAS_TYPE
                                             continuous[T3,induced_topology,T2,T]

  END continuity_subspace

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

  % Judgement subtype TCC generated (at line 37, column 14) for
      % restrict[T1, T3, T2](F)
      % expected type  continuous[T3, induced_topology, T2, T]
  restrict_is_continuous: OBLIGATION
    FORALL (F):
      continuous?[T3, induced_topology[T1, S, T3], T2, T]
          (restrict[T1, T3, T2](F));


body:
  %------------------------------------------------------------------------------
  % Continuity in topological spaces
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            8/10/04  Initial Version
  %------------------------------------------------------------------------------

  top_continuity: THEORY

  BEGIN

    IMPORTING continuity_def,
              continuity,
              continuity_subspace,
              constant_continuity,
              identity_continuity,
              composition_continuity

  END top_continuity


body:
  %------------------------------------------------------------------------------
  % Cross Products
  %
  %     Author: David Lester, Manchester University, NIA, Universite Perpignan
  %
  %
  %     Version 1.0            17/08/07  Initial Version
  %------------------------------------------------------------------------------

  cross_product[T1,T2:TYPE]: THEORY

  BEGIN

    A:  VAR set[T1]
    B:  VAR set[T2]
    NA: VAR (nonempty?[T1])
    NB: VAR (nonempty?[T2])
    X:  VAR set[[T1,T2]]
    a:  VAR T1
    b:  VAR T2
    z:  VAR [T1,T2]

    cross_product(A,B):set[[T1,T2]] = {z | A(z`1) AND B(z`2)}
    projection_1(X):set[T1]         = {a | EXISTS z: X(z) AND z`1 = a}
    projection_2(X):set[T2]         = {b | EXISTS z: X(z) AND z`2 = b}

    cross_product_empty1:    LEMMA empty?(A) => empty?(cross_product(A,B))
    cross_product_empty2:    LEMMA empty?(B) => empty?(cross_product(A,B))

    cross_product_emptyset1: LEMMA empty?(cross_product(emptyset[T1],B))
    cross_product_emptyset2: LEMMA empty?(cross_product(A,emptyset[T2]))
    cross_product_fullset:   LEMMA full?(cross_product(fullset[T1],fullset[T2]))

    projection_product1:     LEMMA projection_1(cross_product(A,NB)) = A
    projection_product2:     LEMMA projection_2(cross_product(NA,B)) = B

    projection_1_emptyset:   LEMMA projection_1(emptyset[[T1,T2]]) = emptyset[T1]
    projection_2_emptyset:   LEMMA projection_2(emptyset[[T1,T2]]) = emptyset[T2]
    projection_1_fullset:    LEMMA (EXISTS b: TRUE) =>
                                   projection_1(fullset[[T1,T2]])  = fullset[T1]
    projection_2_fullset:    LEMMA (EXISTS a: TRUE) =>
                                   projection_2(fullset[[T1,T2]])  = fullset[T2]

    cross_product_empty1_rew:
                          LEMMA cross_product(emptyset[T1],B) = emptyset[[T1,T2]]
    cross_product_empty2_rew:
                          LEMMA cross_product(A,emptyset[T2]) = emptyset[[T1,T2]]
    cross_product_full_rew:
                 LEMMA cross_product(fullset[T1],fullset[T2]) = fullset[[T1,T2]]


    cross_product: TYPE+ = {X | EXISTS A,B: X = cross_product(A,B)}

    Y: VAR cross_product

    product_projection: LEMMA cross_product(projection_1(Y),projection_2(Y)) = Y

    x_section(X,a):set[T2] = {b | X(a,b)}                             % SKB 7.2.4
    y_section(X,b):set[T1] = {a | X(a,b)}
                                                                      % SKB 7.2.6
    x_section(X):[T1->set[T2]] = lambda a: x_section(X,a)
    y_section(X):[T2->set[T1]] = lambda b: y_section(X,b)

  END cross_product

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

  % Existence TCC generated (at line 52, column 2) for
      % cross_product: TYPE+ = {X | EXISTS A, B: X = cross_product(A, B)}
  cross_product_TCC1: OBLIGATION
    EXISTS (x: {X | EXISTS A, B: X = cross_product(A, B)}): TRUE;


body:
  %------------------------------------------------------------------------------
  % Lindelof's Covering Theorem
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  %     Version 1.0            2/09/07  Initial Version
  %------------------------------------------------------------------------------

  lindelof[T:TYPE,(IMPORTING topology_def[T]) S:second_countable]: THEORY

  BEGIN

    IMPORTING topology[T,S],
              sets_aux@countable_image % proof only

    U,V: VAR setofsets[T]

    lindelof: THEOREM open_cover?(U,fullset[T],S) =>
                      EXISTS V: is_countable(V) AND subcover?(V,U,fullset[T])

  END lindelof


body:
  %------------------------------------------------------------------------------
  % Basic Topological Properties
  %
  %     Author: David Lester, Manchester University, NIA, Université Perpignan
  %
  % All references are to WA Sutherland "Introduction to Metric and
  % Topological Spaces", OUP, 1981
  %
  %     Version 1.0            1/12/06  Initial Version
  %------------------------------------------------------------------------------

  top_basic: THEORY

  BEGIN

    IMPORTING topology_prelim,    % Preliminary Definitions for topology
              basis,              % Defining the basis of a topology
              topology_def,       % Basic Definitions for topology
              topology,           % Further properties of topologies
              subspace,           % subspace properties
              lindelof,           % Lindelof covering theorem

              cross_product        %% RWB


  END top_basic


body:
  top: THEORY
  %------------------------------------------------------------------------
  %
  % A Foundational Theory of Trigonometry
  %
  %       by Cesar Munoz                     Langley ICASE Institute
  %          Victor Carreno                  NASA Langley
  %          Ricky Butler                    NASA Langley
  %          Gilles Dowek                    INRIA, Domaine de Voluceau
  %          Alfons Geser                    Langley ICASE Institute
  %          Ben Di Vito                     NASA Langley
  %          David Lester                    Manchester University
  % 
  %      Version 1.0    3/27/01
  %      Version 1.1    6/27/01              New lemmas added:
  %                                          -------------------------------- 
  %                                          tan_period, sin_k_pi , cos_2k_pi,  
  %                                          cos_k_pi  , sin_k_pi2, tan_k_pi,
  %                                          sin_eq_1  , cos_eq_1 , sin_eq_sin,
  %                                          cos_eq_cos, tan_eq_tan, sin_eq_pm1,
  %                                          cos_eq_pm1, and prelude_aux lemmas
  %
  %      Version 1.2    6/28/01              Theory "trig_rew" added
  %
  %      Version 1.3    10/27/03             Corrected, foundational theory
  %                                          (David Lester)
  %
  %      Version 1.31   11/29/03             Renamed PI to pi (Cesar A. Munoz)
  %
  %      Version 1.32   2/6/04               Theory "tan_approx" added (C. Munoz)
  %
  %      Version 1.33   5/30/04              inverse equivalences done (DRL)
  %
  %      Version 1.4    1/5/05               update to analysis name changes
  %
  %      Version 1.5    4/21/05              atan2_props added and minor things
  %
  %      Version 1.6    1/8/08               cleaned up types of inverse functions
  %
  % INDEX:
  % ------
  %
  %     trig_basic:
  %     -----------
  %         - definition of pi with c
  %         - definition of sin, cos, and tan
  %         - pythagorean properties: sq(sin(a)) + sq(cos(a)) = 1 
  %         - sum and difference of two angles
  %         - double angle formulas
  %         - negative properties, e.g. sin(-a)
  %         - periodicity, e.g. sin(a) = sin(a + 2 * j * pi) 
  %         - co-function identities, e.g. sin(pi/2 - a) = cos(a)
  %         - location of zeros of trig functions
  %
  %      trig_values                            Lemma names
  %      -----------                   ------------------------------------
  %         - trig functions at 0      : sin_0     , cos_0     , tan_0 
  %         - trig functions at pi/6   : sin_pi6   , cos_pi6   , tan_pi6 
  %         - trig functions at pi/4   : sin_pi4   , cos_pi4   , tan_pi4 
  %         - trig functions at pi/3   : sin_pi3   , cos_pi3   , tan_pi3 
  %         - trig functions at pi/2   : sin_pi2   , cos_pi2   , tan_pi2 
  %         - trig functions at pi     : sin_pi    , cos_pi    , tan_pi 
  %         - trig functions at 2*pi/3 : sin_2pi3  , cos_2pi3  , tan_2pi3 
  %         - trig functions at 3*pi/4 : sin_3pi4  , cos_3pi4  , tan_3pi4 
  %         - trig functions at 5*pi/4 : sin_5pi4  , cos_5pi4  , tan_5pi4 
  %
  %      trig_ineq
  %      ---------
  %         - regions where functions are greater than 0
  %         - regions where functions are less    than 0
  %         - regions where functions are increasing
  %         - regions where functions are decreasing
  %
  %      trig_extra
  %      ----------
  %         - reduction theorems
  %         - sum and product identities
  %         - half-angle identities and zeros
  %         - triple angle formulas
  %
  %      trig_approx
  %      -----------
  %          - taylor series approximations to trig functions:
  %               sin_approx(a,n): sum first n terms of taylor expansion of sin
  %               cos_approx(a,n): sum first n terms of taylor expansion of cos
  %      
  %      tan_approx
  %      ----------
  %          - taylor series approximations for tangent
  %
  %
  %      law_cosines
  %      -----------
  %         - the law of cosines in a coordinate geometry formulation
  %
  %      trig_degree
  %      -----------
  %         - trig functions that take arguments in degrees: sind, cosd
  %         - defines conversions toRad, toDeg
  %
  %      trig_inverses
  %      -------------
  %         - defines inverse trig functions: arcsin, arccos, and arctan 
  %
  %      trig_rew
  %      -------------
  %         - Experimental auto-rewrite-theory background library

  %
  %      atan2
  %      ----
  %         - defines two-argument inverse tangent: atan2
  %
  %------------------------------------------------------------------------

  BEGIN
     IMPORTING trig_doc,      % Some more documentation (Rationale)

               trig,          % typical needs
               trig_full,     % everything

  % --------------------- The above import the following ------------------

               trig_basic,    % basic properties 
               trig_values,   % values of functions for special arguments
               trig_ineq,     % trig inequalities
               trig_extra,    % sum and product, half-angle, reductions and zeros
  	     exp_term, 
               trig_approx,   % taylor series approximations to trig functions:
               tan_approx,    % Approximations for tangent
               atan_approx,   % Approximations for atan 
               law_cosines,   % law of cosines
               trig_degree,   % conversions to degrees
               trig_inverses, % inverse functions
               trig_rew,      % auto-rewrites

  % ---------------------- Foundational Development -----------------------

               sincos,        % continuity and differentiability of sin, cos

               acos,          % arc cosine  (from arc tangent)
               asin,          % arc sine    (from arc tangent)
               atan,          % one-argument arc tangent (from integral)
               atan_values,   % special values of atan
               atan2,         % two-argument arc tangent
               atan2_props,   % additional properties of atan2
               jatan2,        % Java atan2       

               to2pi,         % normalization of radians to 2pi

               sincos_phase,          % sin and cos from infinite series
               sincos,                % continuity, differentiality, and bounds
               sincos_quad,           % basic properties of sin cos
               deriv_sincos,          % convenient forms over T from real
               integral_sincos,       % convenient forms over T from real
  	     integral_indef_sincos, % sin/cos indefinite integral properties 
               tan_quad               % definiton of tan from atan


  %  ---- type simplifications
  %
  % NOTE: real_abs_lt_pi: NONEMPTY_TYPE = {x:real   | abs(x) < pi/2} was
  %       renamed to real_abs_lt_pi2 which is much more conistent!!!
  %
  %  in atan:
  %
  %  >real_abs_lt_pi2: NONEMPTY_TYPE = {x | abs(x) < pi/2} 
  %  real_abs_lt_pi2: NONEMPTY_TYPE = {x | -pi/2 < x AND x < pi/2} 
  %
  %  in asin:
  %
  %  >real_abs_le1:   NONEMPTY_TYPE = {x:real | abs(x) <= 1}    
  %  >real_abs_lt1:   NONEMPTY_TYPE = {x:real | abs(x) <  1}    
  %  >real_abs_le_pi2: NONEMPTY_TYPE = {x:real | abs(x) <= pi/2} 
  %  real_abs_le1:   NONEMPTY_TYPE =  {x:real | -1 <= x AND x <= 1}    
  %  real_abs_lt1:   NONEMPTY_TYPE =  {x:real | -1 < x  AND x <  1}    
  %  real_abs_le_pi2: NONEMPTY_TYPE = {x:real | -pi/2 <= x AND x <= pi/2} 
  %
  %  in sincos_quad:
  %
  %  >real_abs_lt_pi:     NONEMPTY_TYPE = {x:real   | abs(x) < pi/2} 
  %  real_abs_lt_pi2:     NONEMPTY_TYPE = {x:real   | -pi/2 < x AND x < pi/2} 


  % NAME CHANGES made 7-21-08:
  %
  % sin_continuous2 --> sin_cont_fun
  % cos_continuous2 --> cos_cont_fun
  % sin_derivable2 --> sin_derivable_fun
  % cos_derivable2 --> cos_derivable_fun
  % acos_derivable2 --> acos_derivable_fun
  % asin_derivable2 --> asin_derivable_fun
  % sin_value_derivable2 --> sin_value_derivable_fun
  % cos_value_derivable2 --> cos_value_derivable_fun

  END top


body:
  atan: THEORY
  %------------------------------------------------------------------------------
  %
  %  A foundational theory of atan(x) for the interval [0,pi/2]
  %
  %          David Lester                    Manchester University
  % 
  %------------------------------------------------------------------------------
  BEGIN

  %  IMPORTING reals@prelude_aux_reals, 
    IMPORTING reals@sq, reals@sigma, reals@sqrt, reals@poly_rew
    IMPORTING analysis@derivatives, analysis@restrict2_deriv, analysis@deriv_domains
    IMPORTING analysis@derivative_props, analysis@fundamental_theorem
    IMPORTING analysis@chain_rule,  analysis@derivative_props   % , analysis@derivatives_more
    IMPORTING analysis@continuous_functions_props, analysis@integral
    IMPORTING reals@factorial
    IMPORTING analysis@nth_derivatives[real], analysis@taylors[real]
    IMPORTING reals@harmonic_polynomials, analysis@polynomial_deriv
    IMPORTING reals@binomial, analysis@indefinite_integral

    AUTO_REWRITE- abs_0
    AUTO_REWRITE- abs_nat


    posreal_ge1: NONEMPTY_TYPE = {x:real | x >= 1} CONTAINING 1

    x,y:   VAR real
    px,py: VAR posreal
    nx:    VAR negreal
    nnx:   VAR nnreal
    nzx:   VAR nzreal
    n,m:   VAR nat
    pn:    VAR posnat

    atan_deriv_fn(x:real):posreal = 1/(1+x*x)

    one_over_one_plus_t_sq_cont: LEMMA continuous?[real](atan_deriv_fn)

    atan_value(x:real):real = Integral[real](0,x,atan_deriv_fn)

    atan_value_0      : LEMMA atan_value(0)  = 0
    atan_neg_value    : LEMMA atan_value(-x) = -atan_value(x)
    atan_inv_value    : LEMMA atan_value(1/px) = 2*atan_value(1)-atan_value(px)
    atan_inv_neg_value: LEMMA atan_value(1/nx) = -2*atan_value(1)-atan_value(nx)

    atan_value_strict_increasing: LEMMA strict_increasing?(atan_value)

    atan_value_minus_x1: LEMMA -1/py < x IMPLIES
               atan_value(x)-atan_value(py) = atan_value((x-py)/(1+x*py))

    atan_value_minus_x2: LEMMA x < -1/py IMPLIES
               4*atan_value(1) + atan_value(x) - atan_value(py)
                                     = atan_value((x-py)/(1+x*py))
    atan_value_minus: LEMMA
    (-1 < x*y => atan_value(x)-atan_value(y) = atan_value((x-y)/(1+x*y))) AND
    (x*y < -1 & y > 0 => atan_value(x)-atan_value(y)+4*atan_value(1)
                                             = atan_value((x-y)/(1+x*y))) AND
    (x*y < -1 & y < 0 => atan_value(x)-atan_value(y)-4*atan_value(1)
                                             = atan_value((x-y)/(1+x*y)))

    pi:posreal = 4*atan_value(1)

  %  real_mpi_ppi: NONEMPTY_TYPE = {x:real | abs(x)<2*atan_value(1)} CONTAINING 0
  %  real_mpi_ppi: NONEMPTY_TYPE = {x:real | abs(x) < pi/2} CONTAINING 0

  %  real_abs_lt_pi2: NONEMPTY_TYPE = {x | abs(x) < pi/2} CONTAINING 0
    real_abs_lt_pi2: NONEMPTY_TYPE = {x | -pi/2 < x AND x < pi/2} CONTAINING 0

  %  atan_abs_lt_pi2: JUDGEMENT atan(x) HAS_TYPE real_abs_lt_pi2

    atan(x:real): real_abs_lt_pi2 = atan_value(x)

    pi_value: LEMMA pi = 4*atan(1)

  % non-A&S definitions

    atan_strict_increasing: LEMMA strict_increasing?(atan)

    atan_bij              : LEMMA bijective?[real,real_abs_lt_pi2](atan)
    atan_0                : LEMMA atan(0) = 0

    atan_inv              : LEMMA atan(1/px) = pi/2-atan(px)
    atan_inv_neg          : LEMMA atan(1/nx) = -pi/2-atan(nx)


  % A&S defs

    atan_def: LEMMA atan(x) = Integral(0,x,(LAMBDA (x:real):1/(1+x*x)))  %  4.4.3

    acot(nzx:nzreal):nzreal    = atan(1/nzx)                             %  4.4.8

    atan_neg: LEMMA atan(-x)   = -atan(x)                                % 4.4.16
    acot_neg: LEMMA acot(-nzx) = -acot(nzx)                              % 4.4.19

    atan_minus: LEMMA                                                    % 4.4.34
    (-1 < x*y =>         atan(x)-atan(y)    = atan((x-y)/(1+x*y))) AND
    (x*y < -1 & y > 0 => atan(x)-atan(y)+pi = atan((x-y)/(1+x*y))) AND
    (x*y < -1 & y < 0 => atan(x)-atan(y)-pi = atan((x-y)/(1+x*y)))

    atan_plus:  LEMMA                                                    % 4.4.34
    (x*y < 1 => atan(x)+atan(y)            = atan((x+y)/(1-x*y))) AND
    (1 < x*y & y > 0 => atan(x)+atan(y)-pi = atan((x+y)/(1-x*y))) AND
    (1 < x*y & y < 0 => atan(x)+atan(y)+pi = atan((x+y)/(1-x*y)))

    atan_sub_swap : LEMMA
      x /= 0 AND y /= 0 IMPLIES
      atan(x/y)-atan(y/x) = atan((x^2-y^2)/(2*x*y))

    deriv_atan_fun: LEMMA derivable?(atan) AND
                          deriv(atan) = (LAMBDA (x:real): 1/(1+x*x))     % 4.4.54

    continuous_atan: LEMMA continuous?[real](atan)

  % more non-A&S definitions

    atan_1:    LEMMA atan(1) = 4*atan(1/5) - atan(1/239)
    atan_bnds: LEMMA px/(1+px*px) < atan(px) AND atan(px) < px
    pi_bnds:   LEMMA 306/100 < pi AND pi < 319/100

  % 5/26 < atan(1/5) < 1/5
  % 239/57122 < atan(1/239) < 1/239
  % 40/13-4/239 < pi < 16/5 - 4*239/57122

  % atan Taylor's Theorem

    atanS(n:nat)(x:real):real = harmonic_poly_real(2*n+1,1,x)
    atanD(n:nat)(x:real):real = (1+x*x)^(2*n+1)
    atanF(n:nat)(i:nat ):int
      = IF i > 2*n OR odd?(i) THEN 0
        ELSE (-1)^(i/2+n)*factorial(2*n)*C(2*n+1,i) ENDIF
     atanN(n:nat):[real->real] = polynomial(atanF(n),2*n)

    atan_taylors_prep1: LEMMA
      abs(atanS(n)(x)) <= (1+x*x)^n * sqrt(1+x*x)

    atan_taylors_prep2: LEMMA
      (-1)^n*factorial(2*n)*atanS(n) = atanN(n)

    atan_taylors_prep3: LEMMA   %% bug %%
      derivable_n_times?(atanN(n),m) AND derivable_n_times?(atanD(n),m)

    atanN_derivable   : LEMMA derivable?(atanN(n))
    atanD_derivable   : LEMMA derivable?(atanD(n))

    atan_taylors_prep4: LEMMA
      deriv(atanN(n))
        = IF n = 0 THEN const_fun(0)
                   ELSE polynomial(LAMBDA (i:nat): (i+1)*atanF(n)(i+1),2*n-1)
          ENDIF

    atan_taylors_prep5: LEMMA
      deriv(atanD(n)) = (LAMBDA (x:real): (4*n+2)*x*(1+x*x)^(2*n))

    atan_taylors_prep6: LEMMA
      deriv(deriv(atanN(n)))
        = IF n = 0 THEN const_fun(0)
                   ELSE polynomial(LAMBDA (i:nat): (i+2)*(i+1)*atanF(n)(i+2),2*n-2)
          ENDIF

    atan_taylors_prep7: LEMMA FORALL (f:[real->real], g:[real->nzreal]):
      derivable?(f) AND derivable?(g) IMPLIES
      derivable?(f/g^pn) AND deriv(f/g^pn) = (deriv(f)*g-pn*f*deriv(g))/(g^(pn+1))

    atan_taylors_prep8: LEMMA 
      deriv(deriv(atanN(n)/atanD(n))) = atanN(n+1)/atanD(n+1)

    atan_series_prep4: LEMMA derivable_n_times?(atanN(n)/atanD(n),2*m)

    atan_series_prep5: LEMMA nderiv(2*m,atanN(n)/atanD(n))=atanN(n+m)/atanD(n+m)

    atan_series_prep6: LEMMA 
       derivable_n_times?(LAMBDA (x:real): 1/(1+x*x),2*n) AND
       nderiv(2*n,LAMBDA (x:real): 1/(1+x*x)) = atanN(n)/atanD(n)

    atan_nderiv: LEMMA
      nderiv(n,atan)
        = IF n = 0 THEN atan ELSIF even?(n)
                   THEN (deriv(atanN(n/2-1))*(LAMBDA (x:real): (1+x*x)) -
                            atanN(n/2-1)*(LAMBDA (x:real): (2*n-2)*x))      /
                        (atanD(n/2-1)*(LAMBDA (x:real): (1+x*x)))
                   ELSE atanN((n-1)/2)/atanD((n-1)/2) ENDIF

    atan_nderiv_0: LEMMA
      nderiv(n,atan)(0)
              = IF even?(n) THEN 0 ELSE (-1)^((n-1)/2) * factorial(n-1) ENDIF

    atan_n_times_derivable: LEMMA derivable_n_times?(atan,n)

    atan_series_prep7: LEMMA
      abs(atanN(n)(x)) <= factorial(2*n)*(1+x*x)^(2*n+1)

    atan_series_prep8: LEMMA abs(nderiv(2*n+1,atan)(x)) <= factorial(2*n)

    atan_series_coef(n:nat):rat = ((-1)^n)/(2*n+1)
    atan_series_term(x:real):[nat->real]
       = (LAMBDA (n:nat): x^(2*n+1) * atan_series_coef(n))
    atan_series_n(x:real,n:nat):real = sigma(0,n,atan_series_term(x))

    atan_series_n_increasing: LEMMA
      FORALL (x,y:nnreal): x<=y AND y<=1 IMPLIES
      atan_series_n(x,n) <= atan_series_n(y,n)

    atan_series_n_a0: LEMMA
      atan_series_n(0,n) = 0

    atan_series_eqv: LEMMA
     atan_series_n(x,n) = sigma(0,2*n+2,
        LAMBDA (nn:nat): IF nn > 2*n+2 OR nn = 0 THEN 0 ELSE
                           nderiv(nn,atan)(0)*x^nn/factorial(nn) ENDIF)

    atan_taylors: LEMMA (EXISTS (c: between(0,x)): 
                 atan(x) = atan_series_n(x,n)
                        +  nderiv(2*n+3,atan)(c)*x^(2*n+3)/factorial(2*n+3))

    atan_series: LEMMA abs(atan(x)-atan_series_n(x,n)) <= abs(x^(2*n+3))/(2*n+3)

  END atan

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

  % Assuming TCC generated (at line 18, column 12) for
      % analysis@nth_derivatives[real]
      % generated from assumption nth_derivatives.deriv_domain
  IMP_nth_derivatives_TCC1: OBLIGATION deriv_domain?[real];

  % Assuming TCC generated (at line 18, column 12) for
      % analysis@nth_derivatives[real]
      % generated from assumption nth_derivatives.not_one_element
  IMP_nth_derivatives_TCC2: OBLIGATION not_one_element?[real];

  % Assuming TCC generated (at line 18, column 44) for  analysis@taylors[real]
      % generated from assumption taylors.connected_domain
  IMP_taylors_TCC1: OBLIGATION connected?[real];

  % Subtype TCC generated (at line 36, column 37) for  (1 + x * x)
      % expected type  nznum
  atan_deriv_fn_TCC1: OBLIGATION FORALL (x: real): (1 + x * x) /= 0;

  % Subtype TCC generated (at line 36, column 34) for  1 / (1 + x * x)
      % expected type  posreal
  atan_deriv_fn_TCC2: OBLIGATION
    FORALL (x: real): 1 / (1 + x * x) >= 0 AND 1 / (1 + x * x) > 0;

  % Subtype TCC generated (at line 40, column 47) for  atan_deriv_fn
      % expected type  Integrable_funs[real](0, x)
  atan_value_TCC1: OBLIGATION
    FORALL (x: real): Integrable?[real](0, x, atan_deriv_fn);

  % Subtype TCC generated (at line 50, column 63) for  (1 + x * py)
      % expected type  nznum
  atan_value_minus_x1_TCC1: OBLIGATION
    FORALL (py: posreal, x: real): -1 / py < x IMPLIES (1 + x * py) /= 0;

  % Subtype TCC generated (at line 54, column 56) for  (1 + x * py)
      % expected type  nznum
  atan_value_minus_x2_TCC1: OBLIGATION
    FORALL (py: posreal, x: real): x < -1 / py IMPLIES (1 + x * py) /= 0;

  % Subtype TCC generated (at line 56, column 63) for  (1 + x * y)
      % expected type  nznum
  atan_value_minus_TCC1: OBLIGATION
    FORALL (x, y: real): -1 < x * y IMPLIES (1 + x * y) /= 0;

  % Subtype TCC generated (at line 58, column 63) for  (1 + x * y)
      % expected type  nznum
  atan_value_minus_TCC2: OBLIGATION
    FORALL (x, y: real):
      (-1 < x * y =>
        atan_value(x) - atan_value(y) = atan_value((x - y) / (1 + x * y)))
       AND y > 0 AND x * y < -1
       IMPLIES (1 + x * y) /= 0;

  % Subtype TCC generated (at line 60, column 63) for  (1 + x * y)
      % expected type  nznum
  atan_value_minus_TCC3: OBLIGATION
    FORALL (x, y: real):
      (-1 < x * y =>
        atan_value(x) - atan_value(y) = atan_value((x - y) / (1 + x * y)))
       AND
       (x * y < -1 & y > 0 =>
         atan_value(x) - atan_value(y) + 4 * atan_value(1) =
          atan_value((x - y) / (1 + x * y)))
        AND y < 0 AND x * y < -1
       IMPLIES (1 + x * y) /= 0;

  % Subtype TCC generated (at line 62, column 15) for  4 * atan_value(1)
      % expected type  posreal
  pi_TCC1: OBLIGATION 4 * atan_value(1) >= 0 AND 4 * atan_value(1) > 0;

  % Subtype TCC generated (at line 68, column 75) for  0
      % expected type  real_abs_lt_pi2
  real_abs_lt_pi2_TCC1: OBLIGATION -pi / 2 < 0 AND 0 < pi / 2;

  % Subtype TCC generated (at line 72, column 34) for  atan_value(x)
      % expected type  real_abs_lt_pi2
  atan_TCC1: OBLIGATION
    FORALL (x: real): -pi / 2 < atan_value(x) AND atan_value(x) < pi / 2;

  % Subtype TCC generated (at line 89, column 42) for
      % (LAMBDA (x: real): 1 / (1 + x * x))
      % expected type  Integrable_funs[real](0, x)
  atan_def_TCC1: OBLIGATION
    FORALL (x1: real):
      Integrable?[real](0, x1, (LAMBDA (x: real): 1 / (1 + x * x)));

  % Subtype TCC generated (at line 91, column 31) for  atan(1 / nzx)
      % expected type  nzreal
  acot_TCC1: OBLIGATION FORALL (nzx: nzreal): atan(1 / nzx) /= 0;

  % Subtype TCC generated (at line 98, column 56) for  (1 + x * y)
      % expected type  nznum
  atan_minus_TCC1: OBLIGATION
    FORALL (x, y: real):
      (-1 < x * y => atan(x) - atan(y) = atan((x - y) / (1 + x * y))) AND
       y > 0 AND x * y < -1
       IMPLIES (1 + x * y) /= 0;

  % Subtype TCC generated (at line 99, column 56) for  (1 + x * y)
      % expected type  nznum
  atan_minus_TCC2: OBLIGATION
    FORALL (x, y: real):
      (-1 < x * y => atan(x) - atan(y) = atan((x - y) / (1 + x * y))) AND
       (x * y < -1 & y > 0 =>
         atan(x) - atan(y) + pi = atan((x - y) / (1 + x * y)))
        AND y < 0 AND x * y < -1
       IMPLIES (1 + x * y) /= 0;

  % Subtype TCC generated (at line 102, column 55) for  (1 - x * y)
      % expected type  nznum
  atan_plus_TCC1: OBLIGATION
    FORALL (x, y: real): x * y < 1 IMPLIES (1 - x * y) /= 0;

  % Subtype TCC generated (at line 103, column 55) for  (1 - x * y)
      % expected type  nznum
  atan_plus_TCC2: OBLIGATION
    FORALL (x, y: real):
      (x * y < 1 => atan(x) + atan(y) = atan((x + y) / (1 - x * y))) AND
       y > 0 AND 1 < x * y
       IMPLIES (1 - x * y) /= 0;

  % Subtype TCC generated (at line 104, column 55) for  (1 - x * y)
      % expected type  nznum
  atan_plus_TCC3: OBLIGATION
    FORALL (x, y: real):
      (x * y < 1 => atan(x) + atan(y) = atan((x + y) / (1 - x * y))) AND
       (1 < x * y & y > 0 =>
         atan(x) + atan(y) - pi = atan((x + y) / (1 - x * y)))
        AND y < 0 AND 1 < x * y
       IMPLIES (1 - x * y) /= 0;

  % Subtype TCC generated (at line 108, column 34) for  2
      % expected type  {i: int | x /= 0 OR i >= 0}
  atan_sub_swap_TCC1: OBLIGATION
    FORALL (x, y: real): y /= 0 AND x /= 0 IMPLIES x /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 108, column 38) for  2
      % expected type  {i: int | y /= 0 OR i >= 0}
  atan_sub_swap_TCC2: OBLIGATION
    FORALL (x, y: real): y /= 0 AND x /= 0 IMPLIES y /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 108, column 42) for  (2 * x * y)
      % expected type  nznum
  atan_sub_swap_TCC3: OBLIGATION
    FORALL (x, y: real): y /= 0 AND x /= 0 IMPLIES (2 * x * y) /= 0;

  % Subtype TCC generated (at line 131, column 17) for  (i / 2 + n)
      % expected type  {i: int | TRUE}
  atanF_TCC1: OBLIGATION
    FORALL (n, i: nat):
      NOT i > 2 * n AND NOT odd?(i) IMPLIES integer_pred((i / 2 + n));

  % Subtype TCC generated (at line 131, column 47) for  i
      % expected type  {i: nat | i <= 1 + 2 * n}
  atanF_TCC2: OBLIGATION
    FORALL (n, i: nat): NOT i > 2 * n AND NOT odd?(i) IMPLIES i <= 1 + 2 * n;

  % Subtype TCC generated (at line 131, column 11) for
      % (-1) ^ (i / 2 + n) * factorial(2 * n) * C(2 * n + 1, i)
      % expected type  int
  atanF_TCC3: OBLIGATION
    FORALL (n, i: nat):
      NOT i > 2 * n AND NOT odd?(i) IMPLIES
       integer_pred((-1) ^ (i / 2 + n) * factorial(2 * n) * C(2 * n + 1, i));

  % Subtype TCC generated (at line 135, column 41) for  1 + x * x
      % expected type  nnx: nonneg_real
  atan_taylors_prep1_TCC1: OBLIGATION FORALL (x: real): 1 + x * x >= 0;

  % Subtype TCC generated (at line 147, column 10) for  atanN(n)
      % expected type  deriv_fun[real]
  atan_taylors_prep4_TCC1: OBLIGATION
    FORALL (n: nat): derivable?[real](atanN(n));

  % Subtype TCC generated (at line 149, column 69) for  2 * n - 1
      % expected type  nat
  atan_taylors_prep4_TCC2: OBLIGATION
    FORALL (n: nat): NOT n = 0 IMPLIES 2 * n - 1 >= 0;

  % Subtype TCC generated (at line 153, column 10) for  atanD(n)
      % expected type  deriv_fun[real]
  atan_taylors_prep5_TCC1: OBLIGATION
    FORALL (n: nat): derivable?[real](atanD(n));

  % Subtype TCC generated (at line 156, column 10) for  deriv(atanN(n))
      % expected type  deriv_fun[real]
  atan_taylors_prep6_TCC1: OBLIGATION
    FORALL (n: nat): derivable?[real](deriv[real](atanN(n)));

  % Subtype TCC generated (at line 158, column 75) for  2 * n - 2
      % expected type  nat
  atan_taylors_prep6_TCC2: OBLIGATION
    FORALL (n: nat): NOT n = 0 IMPLIES 2 * n - 2 >= 0;

  % Subtype TCC generated (at line 163, column 17) for  g ^ pn
      % expected type  [real -> nzreal]
  atan_taylors_prep7_TCC1: OBLIGATION
    FORALL (pn: posnat, f: [real -> real], g: [real -> nzreal]):
      derivable?(f) AND derivable?(g) IMPLIES
       (FORALL (x1: real): (^[real](g, pn))(x1) /= 0);

  % Subtype TCC generated (at line 163, column 71) for  (g ^ (pn + 1))
      % expected type  [real -> nzreal]
  atan_taylors_prep7_TCC2: OBLIGATION
    FORALL (pn: posnat, f: [real -> real], g: [real -> nzreal]):
      derivable?(f / g ^ pn) AND derivable?(f) AND derivable?(g) IMPLIES
       (FORALL (x1: real): (^[real](g, (pn + 1)))(x1) /= 0);

  % Subtype TCC generated (at line 166, column 25) for  atanD(n)
      % expected type  [real -> nzreal]
  atan_taylors_prep8_TCC1: OBLIGATION
    FORALL (n: nat, x1: real): atanD(n)(x1) /= 0;

  % Subtype TCC generated (at line 166, column 16) for  atanN(n) / atanD(n)
      % expected type  deriv_fun[real]
  atan_taylors_prep8_TCC2: OBLIGATION
    FORALL (n: nat): derivable?[real](/[real](atanN(n), atanD(n)));

  % Subtype TCC generated (at line 166, column 10) for
      % deriv(atanN(n) / atanD(n))
      % expected type  deriv_fun[real]
  atan_taylors_prep8_TCC3: OBLIGATION
    FORALL (n: nat):
      derivable?[real](deriv[real](/[real](atanN(n), atanD(n))));

  % Subtype TCC generated (at line 166, column 49) for  atanD(n + 1)
      % expected type  [real -> nzreal]
  atan_taylors_prep8_TCC4: OBLIGATION
    FORALL (n: nat, x1: real): atanD(n + 1)(x1) /= 0;

  % Subtype TCC generated (at line 170, column 38) for  atanN(n) / atanD(n)
      % expected type  nderiv_fun[real](2 * m)
  atan_series_prep5_TCC1: OBLIGATION
    FORALL (m, n: nat):
      derivable_n_times?[real](/[real](atanN(n), atanD(n)), 2 * m);

  % Subtype TCC generated (at line 170, column 68) for  atanD(n + m)
      % expected type  [real -> nzreal]
  atan_series_prep5_TCC2: OBLIGATION
    FORALL (m, n: nat, x1: real): atanD(n + m)(x1) /= 0;

  % Subtype TCC generated (at line 177, column 13) for  atan
      % expected type  nderiv_fun[real](n)
  atan_nderiv_TCC1: OBLIGATION
    FORALL (n: nat): derivable_n_times?[real](atan, n);

  % Subtype TCC generated (at line 179, column 35) for  n / 2 - 1
      % expected type  nat
  atan_nderiv_TCC2: OBLIGATION
    FORALL (n: nat):
      NOT n = 0 AND even?(n) IMPLIES
       integer_pred(n / 2 - 1) AND n / 2 - 1 >= 0;

  % Subtype TCC generated (at line 179, column 29) for  atanN(n / 2 - 1)
      % expected type  deriv_fun[real]
  atan_nderiv_TCC3: OBLIGATION
    FORALL (n: nat):
      NOT n = 0 AND even?(n) IMPLIES derivable?[real](atanN(n / 2 - 1));

  % Subtype TCC generated (at line 181, column 23) for
      % (atanD(n / 2 - 1) * (LAMBDA (x: real): (1 + x * x)))
      % expected type  [real -> nzreal]
  atan_nderiv_TCC4: OBLIGATION
    FORALL (n: nat):
      NOT n = 0 AND even?(n) IMPLIES
       (FORALL (x1: real):
          (*[real](atanD(n / 2 - 1), (LAMBDA (x: real): (1 + x * x))))(x1) /=
           0);

  % Subtype TCC generated (at line 182, column 28) for  (n - 1) / 2
      % expected type  nat
  atan_nderiv_TCC5: OBLIGATION
    FORALL (n: nat):
      NOT n = 0 AND NOT even?(n) IMPLIES
       integer_pred((n - 1) / 2) AND (n - 1) / 2 >= 0;

  % Subtype TCC generated (at line 182, column 37) for  atanD((n - 1) / 2)
      % expected type  [real -> nzreal]
  atan_nderiv_TCC6: OBLIGATION
    FORALL (n: nat):
      NOT n = 0 AND NOT even?(n) IMPLIES
       (FORALL (x1: real): atanD((n - 1) / 2)(x1) /= 0);

  % Subtype TCC generated (at line 186, column 44) for  ((n - 1) / 2)
      % expected type  {i: int | TRUE}
  atan_nderiv_0_TCC1: OBLIGATION
    FORALL (n: nat): NOT even?(n) IMPLIES integer_pred(((n - 1) / 2));

  % Subtype TCC generated (at line 186, column 65) for  n - 1
      % expected type  nat
  atan_nderiv_0_TCC2: OBLIGATION
    FORALL (n: nat): NOT even?(n) IMPLIES n - 1 >= 0;

  % Subtype TCC generated (at line 193, column 44) for  atan
      % expected type  nderiv_fun[real](1 + 2 * n)
  atan_series_prep8_TCC1: OBLIGATION
    FORALL (n: nat): derivable_n_times?[real](atan, 1 + 2 * n);

  % Subtype TCC generated (at line 197, column 27) for  (2 * n + 1)
      % expected type  {i: int | x /= 0 OR i >= 0}
  atan_series_term_TCC1: OBLIGATION
    FORALL (x: real, n: nat): x /= 0 OR (2 * n + 1) >= 0;

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

  % Subtype TCC generated (at line 208, column 32) for  2 * n + 2
      % expected type  T_high[nat]
  atan_series_eqv_TCC1: OBLIGATION
    FORALL (n: nat): 2 * n + 2 >= 0 OR (EXISTS (j: nat): 2 * n + 2 <= j);

  % Subtype TCC generated (at line 210, column 35) for  atan
      % expected type  nderiv_fun[real](nn)
  atan_series_eqv_TCC2: OBLIGATION
    FORALL (n, nn: nat):
      NOT nn > 2 * n + 2 AND NOT nn = 0 IMPLIES
       derivable_n_times?[real](atan, nn);

  % Subtype TCC generated (at line 210, column 46) for  nn
      % expected type  {i: int | x /= 0 OR i >= 0}
  atan_series_eqv_TCC3: OBLIGATION
    FORALL (n: nat, x: real, nn: nat):
      NOT nn > 2 * n + 2 AND NOT nn = 0 IMPLIES x /= 0 OR nn >= 0;

  % Subtype TCC generated (at line 214, column 38) for  atan
      % expected type  nderiv_fun[real](3 + 2 * n)
  atan_taylors_TCC1: OBLIGATION
    FORALL (n: nat, x: real, c: between[real](0, x)):
      derivable_n_times?[real](atan, 3 + 2 * n);

  % Subtype TCC generated (at line 214, column 50) for  (2 * n + 3)
      % expected type  {i: int | x /= 0 OR i >= 0}
  atan_taylors_TCC2: OBLIGATION
    FORALL (n: nat, x: real, c: between[real](0, x)):
      x /= 0 OR (2 * n + 3) >= 0;

  % Subtype TCC generated (at line 216, column 63) for  (2 * n + 3)
      % expected type  {i: int | x /= 0 OR i >= 0}
  atan_series_TCC1: OBLIGATION
    FORALL (n: nat, x: real): x /= 0 OR (2 * n + 3) >= 0;


body:
  asin: THEORY

    BEGIN
   
    IMPORTING reals@sq, reals@sqrt
    IMPORTING atan
  % IMPORTING reals@prelude_aux_reals
    IMPORTING analysis@sqrt_derivative, analysis@derivative_props, analysis@deriv_domains

  %  real_abs_le1:   NONEMPTY_TYPE = {x:real | abs(x) <= 1}    CONTAINING 0
  %  real_abs_lt1:   NONEMPTY_TYPE = {x:real | abs(x) <  1}    CONTAINING 0
  %  real_abs_le_pi2: NONEMPTY_TYPE = {x:real | abs(x) <= pi/2} CONTAINING 0


    real_abs_le1:   NONEMPTY_TYPE =  {x:real | -1 <= x AND x <= 1}    CONTAINING 0
    real_abs_lt1:   NONEMPTY_TYPE =  {x:real | -1 < x  AND x <  1}    CONTAINING 0
    real_abs_le_pi2: NONEMPTY_TYPE = {x:real | -pi/2 <= x AND x <= pi/2} CONTAINING 0


    noa_abs_lt1             : LEMMA not_one_element?[real_abs_lt1]
    noa_nnreal_lt1          : LEMMA not_one_element?[{x: nnreal | x < 1}]
    deriv_domain_abs_lt1    : LEMMA deriv_domain?[real_abs_lt1]
    deriv_domain_nnreal_lt_1: LEMMA deriv_domain?[{x: nnreal | x < 1}]

    AUTO_REWRITE+ noa_abs_lt1         
    AUTO_REWRITE+ deriv_domain_abs_lt1
    AUTO_REWRITE+ deriv_domain_nnreal_lt_1
    AUTO_REWRITE+ noa_nnreal_lt1

    x,y:     VAR real_abs_le1
    xne:     VAR real_abs_lt1
    nnx,nny: VAR {x:nnreal | x <= 1}
    nx:      VAR {x:real_abs_le1 | x < 0}
    px:      VAR {x:real_abs_le1 | 0 < x}
    nx_gt1:  VAR {x:negreal | -1 < x}
    px_lt1:  VAR {x:posreal | x < 1}

    asin(x:real_abs_le1):real_abs_le_pi2
      = IF x = -1 THEN -pi/2 ELSIF x < 1 THEN atan(x/sqrt(1-x*x)) ELSE pi/2 ENDIF

    asin_neg_restrict:      LEMMA asin(nx) = -pi/2 - atan(sqrt(1-nx*nx)/nx)
    asin_pos_restrict:      LEMMA asin(px) =  pi/2 - atan(sqrt(1-px*px)/px)
    asin_0:                 LEMMA asin(0)  = 0
    asin_sqrt_half:         LEMMA asin(sqrt(1/2)) = pi/4
    asin_1:                 LEMMA asin(1)  = pi/2
    asin_neg:               LEMMA asin(-x) = -asin(x)
    asin_minus1:  
            LEMMA asin(-1) = -pi/2
    asin_minus_sqrt_half:   LEMMA asin(-sqrt(1/2)) = -pi/4
    asin_strict_increasing: LEMMA strict_increasing?(asin)
    asin_bij:               LEMMA bijective?[real_abs_le1,real_abs_le_pi2](asin)

    asin_diff: LEMMA                                                     % 4.4.32
        asin(nnx)-asin(nny) = asin(nnx*(sqrt(1-sq(nny)))-nny*(sqrt(1-sq(nnx))))

    asin_derivable:  LEMMA
                  derivable?[real_abs_lt1]((LAMBDA (x:real_abs_lt1):asin(x)),xne)

    asin_derivable_fun: LEMMA
                  derivable?[real_abs_lt1](LAMBDA (x:real_abs_lt1): asin(x))

    deriv_asin_fun:  LEMMA deriv[real_abs_lt1](LAMBDA (x:real_abs_lt1): asin(x))
                             = (LAMBDA (x:real_abs_lt1): 1/sqrt(1-sq(x)))

    asin_pos_bnds: LEMMA px < asin(px) AND
               (px*(1-px*px/6) > 0 => asin(px*(1-px*px/6)) < px)

    END asin

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

  % Subtype TCC generated (at line 17, column 82) for  0
      % expected type  real_abs_le_pi2
  real_abs_le_pi2_TCC1: OBLIGATION -pi / 2 <= 0 AND 0 <= pi / 2;

  % Subtype TCC generated (at line 39, column 21) for  -pi / 2
      % expected type  real_abs_le_pi2
  asin_TCC1: OBLIGATION
    FORALL (x: real_abs_le1):
      x = -1 IMPLIES -pi / 2 <= -pi / 2 AND -pi / 2 <= pi / 2;

  % Subtype TCC generated (at line 39, column 56) for  1 - x * x
      % expected type  nnx: nonneg_real
  asin_TCC2: OBLIGATION
    FORALL (x: real_abs_le1): x < 1 AND NOT x = -1 IMPLIES 1 - x * x >= 0;

  % Subtype TCC generated (at line 39, column 51) for  sqrt(1 - x * x)
      % expected type  nznum
  asin_TCC3: OBLIGATION
    FORALL (x: real_abs_le1):
      x < 1 AND NOT x = -1 IMPLIES sqrt(1 - x * x) /= 0;

  % Subtype TCC generated (at line 39, column 44) for
      % atan(x / sqrt(1 - x * x))
      % expected type  real_abs_le_pi2
  asin_TCC4: OBLIGATION
    FORALL (x: real_abs_le1):
      x < 1 AND NOT x = -1 IMPLIES
       -pi / 2 <= atan(x / sqrt(1 - x * x)) AND
        atan(x / sqrt(1 - x * x)) <= pi / 2;

  % Subtype TCC generated (at line 39, column 69) for  pi / 2
      % expected type  real_abs_le_pi2
  asin_TCC5: OBLIGATION
    FORALL (x: real_abs_le1):
      NOT x < 1 AND NOT x = -1 IMPLIES -pi / 2 <= pi / 2 AND pi / 2 <= pi / 2;

  % Subtype TCC generated (at line 41, column 61) for  1 - nx * nx
      % expected type  nnx: nonneg_real
  asin_neg_restrict_TCC1: OBLIGATION
    FORALL (nx: {x: real_abs_le1 | x < 0}): 1 - nx * nx >= 0;

  % Subtype TCC generated (at line 41, column 70) for  nx
      % expected type  nznum
  asin_neg_restrict_TCC2: OBLIGATION
    FORALL (nx: {x: real_abs_le1 | x < 0}): nx /= 0;

  % Subtype TCC generated (at line 42, column 61) for  1 - px * px
      % expected type  nnx: nonneg_real
  asin_pos_restrict_TCC1: OBLIGATION
    FORALL (px: {x: real_abs_le1 | 0 < x}): 1 - px * px >= 0;

  % Subtype TCC generated (at line 42, column 70) for  px
      % expected type  nznum
  asin_pos_restrict_TCC2: OBLIGATION
    FORALL (px: {x: real_abs_le1 | 0 < x}): px /= 0;

  % Subtype TCC generated (at line 44, column 37) for  sqrt(1 / 2)
      % expected type  real_abs_le1
  asin_sqrt_half_TCC1: OBLIGATION -1 <= sqrt(1 / 2) AND sqrt(1 / 2) <= 1;

  % Subtype TCC generated (at line 46, column 37) for  -x
      % expected type  real_abs_le1
  asin_neg_TCC1: OBLIGATION FORALL (x: real_abs_le1): -1 <= -x AND -x <= 1;

  % Subtype TCC generated (at line 49, column 37) for  -sqrt(1 / 2)
      % expected type  real_abs_le1
  asin_minus_sqrt_half_TCC1: OBLIGATION
    -1 <= -sqrt(1 / 2) AND -sqrt(1 / 2) <= 1;

  % Subtype TCC generated (at line 54, column 11) for  nnx
      % expected type  real_abs_le1
  asin_diff_TCC1: OBLIGATION
    FORALL (nnx: {x: nnreal | x <= 1}): -1 <= nnx AND nnx <= 1;

  % Subtype TCC generated (at line 54, column 43) for  1 - sq(nny)
      % expected type  nnx: nonneg_real
  asin_diff_TCC2: OBLIGATION
    FORALL (nny: {x: nnreal | x <= 1}): 1 - sq(nny) >= 0;

  % Subtype TCC generated (at line 54, column 33) for
      % nnx * (sqrt(1 - sq(nny))) - nny * (sqrt(1 - sq(nnx)))
      % expected type  real_abs_le1
  asin_diff_TCC3: OBLIGATION
    FORALL (nnx, nny: {x: nnreal | x <= 1}):
      -1 <= nnx * (sqrt(1 - sq(nny))) - nny * (sqrt(1 - sq(nnx))) AND
       nnx * (sqrt(1 - sq(nny))) - nny * (sqrt(1 - sq(nnx))) <= 1;

  % Subtype TCC generated (at line 57, column 71) for  x
      % expected type  real_abs_le1
  asin_derivable_TCC1: OBLIGATION
    FORALL (x: real_abs_lt1): -1 <= x AND x <= 1;

  % Assuming TCC generated (at line 26, column 4) for
      % analysis@derivatives_def[real_abs_lt1]
      % generated from assumption derivatives_def.deriv_domain
  asin_derivable_TCC2: OBLIGATION deriv_domain?[real_abs_lt1];

  % Assuming TCC generated (at line 28, column 4) for
      % analysis@derivatives_def[real_abs_lt1]
      % generated from assumption derivatives_def.not_one_element
  asin_derivable_TCC3: OBLIGATION not_one_element?[real_abs_lt1];

  % Subtype TCC generated (at line 62, column 45) for
      % LAMBDA (x: real_abs_lt1): asin(x)
      % expected type  deriv_fun[real_abs_lt1]
  deriv_asin_fun_TCC1: OBLIGATION
    derivable?[real_abs_lt1](LAMBDA (x: real_abs_lt1): asin(x));

  % Subtype TCC generated (at line 63, column 62) for  1 - sq(x)
      % expected type  nnx: nonneg_real
  deriv_asin_fun_TCC2: OBLIGATION FORALL (x: real_abs_lt1): 1 - sq(x) >= 0;

  % Subtype TCC generated (at line 63, column 57) for  sqrt(1 - sq(x))
      % expected type  nznum
  deriv_asin_fun_TCC3: OBLIGATION
    FORALL (x: real_abs_lt1): sqrt(1 - sq(x)) /= 0;

  % Subtype TCC generated (at line 66, column 41) for  px * (1 - px * px / 6)
      % expected type  real_abs_le1
  asin_pos_bnds_TCC1: OBLIGATION
    FORALL (px: {x: real_abs_le1 | 0 < x}):
      px < asin(px) AND px * (1 - px * px / 6) > 0 IMPLIES
       -1 <= px * (1 - px * px / 6) AND px * (1 - px * px / 6) <= 1;


body:
  acos: THEORY

    BEGIN

    IMPORTING asin

    nnreal_le_pi: NONEMPTY_TYPE = {x:nnreal | x <= pi}     CONTAINING 0

    x:       VAR real_abs_le1
    xne:     VAR real_abs_lt1
    nnx,nny: VAR {x:nnreal | x <= 1}

    acos(x:real_abs_le1):nnreal_le_pi = pi/2 - asin(x)
    
    acos_neg:               LEMMA acos(-x) = pi-acos(x)
    acos_0:                 LEMMA acos(0)  = pi/2
    acos_sqrt_half:         LEMMA acos(sqrt(1/2)) = pi/4
    acos_1:                 LEMMA acos(1)  = 0
    acos_minus1:            LEMMA acos(-1) = pi
    acos_minus_sqrt_half:   LEMMA acos(-sqrt(1/2)) = 3*pi/4
    acos_strict_decreasing: LEMMA strict_decreasing?(acos)
    acos_bij:               LEMMA bijective?[real_abs_le1,nnreal_le_pi](acos)

    acos_sum: LEMMA                                                     % 4.4.32
        acos(nnx)+acos(nny) = acos(nnx*nny-(sqrt(1-sq(nny)))*(sqrt(1-sq(nnx))))

    acos_derivable:  LEMMA
                  derivable?[real_abs_lt1]((LAMBDA (x:real_abs_lt1):acos(x)),xne)

    acos_derivable_fun: LEMMA
                  derivable?[real_abs_lt1](LAMBDA (x:real_abs_lt1): acos(x))

    deriv_acos_fun:  LEMMA deriv[real_abs_lt1](LAMBDA (x:real_abs_lt1): acos(x))
       = (LAMBDA (x:real_abs_lt1): -deriv(LAMBDA (x: real_abs_lt1): asin(x))(x))


    END acos

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

  % Subtype TCC generated (at line 7, column 68) for  0
      % expected type  nnreal_le_pi
  nnreal_le_pi_TCC1: OBLIGATION 0 <= pi;

  % Subtype TCC generated (at line 13, column 38) for  pi / 2 - asin(x)
      % expected type  nnreal_le_pi
  acos_TCC1: OBLIGATION
    FORALL (x: real_abs_le1):
      pi / 2 - asin(x) >= 0 AND pi / 2 - asin(x) <= pi;

  % Subtype TCC generated (at line 15, column 37) for  -x
      % expected type  real_abs_le1
  acos_neg_TCC1: OBLIGATION FORALL (x: real_abs_le1): -1 <= -x AND -x <= 1;

  % Subtype TCC generated (at line 17, column 37) for  sqrt(1 / 2)
      % expected type  real_abs_le1
  acos_sqrt_half_TCC1: OBLIGATION -1 <= sqrt(1 / 2) AND sqrt(1 / 2) <= 1;

  % Subtype TCC generated (at line 20, column 37) for  -sqrt(1 / 2)
      % expected type  real_abs_le1
  acos_minus_sqrt_half_TCC1: OBLIGATION
    -1 <= -sqrt(1 / 2) AND -sqrt(1 / 2) <= 1;

  % Subtype TCC generated (at line 25, column 11) for  nnx
      % expected type  real_abs_le1
  acos_sum_TCC1: OBLIGATION
    FORALL (nnx: {x: nnreal | x <= 1}): -1 <= nnx AND nnx <= 1;

  % Subtype TCC generated (at line 25, column 47) for  1 - sq(nny)
      % expected type  nnx: nonneg_real
  acos_sum_TCC2: OBLIGATION
    FORALL (nny: {x: nnreal | x <= 1}): 1 - sq(nny) >= 0;

  % Subtype TCC generated (at line 25, column 33) for
      % nnx * nny - (sqrt(1 - sq(nny))) * (sqrt(1 - sq(nnx)))
      % expected type  real_abs_le1
  acos_sum_TCC3: OBLIGATION
    FORALL (nnx, nny: {x: nnreal | x <= 1}):
      -1 <= nnx * nny - (sqrt(1 - sq(nny))) * (sqrt(1 - sq(nnx))) AND
       nnx * nny - (sqrt(1 - sq(nny))) * (sqrt(1 - sq(nnx))) <= 1;

  % Subtype TCC generated (at line 28, column 71) for  x
      % expected type  real_abs_le1
  acos_derivable_TCC1: OBLIGATION
    FORALL (x: real_abs_lt1): -1 <= x AND x <= 1;

  % Assuming TCC generated (at line 26, column 4) for
      % analysis@derivatives_def[real_abs_lt1]
      % generated from assumption derivatives_def.deriv_domain
  acos_derivable_TCC2: OBLIGATION deriv_domain?[real_abs_lt1];

  % Assuming TCC generated (at line 28, column 4) for
      % analysis@derivatives_def[real_abs_lt1]
      % generated from assumption derivatives_def.not_one_element
  acos_derivable_TCC3: OBLIGATION not_one_element?[real_abs_lt1];

  % Subtype TCC generated (at line 33, column 45) for
      % LAMBDA (x: real_abs_lt1): acos(x)
      % expected type  deriv_fun[real_abs_lt1]
  deriv_acos_fun_TCC1: OBLIGATION
    derivable?[real_abs_lt1](LAMBDA (x: real_abs_lt1): acos(x));

  % Subtype TCC generated (at line 34, column 40) for
      % LAMBDA (x: real_abs_lt1): asin(x)
      % expected type  deriv_fun[real_abs_lt1]
  deriv_acos_fun_TCC2: OBLIGATION
    derivable?[real_abs_lt1](LAMBDA (x: real_abs_lt1): asin(x));


body:
  sincos_quad: THEORY
  %------------------------------------------------------------------------------
  %
  %  A foundational theory of sin(x) and cos(x) for the interval [0,pi/2]
  %
  %          David Lester                    Manchester University
  % 
  %------------------------------------------------------------------------------

  BEGIN

    IMPORTING acos, analysis@deriv_domain,
              analysis@indefinite_integral

    IMPORTING analysis@deriv_domains

    nnreal_quad1_closed: NONEMPTY_TYPE = {x:nnreal | x <= pi/2} CONTAINING 0
    nnreal_quad1_open:   NONEMPTY_TYPE = {x:nnreal | x <  pi/2} CONTAINING 0
    posreal_lt_pi:       NONEMPTY_TYPE = {x:posreal| x < pi} CONTAINING pi/2

    noa_real_lt_pi2    : LEMMA not_one_element?[real_abs_lt_pi2]
    noa_real_abs_lt1   : LEMMA not_one_element?[real_abs_lt1]
    noa_posreal_lt_pi  : LEMMA not_one_element?[posreal_lt_pi]
    noa_real_abs_lt_pi2: LEMMA not_one_element?[real_abs_lt_pi2];
    noa_posreal_lt_pi4 : LEMMA not_one_element?[{x: posreal | x < pi / 4}]

    conn_real_lt_pi2   : LEMMA connected?[real_abs_lt_pi2]
    conn_real_abs_lt1  : LEMMA connected?[real_abs_lt1]
    conn_posreal_lt_pi : LEMMA connected?[posreal_lt_pi]
    deriv_domain_real_abs_lt1  : LEMMA deriv_domain?[real_abs_lt1]
    deriv_domain_posreal_lt_pi : LEMMA deriv_domain?[posreal_lt_pi]
    deriv_domain_abs_lt_pi2    : LEMMA deriv_domain?[real_abs_lt_pi2]
    deriv_domain_posreal_lt_pi4: LEMMA deriv_domain?[{x: posreal | x < pi / 4}]

    AUTO_REWRITE+ noa_real_lt_pi2       
    AUTO_REWRITE+ noa_real_abs_lt1 
    AUTO_REWRITE+ noa_posreal_lt_pi        
    AUTO_REWRITE+ noa_real_abs_lt_pi2
    AUTO_REWRITE+ noa_posreal_lt_pi4     
    AUTO_REWRITE+ conn_real_lt_pi2      
    AUTO_REWRITE+ conn_real_abs_lt1 
    AUTO_REWRITE+ conn_posreal_lt_pi
    AUTO_REWRITE+ deriv_domain_real_abs_lt1
    AUTO_REWRITE+ deriv_domain_posreal_lt_pi
    AUTO_REWRITE+ deriv_domain_abs_lt_pi2
    AUTO_REWRITE+ deriv_domain_posreal_lt_pi4


    i:     VAR int
    a,x,y: VAR real
    px:    VAR posreal
    nnx:   VAR nnreal
    xs:    VAR real_abs_le_pi2
    xc:    VAR nnreal_le_pi
    q1,q2: VAR nnreal_quad1_closed
    qo1:   VAR nnreal_quad1_open
    xa:    VAR real_abs_le1

  % First Quadrant properties:

    sin_value:[real_abs_le_pi2->real_abs_le1] = inverse(asin)
    cos_value:[nnreal_le_pi->real_abs_le1]   = inverse(acos)

    sin_value_bij:     LEMMA bijective?[real_abs_le_pi2,real_abs_le1](sin_value)
    cos_value_bij:     LEMMA bijective?[nnreal_le_pi,real_abs_le1](cos_value)

    sin_value_strict_increasing: LEMMA strict_increasing?(sin_value)
    sin_value_increasing:        LEMMA increasing?(sin_value)
    cos_value_strict_decreasing: LEMMA strict_decreasing?(cos_value)
    cos_value_decreasing:        LEMMA decreasing?(cos_value)

    sin_value_neg:       LEMMA sin_value(-xs)   = -sin_value(xs)
    cos_value_neg:       LEMMA cos_value(pi-xc) = -cos_value(xc)
    sin_eqv_cos_value:   LEMMA sin_value(xs)    = -cos_value(pi/2+xs)
    sin_eqv_cos_quad:    LEMMA sin_value(q1)    = cos_value(pi/2-q1)
    cos_eqv_sin_quad:    LEMMA cos_value(q1)    = sin_value(pi/2-q1)
    sin_value_minus_pi2: LEMMA sin_value(-pi/2) = -1
    sin_value_0:         LEMMA sin_value(0)     =  0
    sin_value_pi4:       LEMMA sin_value(pi/4)  =  sqrt(1/2)
    sin_value_pi2:       LEMMA sin_value(pi/2)  =  1
    cos_value_0:         LEMMA cos_value(0)     =  1
    cos_value_pi4:       LEMMA cos_value(pi/4)  =  sqrt(1/2)
    cos_value_pi2:       LEMMA cos_value(pi/2)  =  0
    cos_value_pi:        LEMMA cos_value(pi)    = -1

    asin_sin_value:      LEMMA asin(sin_value(xs)) = xs
    acos_cos_value:      LEMMA acos(cos_value(xc)) = xc
    sin_value_asin:      LEMMA sin_value(asin(xa)) = xa
    cos_value_acos:      LEMMA cos_value(acos(xa)) = xa

    sin2_cos2_value:        LEMMA sq(sin_value(q1))+sq(cos_value(q1)) = 1
    sin_eqv_sqrt_cos_value: LEMMA sqrt(1-sq(cos_value(q1))) = sin_value(q1)
    cos_eqv_sqrt_sin_value: LEMMA sqrt(1-sq(sin_value(q1))) = cos_value(q1)

    atan_tan_value:      LEMMA atan(sin_value(qo1)/cos_value(qo1)) = qo1
    sin_value_atan:      LEMMA sin_value(atan(x))   = x/sqrt(1+sq(x))
    cos_value_atan:      LEMMA cos_value(atan(nnx)) = 1/sqrt(1+sq(nnx))

    sin_value_pi6:       LEMMA sin_value(pi/6)  =  1/2
    cos_value_pi6:       LEMMA cos_value(pi/6)  =  sqrt(3)/2

    cos_value_sum:  LEMMA cos_value(q1+q2) = 
                          cos_value(q1)*cos_value(q2)-sin_value(q1)*sin_value(q2)

    sin_value_diff: LEMMA sin_value(q1-q2) = 
                          sin_value(q1)*cos_value(q2)-cos_value(q1)*sin_value(q2)

    sin_value_derivable:  LEMMA FORALL (x:real_abs_lt_pi2):
          derivable?[real_abs_lt_pi2]((LAMBDA (x:real_abs_lt_pi2): sin_value(x)),x)

    sin_value_derivable_fun: LEMMA
          derivable?[real_abs_lt_pi2](LAMBDA (x:real_abs_lt_pi2): sin_value(x))

    deriv_sin_value     :   LEMMA
          deriv[real_abs_lt_pi2](LAMBDA (x:real_abs_lt_pi2): sin_value(x))
                            = (LAMBDA (x:real_abs_lt_pi2): cos_value (abs(x)))

    sin_value_sum: LEMMA  IF q1+q2 <= pi/2 THEN sin_value(q1+q2) 
                          ELSE cos_value(q1+q2-pi/2) ENDIF
                       = sin_value(q1)*cos_value(q2)+cos_value(q1)*sin_value(q2)

    cos_value_diff:  LEMMA IF q1-q2 < 0 THEN cos_value(q2-q1) 
                           ELSE cos_value(q1-q2) ENDIF
                       = cos_value(q1)*cos_value(q2)+sin_value(q1)*sin_value(q2)

    cos_value_derivable:  LEMMA FORALL (x:posreal_lt_pi):
          derivable?[posreal_lt_pi]((LAMBDA (x:posreal_lt_pi): cos_value(x)),x)

    cos_value_derivable_fun: LEMMA
          derivable?[posreal_lt_pi](LAMBDA (x:posreal_lt_pi): cos_value(x))

    deriv_cos_value:   LEMMA
       deriv[posreal_lt_pi](LAMBDA (x:posreal_lt_pi): cos_value(x))
               = (LAMBDA (x:posreal_lt_pi): IF x < pi/2 THEN -sin_value(x)
                                            ELSE -sin_value(pi-x) ENDIF)

    END sincos_quad

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

  % Subtype TCC generated (at line 17, column 73) for  0
      % expected type  nnreal_quad1_closed
  nnreal_quad1_closed_TCC1: OBLIGATION 0 <= pi / 2;

  % Subtype TCC generated (at line 18, column 73) for  0
      % expected type  nnreal_quad1_open
  nnreal_quad1_open_TCC1: OBLIGATION 0 < pi / 2;

  % Subtype TCC generated (at line 19, column 70) for  pi / 2
      % expected type  posreal_lt_pi
  posreal_lt_pi_TCC1: OBLIGATION pi / 2 < pi;

  % Subtype TCC generated (at line 72, column 39) for  -xs
      % expected type  real_abs_le_pi2
  sin_value_neg_TCC1: OBLIGATION
    FORALL (xs: real_abs_le_pi2): -pi / 2 <= -xs AND -xs <= pi / 2;

  % Subtype TCC generated (at line 73, column 39) for  pi - xc
      % expected type  nnreal_le_pi
  cos_value_neg_TCC1: OBLIGATION
    FORALL (xc: nnreal_le_pi): pi - xc >= 0 AND pi - xc <= pi;

  % Subtype TCC generated (at line 74, column 59) for  pi / 2 + xs
      % expected type  nnreal_le_pi
  sin_eqv_cos_value_TCC1: OBLIGATION
    FORALL (xs: real_abs_le_pi2): pi / 2 + xs >= 0 AND pi / 2 + xs <= pi;

  % Subtype TCC generated (at line 75, column 39) for  q1
      % expected type  real_abs_le_pi2
  sin_eqv_cos_quad_TCC1: OBLIGATION
    FORALL (q1: nnreal_quad1_closed): -pi / 2 <= q1 AND q1 <= pi / 2;

  % Subtype TCC generated (at line 75, column 58) for  pi / 2 - q1
      % expected type  nnreal_le_pi
  sin_eqv_cos_quad_TCC2: OBLIGATION
    FORALL (q1: nnreal_quad1_closed): pi / 2 - q1 >= 0 AND pi / 2 - q1 <= pi;

  % Subtype TCC generated (at line 76, column 39) for  q1
      % expected type  nnreal_le_pi
  cos_eqv_sin_quad_TCC1: OBLIGATION
    FORALL (q1: nnreal_quad1_closed): q1 <= pi;

  % Subtype TCC generated (at line 76, column 58) for  pi / 2 - q1
      % expected type  real_abs_le_pi2
  cos_eqv_sin_quad_TCC2: OBLIGATION
    FORALL (q1: nnreal_quad1_closed):
      -pi / 2 <= pi / 2 - q1 AND pi / 2 - q1 <= pi / 2;

  % Subtype TCC generated (at line 77, column 39) for  -pi / 2
      % expected type  real_abs_le_pi2
  sin_value_minus_pi2_TCC1: OBLIGATION
    -pi / 2 <= -pi / 2 AND -pi / 2 <= pi / 2;

  % Subtype TCC generated (at line 78, column 39) for  0
      % expected type  real_abs_le_pi2
  sin_value_0_TCC1: OBLIGATION -pi / 2 <= 0 AND 0 <= pi / 2;

  % Subtype TCC generated (at line 79, column 39) for  pi / 4
      % expected type  real_abs_le_pi2
  sin_value_pi4_TCC1: OBLIGATION -pi / 2 <= pi / 4 AND pi / 4 <= pi / 2;

  % Subtype TCC generated (at line 80, column 39) for  pi / 2
      % expected type  real_abs_le_pi2
  sin_value_pi2_TCC1: OBLIGATION -pi / 2 <= pi / 2 AND pi / 2 <= pi / 2;

  % Subtype TCC generated (at line 81, column 39) for  0
      % expected type  nnreal_le_pi
  cos_value_0_TCC1: OBLIGATION 0 <= pi;

  % Subtype TCC generated (at line 82, column 39) for  pi / 4
      % expected type  nnreal_le_pi
  cos_value_pi4_TCC1: OBLIGATION pi / 4 <= pi;

  % Subtype TCC generated (at line 83, column 39) for  pi / 2
      % expected type  nnreal_le_pi
  cos_value_pi2_TCC1: OBLIGATION pi / 2 <= pi;

  % Subtype TCC generated (at line 84, column 39) for  pi
      % expected type  nnreal_le_pi
  cos_value_pi_TCC1: OBLIGATION pi <= pi;

  % Subtype TCC generated (at line 92, column 37) for  1 - sq(cos_value(q1))
      % expected type  nnx: nonneg_real
  sin_eqv_sqrt_cos_value_TCC1: OBLIGATION
    FORALL (q1: nnreal_quad1_closed): 1 - sq(cos_value(q1)) >= 0;

  % Subtype TCC generated (at line 93, column 37) for  1 - sq(sin_value(q1))
      % expected type  nnx: nonneg_real
  cos_eqv_sqrt_sin_value_TCC1: OBLIGATION
    FORALL (q1: nnreal_quad1_closed): 1 - sq(sin_value(q1)) >= 0;

  % Subtype TCC generated (at line 95, column 44) for  qo1
      % expected type  real_abs_le_pi2
  atan_tan_value_TCC1: OBLIGATION
    FORALL (qo1: nnreal_quad1_open): -pi / 2 <= qo1 AND qo1 <= pi / 2;

  % Subtype TCC generated (at line 95, column 59) for  qo1
      % expected type  nnreal_le_pi
  atan_tan_value_TCC2: OBLIGATION FORALL (qo1: nnreal_quad1_open): qo1 <= pi;

  % Subtype TCC generated (at line 95, column 49) for  cos_value(qo1)
      % expected type  nznum
  atan_tan_value_TCC3: OBLIGATION
    FORALL (qo1: nnreal_quad1_open): cos_value(qo1) /= 0;

  % Subtype TCC generated (at line 96, column 39) for  atan(x)
      % expected type  real_abs_le_pi2
  sin_value_atan_TCC1: OBLIGATION
    FORALL (x: real): -pi / 2 <= atan(x) AND atan(x) <= pi / 2;

  % Subtype TCC generated (at line 97, column 39) for  atan(nnx)
      % expected type  nnreal_le_pi
  cos_value_atan_TCC1: OBLIGATION
    FORALL (nnx: nnreal): atan(nnx) >= 0 AND atan(nnx) <= pi;

  % Subtype TCC generated (at line 99, column 39) for  pi / 6
      % expected type  real_abs_le_pi2
  sin_value_pi6_TCC1: OBLIGATION -pi / 2 <= pi / 6 AND pi / 6 <= pi / 2;

  % Subtype TCC generated (at line 100, column 39) for  pi / 6
      % expected type  nnreal_le_pi
  cos_value_pi6_TCC1: OBLIGATION pi / 6 <= pi;

  % Subtype TCC generated (at line 102, column 34) for  q1 + q2
      % expected type  nnreal_le_pi
  cos_value_sum_TCC1: OBLIGATION
    FORALL (q1, q2: nnreal_quad1_closed): q1 + q2 <= pi;

  % Subtype TCC generated (at line 105, column 34) for  q1 - q2
      % expected type  real_abs_le_pi2
  sin_value_diff_TCC1: OBLIGATION
    FORALL (q1, q2: nnreal_quad1_closed):
      -pi / 2 <= q1 - q2 AND q1 - q2 <= pi / 2;

  % Subtype TCC generated (at line 109, column 75) for  x
      % expected type  real_abs_le_pi2
  sin_value_derivable_TCC1: OBLIGATION
    FORALL (x1: real_abs_lt_pi2): -pi / 2 <= x1 AND x1 <= pi / 2;

  % Assuming TCC generated (at line 26, column 4) for
      % analysis@derivatives_def[real_abs_lt_pi2]
      % generated from assumption derivatives_def.deriv_domain
  sin_value_derivable_TCC2: OBLIGATION deriv_domain?[real_abs_lt_pi2];

  % Assuming TCC generated (at line 28, column 4) for
      % analysis@derivatives_def[real_abs_lt_pi2]
      % generated from assumption derivatives_def.not_one_element
  sin_value_derivable_TCC3: OBLIGATION not_one_element?[real_abs_lt_pi2];

  % Subtype TCC generated (at line 115, column 31) for
      % LAMBDA (x: real_abs_lt_pi2): sin_value(x)
      % expected type  deriv_fun[real_abs_lt_pi2]
  deriv_sin_value_TCC1: OBLIGATION
    derivable?[real_abs_lt_pi2](LAMBDA (x: real_abs_lt_pi2): sin_value(x));

  % Subtype TCC generated (at line 116, column 68) for  abs(x)
      % expected type  nnreal_le_pi
  deriv_sin_value_TCC2: OBLIGATION FORALL (x: real_abs_lt_pi2): abs(x) <= pi;

  % Subtype TCC generated (at line 118, column 56) for  q1 + q2
      % expected type  real_abs_le_pi2
  sin_value_sum_TCC1: OBLIGATION
    FORALL (q1, q2: nnreal_quad1_closed):
      q1 + q2 <= pi / 2 IMPLIES -pi / 2 <= q1 + q2 AND q1 + q2 <= pi / 2;

  % Subtype TCC generated (at line 119, column 39) for  q1 + q2 - pi / 2
      % expected type  nnreal_le_pi
  sin_value_sum_TCC2: OBLIGATION
    FORALL (q1, q2: nnreal_quad1_closed):
      NOT q1 + q2 <= pi / 2 IMPLIES
       q1 + q2 - pi / 2 >= 0 AND q1 + q2 - pi / 2 <= pi;

  % Subtype TCC generated (at line 122, column 53) for  q2 - q1
      % expected type  nnreal_le_pi
  cos_value_diff_TCC1: OBLIGATION
    FORALL (q1, q2: nnreal_quad1_closed):
      q1 - q2 < 0 IMPLIES q2 - q1 >= 0 AND q2 - q1 <= pi;

  % Subtype TCC generated (at line 123, column 40) for  q1 - q2
      % expected type  nnreal_le_pi
  cos_value_diff_TCC2: OBLIGATION
    FORALL (q1, q2: nnreal_quad1_closed):
      NOT q1 - q2 < 0 IMPLIES q1 - q2 >= 0 AND q1 - q2 <= pi;

  % Subtype TCC generated (at line 127, column 71) for  x
      % expected type  nnreal_le_pi
  cos_value_derivable_TCC1: OBLIGATION FORALL (x1: posreal_lt_pi): x1 <= pi;

  % Assuming TCC generated (at line 26, column 4) for
      % analysis@derivatives_def[posreal_lt_pi]
      % generated from assumption derivatives_def.deriv_domain
  cos_value_derivable_TCC2: OBLIGATION deriv_domain?[posreal_lt_pi];

  % Assuming TCC generated (at line 28, column 4) for
      % analysis@derivatives_def[posreal_lt_pi]
      % generated from assumption derivatives_def.not_one_element
  cos_value_derivable_TCC3: OBLIGATION not_one_element?[posreal_lt_pi];

  % Subtype TCC generated (at line 133, column 26) for
      % LAMBDA (x: posreal_lt_pi): cos_value(x)
      % expected type  deriv_fun[posreal_lt_pi]
  deriv_cos_value_TCC1: OBLIGATION
    derivable?[posreal_lt_pi](LAMBDA (x: posreal_lt_pi): cos_value(x));

  % Subtype TCC generated (at line 134, column 70) for  x
      % expected type  real_abs_le_pi2
  deriv_cos_value_TCC2: OBLIGATION
    FORALL (x: posreal_lt_pi):
      x < pi / 2 IMPLIES -pi / 2 <= x AND x <= pi / 2;

  % Subtype TCC generated (at line 135, column 58) for  pi - x
      % expected type  real_abs_le_pi2
  deriv_cos_value_TCC3: OBLIGATION
    FORALL (x: posreal_lt_pi):
      NOT x < pi / 2 IMPLIES -pi / 2 <= pi - x AND pi - x <= pi / 2;


body:
  tan_quad: THEORY

    BEGIN
    
  % A foundational theory of tan(x) for the interval [0,pi/2)

    IMPORTING sincos_quad

    x: VAR real_abs_lt_pi2

    tan_value:[real_abs_lt_pi2->real] = inverse(atan)

    tan_value_def: LEMMA tan_value(x) = sin_value(x)/cos_value(abs(x))

    tan_value_0:   LEMMA tan_value(0) = 0
    tan_value_pi4: LEMMA tan_value(pi/4) = 1

    END tan_quad

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

  % Subtype TCC generated (at line 13, column 48) for  x
      % expected type  real_abs_le_pi2
  tan_value_def_TCC1: OBLIGATION
    FORALL (x: real_abs_lt_pi2): -pi / 2 <= x AND x <= pi / 2;

  % Subtype TCC generated (at line 13, column 61) for  abs(x)
      % expected type  nnreal_le_pi
  tan_value_def_TCC2: OBLIGATION FORALL (x: real_abs_lt_pi2): abs(x) <= pi;

  % Subtype TCC generated (at line 13, column 51) for  cos_value(abs(x))
      % expected type  nznum
  tan_value_def_TCC3: OBLIGATION
    FORALL (x: real_abs_lt_pi2): cos_value(abs(x)) /= 0;

  % Subtype TCC generated (at line 15, column 33) for  0
      % expected type  real_abs_lt_pi2
  tan_value_0_TCC1: OBLIGATION -pi / 2 < 0 AND 0 < pi / 2;

  % Subtype TCC generated (at line 16, column 33) for  pi / 4
      % expected type  real_abs_lt_pi2
  tan_value_pi4_TCC1: OBLIGATION -pi / 2 < pi / 4 AND pi / 4 < pi / 2;


body:
  sincos_phase: THEORY
  %------------------------------------------------------------------------------
  %
  %  Definitions of sin and cos from infinite series
  %
  %          David Lester                    Manchester University
  % 
  %------------------------------------------------------------------------------

    BEGIN

    IMPORTING sincos_quad

    trig_phase: NONEMPTY_TYPE = {x:nnreal| x < 2*pi} CONTAINING 0

    x,y:   VAR trig_phase
    px,py: VAR {x:posreal| x < 2*pi}
    xa:    VAR real_abs_le1
    
  % Principle Phase [0,2*pi)
    sin_phase(x:trig_phase):real_abs_le1
       = LET   i = floor((2*x)/pi) IN
         IF    i = 0 THEN  sin_value(x)
         ELSIF i = 1 THEN  sin_value(pi-x)
         ELSIF i = 2 THEN -sin_value(x-pi)
                     ELSE -sin_value(2*pi-x)
         ENDIF

    cos_phase(x:trig_phase):real_abs_le1
       = LET i = floor(x/pi) IN
         IF i = 0 THEN cos_value(x) ELSE cos_value(2*pi-x) ENDIF

    phase_sin_q1: LEMMA floor((2*x)/pi) = 0 IFF 0 <= x      AND x < pi/2
    phase_sin_q2: LEMMA floor((2*x)/pi) = 1 IFF pi/2 <= x   AND x < pi
    phase_sin_q3: LEMMA floor((2*x)/pi) = 2 IFF pi <= x     AND x < 3*pi/2
    phase_sin_q4: LEMMA floor((2*x)/pi) = 3 IFF 3*pi/2 <= x AND x < 2*pi

    phases_sin:   LEMMA floor((2*x)/pi) = 0 OR floor((2*x)/pi) = 1 OR 
                        floor((2*x)/pi) = 2 OR floor((2*x)/pi) = 3

    sin_q1: LEMMA floor((2*x)/pi) = 0 => sin_phase(x) =  sin_value(x)
    sin_q2: LEMMA floor((2*x)/pi) = 1 => sin_phase(x) =  cos_value(x-pi/2)
    sin_q3: LEMMA floor((2*x)/pi) = 2 => sin_phase(x) = -sin_value(x-pi)
    sin_q4: LEMMA floor((2*x)/pi) = 3 => sin_phase(x) = -cos_value(x-3*pi/2)

    phase_cos_q1: LEMMA floor(x/pi) = 0 IFF 0  <= x AND x < pi
    phase_cos_q2: LEMMA floor(x/pi) = 1 IFF pi <= x AND x < 2*pi

    phases_cos:   LEMMA floor(x/pi) = 0 OR floor(x/pi) = 1

    cos_q1: LEMMA floor((2*x)/pi) = 0 => cos_phase(x) =  cos_value(x)
    cos_q2: LEMMA floor((2*x)/pi) = 1 => cos_phase(x) = -sin_value(x-pi/2)
    cos_q3: LEMMA floor((2*x)/pi) = 2 => cos_phase(x) = -cos_value(x-pi)
    cos_q4: LEMMA floor((2*x)/pi) = 3 => cos_phase(x) =  sin_value(x-3*pi/2)

    sin_h2: LEMMA floor(x/pi) = 1 => sin_phase(x) = -sin_phase(x-pi)
    sin_h1: LEMMA floor(x/pi) = 0 => sin_phase(x) = -sin_phase(x+pi)
    cos_h1: LEMMA floor(x/pi) = 0 => cos_phase(x) = -cos_phase(x+pi)
    cos_h2: LEMMA floor(x/pi) = 1 => cos_phase(x) = -cos_phase(x-pi)

    sin_phase_neg:       LEMMA sin_phase(2*pi-px) = -sin_phase(px)
    cos_phase_neg:       LEMMA cos_phase(2*pi-px) =  cos_phase(px)
    sin_eqv_cos_phase:   LEMMA
      sin_phase(x) = IF x < 3*pi/2 THEN -cos_phase(pi/2+x)
                                   ELSE -cos_phase(x-3*pi/2) ENDIF
    cos_eqv_sin_phase:   LEMMA
      cos_phase(x) = IF x < 3*pi/2 THEN sin_phase(pi/2+x)
                                   ELSE sin_phase(x-3*pi/2) ENDIF
    sin_phase_inv:       LEMMA
      sin_phase(x) = IF x < pi THEN -sin_phase(x+pi) ELSE -sin_phase(x-pi) ENDIF
    cos_phase_inv:       LEMMA
      cos_phase(x) = IF x < pi THEN -cos_phase(x+pi) ELSE -cos_phase(x-pi) ENDIF
    sin_phase_3pi2:      LEMMA sin_phase(3*pi/2) = -1
    sin_phase_0:         LEMMA sin_phase(0)      =  0
    sin_phase_pi4:       LEMMA sin_phase(pi/4)   =  sqrt(1/2)
    sin_phase_pi2:       LEMMA sin_phase(pi/2)   =  1
    cos_phase_0:         LEMMA cos_phase(0)      =  1
    cos_phase_pi4:       LEMMA cos_phase(pi/4)   =  sqrt(1/2)
    cos_phase_pi2:       LEMMA cos_phase(pi/2)   =  0
    cos_phase_pi:        LEMMA cos_phase(pi)     = -1

    sin_phase_asin:      LEMMA IF xa < 0 THEN sin_phase(asin(xa)+2*pi)
                                         ELSE sin_phase(asin(xa)) ENDIF = xa
    cos_phase_acos:      LEMMA cos_phase(acos(xa)) = xa

    sin2_cos2_phase:     LEMMA sq(sin_phase(x))+sq(cos_phase(x)) = 1

    sin_phase_diff: LEMMA sin_phase(x)*cos_phase(y)-cos_phase(x)*sin_phase(y)
       = IF x-y >= 0   THEN sin_phase(x-y) ELSE sin_phase(x-y+2*pi) ENDIF

    cos_phase_sum:  LEMMA cos_phase(x)*cos_phase(y)-sin_phase(x)*sin_phase(y)
       = IF x+y < 2*pi THEN cos_phase(x+y) ELSE cos_phase(x+y-2*pi) ENDIF 

    cos_phase_diff:  LEMMA cos_phase(x)*cos_phase(y)+sin_phase(x)*sin_phase(y)
       = IF x-y >= 0   THEN cos_phase(x-y) ELSE cos_phase(x-y+2*pi) ENDIF 

    sin_phase_sum:  LEMMA sin_phase(x)*cos_phase(y)+cos_phase(x)*sin_phase(y)
       = IF x+y < 2*pi THEN sin_phase(x+y) ELSE sin_phase(x+y-2*pi) ENDIF

    END sincos_phase

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

  % Subtype TCC generated (at line 14, column 62) for  0
      % expected type  trig_phase
  trig_phase_TCC1: OBLIGATION 0 < 2 * pi;

  % Subtype TCC generated (at line 23, column 35) for  x
      % expected type  real_abs_le_pi2
  sin_phase_TCC1: OBLIGATION
    FORALL (x: trig_phase,
            i: {i | i <= (2 * x) / pi & (2 * x) / pi < 1 + i}):
      i = 0 AND i = floor((2 * x) / pi) IMPLIES -pi / 2 <= x AND x <= pi / 2;

  % Subtype TCC generated (at line 24, column 35) for  pi - x
      % expected type  real_abs_le_pi2
  sin_phase_TCC2: OBLIGATION
    FORALL (x: trig_phase,
            i: {i | i <= (2 * x) / pi & (2 * x) / pi < 1 + i}):
      i = 1 AND NOT i = 0 AND i = floor((2 * x) / pi) IMPLIES
       -pi / 2 <= pi - x AND pi - x <= pi / 2;

  % Subtype TCC generated (at line 25, column 35) for  x - pi
      % expected type  real_abs_le_pi2
  sin_phase_TCC3: OBLIGATION
    FORALL (x: trig_phase,
            i: {i | i <= (2 * x) / pi & (2 * x) / pi < 1 + i}):
      i = 2 AND NOT i = 1 AND NOT i = 0 AND i = floor((2 * x) / pi) IMPLIES
       -pi / 2 <= x - pi AND x - pi <= pi / 2;

  % Subtype TCC generated (at line 25, column 24) for  -sin_value(x - pi)
      % expected type  real_abs_le1
  sin_phase_TCC4: OBLIGATION
    FORALL (x: trig_phase,
            i: {i | i <= (2 * x) / pi & (2 * x) / pi < 1 + i}):
      i = 2 AND NOT i = 1 AND NOT i = 0 AND i = floor((2 * x) / pi) IMPLIES
       -1 <= -sin_value(x - pi) AND -sin_value(x - pi) <= 1;

  % Subtype TCC generated (at line 26, column 35) for  2 * pi - x
      % expected type  real_abs_le_pi2
  sin_phase_TCC5: OBLIGATION
    FORALL (x: trig_phase,
            i: {i | i <= (2 * x) / pi & (2 * x) / pi < 1 + i}):
      NOT i = 2 AND NOT i = 1 AND NOT i = 0 AND i = floor((2 * x) / pi)
       IMPLIES -pi / 2 <= 2 * pi - x AND 2 * pi - x <= pi / 2;

  % Subtype TCC generated (at line 26, column 24) for  -sin_value(2 * pi - x)
      % expected type  real_abs_le1
  sin_phase_TCC6: OBLIGATION
    FORALL (x: trig_phase,
            i: {i | i <= (2 * x) / pi & (2 * x) / pi < 1 + i}):
      NOT i = 2 AND NOT i = 1 AND NOT i = 0 AND i = floor((2 * x) / pi)
       IMPLIES -1 <= -sin_value(2 * pi - x) AND -sin_value(2 * pi - x) <= 1;

  % Subtype TCC generated (at line 31, column 31) for  x
      % expected type  nnreal_le_pi
  cos_phase_TCC1: OBLIGATION
    FORALL (x: trig_phase, i: {i | i <= x / pi & x / pi < 1 + i}):
      i = 0 AND i = floor(x / pi) IMPLIES x <= pi;

  % Subtype TCC generated (at line 31, column 49) for  2 * pi - x
      % expected type  nnreal_le_pi
  cos_phase_TCC2: OBLIGATION
    FORALL (x: trig_phase, i: {i | i <= x / pi & x / pi < 1 + i}):
      NOT i = 0 AND i = floor(x / pi) IMPLIES
       2 * pi - x >= 0 AND 2 * pi - x <= pi;

  % Subtype TCC generated (at line 41, column 65) for  x
      % expected type  real_abs_le_pi2
  sin_q1_TCC1: OBLIGATION
    FORALL (x: trig_phase):
      floor((2 * x) / pi) = 0 IMPLIES -pi / 2 <= x AND x <= pi / 2;

  % Subtype TCC generated (at line 42, column 65) for  x - pi / 2
      % expected type  nnreal_le_pi
  sin_q2_TCC1: OBLIGATION
    FORALL (x: trig_phase):
      floor((2 * x) / pi) = 1 IMPLIES x - pi / 2 >= 0 AND x - pi / 2 <= pi;

  % Subtype TCC generated (at line 43, column 65) for  x - pi
      % expected type  real_abs_le_pi2
  sin_q3_TCC1: OBLIGATION
    FORALL (x: trig_phase):
      floor((2 * x) / pi) = 2 IMPLIES -pi / 2 <= x - pi AND x - pi <= pi / 2;

  % Subtype TCC generated (at line 44, column 65) for  x - 3 * pi / 2
      % expected type  nnreal_le_pi
  sin_q4_TCC1: OBLIGATION
    FORALL (x: trig_phase):
      floor((2 * x) / pi) = 3 IMPLIES
       x - 3 * pi / 2 >= 0 AND x - 3 * pi / 2 <= pi;

  % Subtype TCC generated (at line 51, column 65) for  x
      % expected type  nnreal_le_pi
  cos_q1_TCC1: OBLIGATION
    FORALL (x: trig_phase): floor((2 * x) / pi) = 0 IMPLIES x <= pi;

  % Subtype TCC generated (at line 52, column 65) for  x - pi / 2
      % expected type  real_abs_le_pi2
  cos_q2_TCC1: OBLIGATION
    FORALL (x: trig_phase):
      floor((2 * x) / pi) = 1 IMPLIES
       -pi / 2 <= x - pi / 2 AND x - pi / 2 <= pi / 2;

  % Subtype TCC generated (at line 53, column 65) for  x - pi
      % expected type  nnreal_le_pi
  cos_q3_TCC1: OBLIGATION
    FORALL (x: trig_phase):
      floor((2 * x) / pi) = 2 IMPLIES x - pi >= 0 AND x - pi <= pi;

  % Subtype TCC generated (at line 54, column 65) for  x - 3 * pi / 2
      % expected type  real_abs_le_pi2
  cos_q4_TCC1: OBLIGATION
    FORALL (x: trig_phase):
      floor((2 * x) / pi) = 3 IMPLIES
       -pi / 2 <= x - 3 * pi / 2 AND x - 3 * pi / 2 <= pi / 2;

  % Subtype TCC generated (at line 56, column 61) for  x - pi
      % expected type  trig_phase
  sin_h2_TCC1: OBLIGATION
    FORALL (x: trig_phase):
      floor(x / pi) = 1 IMPLIES x - pi >= 0 AND x - pi < 2 * pi;

  % Subtype TCC generated (at line 57, column 61) for  x + pi
      % expected type  trig_phase
  sin_h1_TCC1: OBLIGATION
    FORALL (x: trig_phase): floor(x / pi) = 0 IMPLIES x + pi < 2 * pi;

  % Subtype TCC generated (at line 61, column 39) for  2 * pi - px
      % expected type  trig_phase
  sin_phase_neg_TCC1: OBLIGATION
    FORALL (px: {x: posreal | x < 2 * pi}):
      2 * pi - px >= 0 AND 2 * pi - px < 2 * pi;

  % Subtype TCC generated (at line 64, column 49) for  pi / 2 + x
      % expected type  trig_phase
  sin_eqv_cos_phase_TCC1: OBLIGATION
    FORALL (x: trig_phase): x < 3 * pi / 2 IMPLIES pi / 2 + x < 2 * pi;

  % Subtype TCC generated (at line 65, column 49) for  x - 3 * pi / 2
      % expected type  trig_phase
  sin_eqv_cos_phase_TCC2: OBLIGATION
    FORALL (x: trig_phase):
      NOT x < 3 * pi / 2 IMPLIES
       x - 3 * pi / 2 >= 0 AND x - 3 * pi / 2 < 2 * pi;

  % Subtype TCC generated (at line 70, column 45) for  x + pi
      % expected type  trig_phase
  sin_phase_inv_TCC1: OBLIGATION
    FORALL (x: trig_phase): x < pi IMPLIES x + pi < 2 * pi;

  % Subtype TCC generated (at line 70, column 67) for  x - pi
      % expected type  trig_phase
  sin_phase_inv_TCC2: OBLIGATION
    FORALL (x: trig_phase):
      NOT x < pi IMPLIES x - pi >= 0 AND x - pi < 2 * pi;

  % Subtype TCC generated (at line 73, column 39) for  3 * pi / 2
      % expected type  trig_phase
  sin_phase_3pi2_TCC1: OBLIGATION 3 * pi / 2 < 2 * pi;

  % Subtype TCC generated (at line 75, column 39) for  pi / 4
      % expected type  trig_phase
  sin_phase_pi4_TCC1: OBLIGATION pi / 4 < 2 * pi;

  % Subtype TCC generated (at line 76, column 39) for  pi / 2
      % expected type  trig_phase
  sin_phase_pi2_TCC1: OBLIGATION pi / 2 < 2 * pi;

  % Subtype TCC generated (at line 80, column 39) for  pi
      % expected type  trig_phase
  cos_phase_pi_TCC1: OBLIGATION pi < 2 * pi;

  % Subtype TCC generated (at line 82, column 54) for  asin(xa) + 2 * pi
      % expected type  trig_phase
  sin_phase_asin_TCC1: OBLIGATION
    FORALL (xa: real_abs_le1):
      xa < 0 IMPLIES asin(xa) + 2 * pi >= 0 AND asin(xa) + 2 * pi < 2 * pi;

  % Subtype TCC generated (at line 83, column 54) for  asin(xa)
      % expected type  trig_phase
  sin_phase_asin_TCC2: OBLIGATION
    FORALL (xa: real_abs_le1):
      NOT xa < 0 IMPLIES asin(xa) >= 0 AND asin(xa) < 2 * pi;

  % Subtype TCC generated (at line 84, column 39) for  acos(xa)
      % expected type  trig_phase
  cos_phase_acos_TCC1: OBLIGATION
    FORALL (xa: real_abs_le1): acos(xa) < 2 * pi;

  % Subtype TCC generated (at line 89, column 36) for  x - y
      % expected type  trig_phase
  sin_phase_diff_TCC1: OBLIGATION
    FORALL (x, y: trig_phase): x - y >= 0 IMPLIES x - y < 2 * pi;

  % Subtype TCC generated (at line 89, column 56) for  x - y + 2 * pi
      % expected type  trig_phase
  sin_phase_diff_TCC2: OBLIGATION
    FORALL (x, y: trig_phase):
      NOT x - y >= 0 IMPLIES x - y + 2 * pi >= 0 AND x - y + 2 * pi < 2 * pi;

  % Subtype TCC generated (at line 92, column 56) for  x + y - 2 * pi
      % expected type  trig_phase
  cos_phase_sum_TCC1: OBLIGATION
    FORALL (x, y: trig_phase):
      NOT x + y < 2 * pi IMPLIES
       x + y - 2 * pi >= 0 AND x + y - 2 * pi < 2 * pi;


body:
  sincos_def: THEORY
  %----------------------------------------------------------------------------
  % Defining sin, cos and tan. And making the connections with the inverses.
  %
  % David R Lester 30/5/04
  %----------------------------------------------------------------------------
  BEGIN
    IMPORTING sincos_phase, tan_quad

    a: VAR real

  %------------------------------------------------------------------------------
  % the following ripped out of trig_basic and placed here...

    trig_range  : TYPE = {a | -1 <= a AND a <= 1}

    x: VAR trig_range

    sin(x:real): real = sin_phase(x-2*pi*floor(x/(2*pi)))
    cos(x:real): real = cos_phase(x-2*pi*floor(x/(2*pi)))

    sin_range   : JUDGEMENT sin(a) HAS_TYPE trig_range
    cos_range   : JUDGEMENT cos(a) HAS_TYPE trig_range

    sin_range_ax: LEMMA -1 <= sin(a) AND sin(a) <= 1
    cos_range_ax: LEMMA -1 <= cos(a) AND cos(a) <= 1

    Tan?(a)        : bool = cos(a) /= 0
   
    tan(a:(Tan?))  : real = sin(a)/cos(a)

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

    tan_rew:       LEMMA FORALL (a:(Tan?)): sin(a)/cos(a) = tan(a)

  % Range reduction equivalences:

    sin_sin_phase: LEMMA 0     <= a AND a < 2*pi  IMPLIES sin(a) = sin_phase(a)
    cos_cos_phase: LEMMA 0     <= a AND a < 2*pi  IMPLIES cos(a) = cos_phase(a)
    sin_sin_value: LEMMA -pi/2 <= a AND a <= pi/2 IMPLIES sin(a) = sin_value(a)
    cos_cos_value: LEMMA 0     <= a AND a <= pi   IMPLIES cos(a) = cos_value(a)

    tan_value_TCC: LEMMA -pi/2 <  a AND a <  pi/2 IMPLIES Tan?(a)

    tan_tan_value: LEMMA -pi/2 <  a AND a <  pi/2 IMPLIES tan(a) = tan_value(a)

    sin_asin: LEMMA sin(asin(x)) = x
    cos_acos: LEMMA cos(acos(x)) = x
    tan_atan: LEMMA tan(atan(a)) = a

    asin_sin: LEMMA FORALL (x:real_abs_le_pi2): asin(sin(x)) = x
    acos_cos: LEMMA FORALL (x:nnreal_le_pi):   acos(cos(x)) = x
    atan_tan: LEMMA FORALL (x:real_abs_lt_pi2): atan(tan(x)) = x

  END sincos_def

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

  % Subtype TCC generated (at line 19, column 32) for
      % x - 2 * pi * floor(x / (2 * pi))
      % expected type  trig_phase
  sin_TCC1: OBLIGATION
    FORALL (x: real):
      x - 2 * pi * floor(x / (2 * pi)) >= 0 AND
       x - 2 * pi * floor(x / (2 * pi)) < 2 * pi;

  % Judgement subtype TCC generated (at line 22, column 26) for  sin(a)
      % expected type  trig_range
  sin_range: OBLIGATION FORALL (a): -1 <= sin(a) AND sin(a) <= 1;

  % Judgement subtype TCC generated (at line 23, column 26) for  cos(a)
      % expected type  trig_range
  cos_range: OBLIGATION FORALL (a): -1 <= cos(a) AND cos(a) <= 1;

  % Subtype TCC generated (at line 30, column 33) for  cos(a)
      % expected type  nznum
  tan_TCC1: OBLIGATION FORALL (a: (Tan?)): cos(a) /= 0;

  % Subtype TCC generated (at line 38, column 75) for  a
      % expected type  trig_phase
  sin_sin_phase_TCC1: OBLIGATION
    FORALL (a: real): a < 2 * pi AND 0 <= a IMPLIES a >= 0;

  % Subtype TCC generated (at line 40, column 75) for  a
      % expected type  real_abs_le_pi2
  sin_sin_value_TCC1: OBLIGATION
    FORALL (a: real):
      a <= pi / 2 AND -pi / 2 <= a IMPLIES -pi / 2 <= a AND a <= pi / 2;

  % Subtype TCC generated (at line 41, column 75) for  a
      % expected type  nnreal_le_pi
  cos_cos_value_TCC1: OBLIGATION
    FORALL (a: real): a <= pi AND 0 <= a IMPLIES a >= 0;

  % Subtype TCC generated (at line 45, column 60) for  a
      % expected type  (Tan?)
  tan_tan_value_TCC1: OBLIGATION
    FORALL (a: real): a < pi / 2 AND -pi / 2 < a IMPLIES Tan?(a);

  % Subtype TCC generated (at line 45, column 75) for  a
      % expected type  real_abs_lt_pi2
  tan_tan_value_TCC2: OBLIGATION
    FORALL (a: real):
      a < pi / 2 AND -pi / 2 < a IMPLIES -pi / 2 < a AND a < pi / 2;

  % Subtype TCC generated (at line 49, column 22) for  atan(a)
      % expected type  (Tan?)
  tan_atan_TCC1: OBLIGATION FORALL (a: real): Tan?(atan(a));

  % Subtype TCC generated (at line 53, column 55) for  x
      % expected type  (Tan?)
  atan_tan_TCC1: OBLIGATION FORALL (x: real_abs_lt_pi2): Tan?(x);


body:
  atan_approx: THEORY
  %-----------------------------------------------------------------------------
  %      atan_approx by David Lester
  %      -----------
  %      Defines upper and lower bounds on atan and pi:
  %           - atan_lb(a,n) <= atan(a) <= atan_ub(a,n)
  %           - pi_lb(a,n) <= pi <= pi_ub(n)
  %
  %      Additions 2012 by Anthony Narkawicz
  %
  %-----------------------------------------------------------------------------
    BEGIN

    IMPORTING atan,sincos_def

    m,n   : VAR nat
    x     : VAR real
    px,py : VAR posreal

    atan_pos_le1_ub(n,x): real = atan_series_n(x,2*n)
    atan_pos_le1_lb(n,x): real = atan_series_n(x,2*n+1)

    atan_pos_le1_ub_lt : LEMMA
      0 < x AND x <= 1 IMPLIES
      atan_pos_le1_ub(n+1,x) < atan_pos_le1_ub(n,x)

    atan_pos_le1_lb_lt : LEMMA
      0 < x AND x <= 1 IMPLIES
      atan_pos_le1_lb(n,x) < atan_pos_le1_lb(n+1,x)

    atan_pos_le1_bounds: LEMMA 0 < x AND x <= 1 IMPLIES
      (atan_pos_le1_lb(n,x) < atan(x) AND atan(x) < atan_pos_le1_ub(n,x))

    atan_pos_le1_lb_inc: LEMMA px <= 1 AND n < m =>
                               atan_pos_le1_lb(n,px) < atan_pos_le1_lb(m,px)

    atan_pos_le1_ub_dec: LEMMA px <= 1 AND n < m =>
                               atan_pos_le1_ub(m,px) < atan_pos_le1_ub(n,px)

    pi_lbn(n): real = 4*(4*atan_pos_le1_lb(n,1/5) - atan_pos_le1_ub(n,1/239))
    pi_ubn(n): real = 4*(4*atan_pos_le1_ub(n,1/5) - atan_pos_le1_lb(n,1/239))

    pi_lbn_lt : LEMMA
      pi_lbn(n) < pi_lbn(n+1)

    pi_lbn_LT : LEMMA
      FORALL (k:above(n)):
        pi_lbn(n) < pi_lbn(k)

    pi_bounds: LEMMA pi_lbn(n) < pi AND pi < pi_ubn(n)

    pi_lb_pos : JUDGEMENT
      pi_lbn(n) HAS_TYPE posreal 

    pi_ub_pos : JUDGEMENT
      pi_ubn(n) HAS_TYPE posreal 

    pi_bounds0: LEMMA pi_lbn(0) = 281476/89625 AND    % > 3.1405
                      pi_ubn(0) = 651864872/204778785 % < 3.1837

    pi_lb : posreal = 31415926/10000000

    pi_ub : posreal = 31415927/10000000

    pi_bounds2: LEMMA pi_lb < pi_lbn(2) AND pi_ubn(2) < pi_ub

    pi_bound : JUDGEMENT pi HAS_TYPE {r:posreal | pi_lb < r AND r < pi_ub}

    pi_lb_inc: LEMMA n < m => pi_lbn(n) < pi_lbn(m)

    pi_ub_dec: LEMMA n < m => pi_ubn(m) < pi_ubn(n)

    atan_pos_lb(n,px): real = IF px <= 1 THEN atan_pos_le1_lb(n,px) ELSE
                              max(atan_pos_le1_lb(n,1),pi_lbn(n)/2 - atan_pos_le1_ub(n,1/px)) ENDIF

    atan_pos_ub(n,px): real = IF px <= 1 THEN atan_pos_le1_ub(n,px) ELSE
                              max(atan_pos_le1_ub(n,1),pi_ubn(n)/2 - atan_pos_le1_lb(n,1/px)) ENDIF

    atan_pos_bounds: LEMMA 0 < x IMPLIES
      (atan_pos_lb(n,x) < atan(x) AND atan(x) < atan_pos_ub(n,x))

    atan_lb(x,n): real = IF    x > 0 THEN atan_pos_lb(n,x)
                         ELSIF x = 0 THEN 0
                                     ELSE -atan_pos_ub(n,-x) ENDIF

    atan_ub(x,n): real = IF    x > 0 THEN atan_pos_ub(n,x)
                         ELSIF x = 0 THEN 0
                                     ELSE -atan_pos_lb(n,-x) ENDIF

    atan_bounds: LEMMA atan_lb(x,n) <= atan(x) AND atan(x) <= atan_ub(x,n)

    atan_lb_increasing: LEMMA increasing?(LAMBDA (x:real): atan_lb(x,n))

    atan_ub_increasing: LEMMA increasing?(LAMBDA (x:real): atan_ub(x,n))

    atan_pos_lb_inc: LEMMA n <= m => atan_pos_lb(n,px) <= atan_pos_lb(m,px)

    atan_pos_ub_dec: LEMMA n <= m => atan_pos_ub(m,px) <= atan_pos_ub(n,px)

    pi_lb_pi: LEMMA pi-pi_lbn(n) <= 16*((1/5)^(4*n+5)/(4*n+5)) +
                                    4*((1/239)^(4*n+3)/(4*n+3))

    pi_ub_pi: LEMMA pi_ubn(n)-pi <= 16*((1/5)^(4*n+3)/(4*n+3)) +
                                    4*((1/239)^(4*n+5)/(4*n+5))

    pi_lb_diff: LEMMA pi_lbn(n+1)-pi_lbn(n) = 
                      16*(1/5)^(4*n+5)*(1/(4*n+5) - 1/(25*(4*n+7))) +
                      4*(1/239)^(4*n+3)*(1/(4*n+3) - 1/(57121*(4*n+5)))

    pi_ub_diff: LEMMA pi_ubn(n)-pi_ubn(n+1) = 
                     16*(((1/5)^(3+4*n))*(1/(3+4*n)))
  		   -16*(((1/5)^(5+4*n))*(1/(5+4*n)))
  		   +4*(((1/239)^(5+4*n))*(1/(5+4*n)))
  		   -4*(((1/239)^(7+4*n))*(1/(7+4*n)))

    pi_lb_diff_bounds: LEMMA n>=5 IMPLIES
      LET xdiff = pi_lbn(n+1)-pi_lbn(n) IN
      14*(1/5)^(5*n+5) < xdiff AND xdiff < (116/25)*(1/5)^(4*n+3)

    pi_lb_quot_bounds: LEMMA 
      LET xquot = pi_lbn(n)/pi_lbn(n+1) IN
      1-14.5*(1/5)^(4*n+3) <= xquot AND xquot <= 1

    pi_ub_diff_bounds: LEMMA n>=5 IMPLIES
      LET xdiff = pi_ubn(n)-pi_ubn(n+1) IN
      32*(1/5)^(5*n+3) < xdiff AND xdiff < (7/5)*(1/5)^(4*n+3)

    pi_ub_quot_bounds: LEMMA 
      LET xquot = pi_ubn(n+1)/pi_ubn(n) IN
      1-(9/5)*(1/5)^(4*n+3) <= xquot AND xquot <= 1

    END atan_approx

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

  % Judgement subtype TCC generated (at line 53, column 4) for  pi_lbn(n)
      % expected type  posreal
  pi_lb_pos: OBLIGATION FORALL (n): pi_lbn(n) >= 0 AND pi_lbn(n) > 0;

  % Judgement subtype TCC generated (at line 56, column 4) for  pi_ubn(n)
      % expected type  posreal
  pi_ub_pos: OBLIGATION FORALL (n): pi_ubn(n) >= 0 AND pi_ubn(n) > 0;

  % Judgement subtype TCC generated (at line 67, column 23) for  pi
      % expected type  {r: posreal | pi_lb < r AND r < pi_ub}
  pi_bound: OBLIGATION pi_lb < pi AND pi < pi_ub;

  % Subtype TCC generated (at line 80, column 19) for  x
      % expected type  posreal
  atan_pos_bounds_TCC1: OBLIGATION
    FORALL (x: real): 0 < x IMPLIES x >= 0 AND x > 0;

  % Subtype TCC generated (at line 82, column 54) for  x
      % expected type  posreal
  atan_lb_TCC1: OBLIGATION FORALL (x: real): x > 0 IMPLIES x >= 0;

  % Subtype TCC generated (at line 84, column 55) for  -x
      % expected type  posreal
  atan_lb_TCC2: OBLIGATION
    FORALL (x: real): NOT x = 0 AND NOT x > 0 IMPLIES -x >= 0 AND -x > 0;


body:
  trig_basic : THEORY
  %-----------------------------------------------------------------------------
  %     trig_basic:
  %     -----------
  %         - definition of pi with crude upper and lower bounds
  %         - definition of sin, cos, and tan
  %         - pythagorean properties: sq(sin(a)) + sq(cos(a)) = 1 
  %         - sum and difference of two angles
  %         - double angle formulas
  %         - negative properties, e.g. sin(-a)
  %         - periodicity, e.g. sin(a) = sin(a + 2 * j * pi) 
  %         - co-function identities, e.g. sin(pi/2 - a) = cos(a)
  %         - location of zeros of trig functions
  %
  %   Version 1.1 27/10/03 Foundational Version David Lester
  %
  %   CHANGES 
  %         - Oct 21 2004 (C. Munoz) Moved pi_lb, pi_ub, pi_bound to atan_approx
  %
  %-----------------------------------------------------------------------------
  BEGIN

    IMPORTING reals@sqrt, sincos_def, atan_approx

    a,b,c,d           : VAR real
    nnc               : VAR nonneg_real 
    j                 : VAR integer
    
  % This is now in atan_approx.pvs
  %
  %  pi_lb  : real = 31415926/10000000
  % 
  %  pi_ub  : real = 31415927/10000000
  %
  %  pi_bound : JUDGEMENT pi HAS_TYPE {r:posreal | pi_lb < r AND r < pi_ub}

  % -------------------- definition of sin and cos --------------------
  %
  % This is now in sincos_def.pvs
  %
  %  trig_range  : TYPE = {a | -1 <= a AND a <= 1}
  %
  %  sin(x:real) : real = sin_phase(x-2*pi*floor(x/(2*pi)))
  %  cos(x:real) : real = cos_phase(x-2*pi*floor(x/(2*pi)))
  %
  %  sin_range_ax: LEMMA -1 <= sin(a) AND sin(a) <= 1
  %  cos_range_ax: LEMMA -1 <= cos(a) AND cos(a) <= 1
  %
  %  sin_range   : JUDGEMENT sin(a) HAS_TYPE trig_range
  %  cos_range   : JUDGEMENT cos(a) HAS_TYPE trig_range
  %
  %  Tan?(a)        : bool = cos(a) /= 0
  % 
  %  tan(a:(Tan?))  : real = sin(a)/cos(a)

  % -------------------- Pythagorean Property --------------------
   
    sin2_cos2    : LEMMA sq(sin(a)) + sq(cos(a)) = 1

    cos2         : LEMMA sq(cos(a)) = 1 - sq(sin(a)) 

    sin2         : LEMMA sq(sin(a)) = 1 - sq(cos(a)) 

  % --------------------- Basic Values ----------------------------

    cos_0         : LEMMA cos(0) = 1 

    sin_0         : LEMMA sin(0) = 0

    sin_pi2       : LEMMA sin(pi/2) = 1

    cos_pi2       : LEMMA cos(pi/2) = 0

    tan_0         : LEMMA tan(0) = 0

  % --------------------- Negative Properties ----------------------

    sin_neg : LEMMA sin(-a) = -sin(a) 
    cos_neg : LEMMA cos(-a) = cos(a) 
    tan_neg : LEMMA FORALL(a:(Tan?)): tan(-a) = -tan(a)


  % -------------------- Co-Function Identities -----------------------

    cos_sin    : LEMMA cos(a) = sin(a+pi/2)
    sin_cos    : LEMMA sin(a) = -cos(a+pi/2)
    sin_shift  : LEMMA sin(pi/2 - a) = cos(a)
    cos_shift  : LEMMA cos(pi/2 - a) = sin(a)

  % --------------------- Arguments involving pi ---------------------

    neg_cos     : LEMMA -cos(a) = cos(a+pi)
    neg_sin     : LEMMA -sin(a) = sin(a+pi)

    sin_pi      : LEMMA sin(pi) = 0
    cos_pi      : LEMMA cos(pi) = -1
    tan_pi      : LEMMA tan(pi) = 0
    sin_3pi2    : LEMMA sin(3*pi/2) = -1
    cos_3pi2    : LEMMA cos(3*pi/2) = 0
    sin_2pi     : LEMMA sin(2*pi) = 0
    cos_2pi     : LEMMA cos(2*pi) = 1
    tan_2pi     : LEMMA tan(2*pi) = 0

  % ----------------- Sum and Difference of Two Angles ----------------

    sin_plus  : LEMMA sin(a + b) = sin(a)*cos(b) + cos(a)*sin(b)   
    sin_minus : LEMMA sin(a - b) = sin(a)*cos(b) - sin(b)*cos(a)

    cos_plus  : LEMMA cos(a + b) = cos(a)*cos(b) - sin(a)*sin(b)
    cos_minus : LEMMA cos(a - b) = cos(a)*cos(b) + sin(a)*sin(b)

    tan_plus  : LEMMA Tan?(a) AND Tan?(b) AND Tan?(a+b) AND
                      tan(a) * tan(b) /= 1 IMPLIES                 
                        tan(a + b) = (tan(a) + tan(b))/(1 - tan(a)*tan(b)) 

    tan_minus : LEMMA Tan?(a) AND Tan?(b) AND Tan?(a-b) AND
                      tan(a) * tan(b) /= -1 IMPLIES                 
                        tan(a - b) = (tan(a) - tan(b))/(1 + tan(a)*tan(b))

    arc_sin_cos  : LEMMA sq(a)+sq(b)=sq(c) IMPLIES
                              EXISTS d: a = c*cos(d) AND b = c*sin(d)

    pythagorean  : LEMMA sq(a)+sq(b)=sq(nnc) IMPLIES
                              EXISTS(alpha:real): nnc=a*cos(alpha)+b*sin(alpha)

  % -------------------- Double Angle Formulas -------------------- 

     sin_2a     : LEMMA sin(2*a) = 2 * sin(a) * cos(a)
     cos_2a     : LEMMA cos(2*a) = cos(a)*cos(a) - sin(a)*sin(a)
     cos_2a_cos : LEMMA cos(2*a) = 2 * cos(a)*cos(a) - 1
     cos_2a_sin : LEMMA cos(2*a) = 1 - 2 * sin(a)*sin(a)
     tan_2a     : LEMMA Tan?(a) AND Tan?(2*a) AND 
                        tan(a) * tan(a) /= 1 IMPLIES 
                          tan(2*a) = 2 * tan(a)/(1 - tan(a) * tan(a))
   
  % ------------------------- Periodicity -----------------------------

  %  IMPORTING reals@prelude_aux_reals

    n: VAR nat
    k: VAR integer

    sin_period  : LEMMA sin(a) = sin(a + 2 * j * pi) 
    cos_period  : LEMMA cos(a) = cos(a + 2 * j * pi) 
    tan_period  : LEMMA Tan?(a) IMPLIES tan(a) = tan(a + j * pi) 

    sin_k_pi    : LEMMA sin(k*pi) = 0
    cos_2k_pi   : LEMMA cos(2*k*pi) = 1
    cos_k_pi    : LEMMA cos(k*pi) = (-1)^(k)
    sin_k_pi2   : LEMMA sin(k*pi + pi/2) = (-1)^k 
    tan_k_pi    : LEMMA tan(k*pi) = 0

  % -------------------- Characterization of zeroes -------------------


    sin_eq_0_2pi : COROLLARY 0 <= a AND a <= 2*pi IMPLIES
                      (sin(a)=0 IFF a=0 OR a=pi OR a=2*pi)

    cos_eq_0_2pi : COROLLARY 0 <= a AND a <= 2*pi IMPLIES
                      (cos(a)=0 IFF a=pi/2 OR a=3*pi/2)

    sin_eq_0     : LEMMA sin(a) = 0 IFF EXISTS (i: int): a = i * pi

    cos_eq_0     : LEMMA cos(a) = 0 IFF EXISTS (i: int): a = i * pi + pi/2


  % ---------------------- Maximum Points -----------------------------
   
    sin_eq_1     : LEMMA sin(a) = 1 IFF EXISTS (i: int): a = 2 * i * pi + pi/2
    cos_eq_1     : LEMMA cos(a) = 1 IFF EXISTS (i: int): a = 2 * i * pi 

  END trig_basic

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

  % Subtype TCC generated (at line 74, column 28) for  0
      % expected type  (Tan?)
  tan_0_TCC1: OBLIGATION Tan?(0);

  % Subtype TCC generated (at line 80, column 40) for  -a
      % expected type  (Tan?)
  tan_neg_TCC1: OBLIGATION FORALL (a: (Tan?)): Tan?(-a);

  % Subtype TCC generated (at line 97, column 26) for  pi
      % expected type  (Tan?)
  tan_pi_TCC1: OBLIGATION Tan?(pi);

  % Subtype TCC generated (at line 102, column 26) for  2 * pi
      % expected type  (Tan?)
  tan_2pi_TCC1: OBLIGATION Tan?(2 * pi);

  % Subtype TCC generated (at line 114, column 54) for  (1 - tan(a) * tan(b))
      % expected type  nznum
  tan_plus_TCC1: OBLIGATION
    FORALL (a, b: real):
      tan(a) * tan(b) /= 1 AND Tan?(a + b) AND Tan?(b) AND Tan?(a) IMPLIES
       (1 - tan(a) * tan(b)) /= 0;

  % Subtype TCC generated (at line 118, column 54) for  (1 + tan(a) * tan(b))
      % expected type  nznum
  tan_minus_TCC1: OBLIGATION
    FORALL (a, b: real):
      tan(a) * tan(b) /= -1 AND Tan?(a - b) AND Tan?(b) AND Tan?(a) IMPLIES
       (1 + tan(a) * tan(b)) /= 0;

  % Subtype TCC generated (at line 134, column 47) for  (1 - tan(a) * tan(a))
      % expected type  nznum
  tan_2a_TCC1: OBLIGATION
    FORALL (a: real):
      tan(a) * tan(a) /= 1 AND Tan?(2 * a) AND Tan?(a) IMPLIES
       (1 - tan(a) * tan(a)) /= 0;

  % Subtype TCC generated (at line 145, column 51) for  a + j * pi
      % expected type  (Tan?)
  tan_period_TCC1: OBLIGATION
    FORALL (a: real, j: integer): Tan?(a) IMPLIES Tan?(a + j * pi);

  % Subtype TCC generated (at line 151, column 26) for  k * pi
      % expected type  (Tan?)
  tan_k_pi_TCC1: OBLIGATION FORALL (k: integer): Tan?(k * pi);


body:
  sincos: THEORY

    BEGIN

    IMPORTING reals@quadratic
    IMPORTING trig_basic, analysis@deriv_domain

    AUTO_REWRITE- abs_0
    AUTO_REWRITE- abs_nat

    IMPORTING analysis@deriv_domains

    x,x0:  VAR real
    e,px:  VAR posreal
    n:     VAR nat

    noa_nnreal_lt_pi2     : LEMMA not_one_element?[{x: nnreal | x < pi / 2}]
    noa_real_lt_pi2       : LEMMA not_one_element?[real_abs_lt_pi2]
    noa_posreal_lt_pi     : LEMMA not_one_element?[posreal_lt_pi]
    noa_nnreal_pi4_to_pi  : LEMMA not_one_element?[{x: nnreal | pi / 4 <= x & x < pi}]
    noa_posreal_pi2_to_pi : LEMMA not_one_element?[{x: posreal | pi / 2 <= x & x < pi}]
    noa_nnreal_lt_pi4     : LEMMA not_one_element?[{x: nnreal | x < pi / 4}] 
    noa_mpi4_to_pi4       : LEMMA not_one_element?[{x: real | -pi / 4 < x & x < pi / 4}]

    conn_nnreal_lt_p2     : LEMMA connected?[{x: nnreal | x < pi / 2}]
    conn_nnreal_pi4_to_pi : LEMMA connected?[{x: nnreal | pi / 4 <= x & x < pi}]
    conn_posreal_pi2_to_pi: LEMMA connected?[{x: posreal | pi / 2 <= x & x < pi}]
    conn_nnreal_lt_pi4    : LEMMA connected?[{x: nnreal | x < pi / 4}]

    deriv_domain_nnreal_lt_pi2    : LEMMA deriv_domain?[{x: nnreal | x < pi / 2}]
    deriv_domain_real_abs_lt_pi2  : LEMMA deriv_domain?[real_abs_lt_pi2]
    deriv_domain_posreal_pi2_to_pi: LEMMA deriv_domain?[{x: posreal | pi / 2 <= x & x < pi}]
    deriv_domain_posreal_lt_pi    : LEMMA deriv_domain?[posreal_lt_pi]
    deriv_domain_nnreal_pi4_to_pi : LEMMA deriv_domain?[{x: nnreal | pi / 4 <= x & x < pi}]
    deriv_domain_nnreal_lt_pi4    : LEMMA deriv_domain?[{x: nnreal | x < pi / 4}]
    deriv_domain_mpi4_to_pi4      : LEMMA deriv_domain?[{x: real | -pi / 4 < x & x < pi / 4}]

    AUTO_REWRITE+ noa_nnreal_lt_pi2
    AUTO_REWRITE+ noa_real_lt_pi2  
    AUTO_REWRITE+ noa_posreal_lt_pi    
    AUTO_REWRITE+ noa_nnreal_pi4_to_pi 
    AUTO_REWRITE+ noa_posreal_pi2_to_pi 
    AUTO_REWRITE+ noa_nnreal_lt_pi4
    AUTO_REWRITE+ noa_mpi4_to_pi4   

    AUTO_REWRITE+ conn_nnreal_lt_p2
    AUTO_REWRITE+ conn_nnreal_pi4_to_pi
    AUTO_REWRITE+ conn_posreal_pi2_to_pi
    AUTO_REWRITE+ conn_nnreal_lt_pi4

    AUTO_REWRITE+ deriv_domain_nnreal_lt_pi2
    AUTO_REWRITE+ deriv_domain_real_abs_lt_pi2
    AUTO_REWRITE+ deriv_domain_posreal_pi2_to_pi
    AUTO_REWRITE+ deriv_domain_posreal_lt_pi  
    AUTO_REWRITE+ deriv_domain_nnreal_pi4_to_pi
    AUTO_REWRITE+ deriv_domain_nnreal_lt_pi4 
    AUTO_REWRITE+ deriv_domain_mpi4_to_pi4




    cos_ub: LEMMA cos(x)        <= 1
    sin_ub: LEMMA sin(px)       <  px
    cos_lb: LEMMA 1-px*px/2     <  cos(px)
    sin_lb: LEMMA px-px*px*px/6 <  sin(px)

    cos_pos_bnds:    LEMMA 1-px*px/2     < cos(px) AND cos(px) <= 1
    sin_pos_bnds:    LEMMA px-px*px*px/6 < sin(px) AND sin(px) <  px

    sin_convergence  : LEMMA convergence(NQ(sin,x),0,cos(x))
    sin_derivable    : LEMMA derivable?(sin,x)
    sin_derivable_fun: LEMMA derivable?(sin)
    deriv_sin_fun    : LEMMA deriv(sin) = cos

    cos_convergence  : LEMMA convergence(NQ(cos,x),0,-sin(x))
    cos_derivable    : LEMMA derivable?(cos,x)
    cos_derivable_fun: LEMMA derivable?(cos)
    deriv_cos_fun    : LEMMA deriv(cos) = -sin

    sin_continuous   : LEMMA continuous?(sin,x0)
    cos_continuous   : LEMMA continuous?(cos,x0)
    sin_cont_fun     : LEMMA continuous?(sin)
    cos_cont_fun     : LEMMA continuous?(cos)

    nderiv_sin_fun:  LEMMA derivable_n_times?(sin,n) AND
                           nderiv(n,sin) = LAMBDA (x:real): sin((n*pi/2)+x)
    nderiv_cos_fun:  LEMMA derivable_n_times?(cos,n) AND
                           nderiv(n,cos) = LAMBDA (x:real): cos((n*pi/2)+x)

    sin_series_term(x:real):[nat->real]
      = (LAMBDA (n:nat): (-1)^n*x^(2*n+1)/factorial(2*n+1))
    sin_series_n(x:real,n:nat):real
      = sigma(0,n,LAMBDA (i:nat): IF i>n THEN 0 ELSE sin_series_term(x)(i) ENDIF)
    cos_series_term(x:real):[nat->real]
      = (LAMBDA (n:nat): IF n=0 THEN 1 ELSE (-1)^n*x^(2*n)/factorial(2*n) ENDIF)
    cos_series_n(x:real,n:nat):real
      = sigma(0,n,LAMBDA (i:nat): IF i>n THEN 0 ELSE cos_series_term(x)(i) ENDIF)

    sin_taylors: LEMMA (EXISTS (c: between(0,x)): 
      sin(x) = sin_series_n(x,n)+nderiv(2*n+3,sin)(c)*x^(2*n+3)/factorial(2*n+3))

    cos_taylors: LEMMA (EXISTS (c: between(0,x)): 
      cos(x) = cos_series_n(x,n)+nderiv(2*n+2,cos)(c)*x^(2*n+2)/factorial(2*n+2))

    sin_series: LEMMA abs(sin(x)-sin_series_n(x,n))
                        <= abs(x^(2*n+3))/factorial(2*n+3)
    cos_series: LEMMA abs(cos(x)-cos_series_n(x,n))
                        <= abs(x^(2*n+2))/factorial(2*n+2)


    END sincos

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

  % Assuming TCC generated (at line 30, column 12) for
      % analysis@derivatives_def[real]
      % generated from assumption derivatives_def.deriv_domain
  sin_convergence_TCC1: OBLIGATION deriv_domain?[real];

  % Assuming TCC generated (at line 30, column 12) for
      % analysis@derivatives_def[real]
      % generated from assumption derivatives_def.not_one_element
  sin_convergence_TCC2: OBLIGATION not_one_element?[real];

  % Subtype TCC generated (at line 73, column 33) for  sin
      % expected type  deriv_fun[real]
  deriv_sin_fun_TCC1: OBLIGATION derivable?[real](sin);

  % Subtype TCC generated (at line 78, column 33) for  cos
      % expected type  deriv_fun[real]
  deriv_cos_fun_TCC1: OBLIGATION derivable?[real](cos);

  % Subtype TCC generated (at line 91, column 33) for  (2 * n + 1)
      % expected type  {i: int | x /= 0 OR i >= 0}
  sin_series_term_TCC1: OBLIGATION
    FORALL (x: real, n: nat): x /= 0 OR (2 * n + 1) >= 0;

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

  % Subtype TCC generated (at line 95, column 52) for  (2 * n)
      % expected type  {i: int | x /= 0 OR i >= 0}
  cos_series_term_TCC1: OBLIGATION
    FORALL (x: real, n: nat): NOT n = 0 IMPLIES x /= 0 OR (2 * n) >= 0;

  % Subtype TCC generated (at line 100, column 44) for  sin
      % expected type  nderiv_fun[real](3 + 2 * n)
  sin_taylors_TCC1: OBLIGATION
    FORALL (n: nat, x: real, c: between[real](0, x)):
      derivable_n_times?[real](sin, 3 + 2 * n);

  % Subtype TCC generated (at line 100, column 55) for  (2 * n + 3)
      % expected type  {i: int | x /= 0 OR i >= 0}
  sin_taylors_TCC2: OBLIGATION
    FORALL (n: nat, x: real, c: between[real](0, x)):
      x /= 0 OR (2 * n + 3) >= 0;

  % Subtype TCC generated (at line 103, column 44) for  cos
      % expected type  nderiv_fun[real](2 + 2 * n)
  cos_taylors_TCC1: OBLIGATION
    FORALL (n: nat, x: real, c: between[real](0, x)):
      derivable_n_times?[real](cos, 2 + 2 * n);

  % Subtype TCC generated (at line 103, column 55) for  (2 * n + 2)
      % expected type  {i: int | x /= 0 OR i >= 0}
  cos_taylors_TCC2: OBLIGATION
    FORALL (n: nat, x: real, c: between[real](0, x)):
      x /= 0 OR (2 * n + 2) >= 0;

  % Subtype TCC generated (at line 106, column 32) for  (2 * n + 3)
      % expected type  {i: int | x /= 0 OR i >= 0}
  sin_series_TCC1: OBLIGATION
    FORALL (n: nat, x: real): x /= 0 OR (2 * n + 3) >= 0;

  % Subtype TCC generated (at line 108, column 32) for  (2 * n + 2)
      % expected type  {i: int | x /= 0 OR i >= 0}
  cos_series_TCC1: OBLIGATION
    FORALL (n: nat, x: real): x /= 0 OR (2 * n + 2) >= 0;


body:
  deriv_sincos[ T : TYPE FROM real ] : THEORY
  %------------------------------------------------------------------------------
  %  Convenient forms of sin cos derivatives.
  %
  %      Rick Butler 4/1/2010
  %------------------------------------------------------------------------------
  BEGIN

     ASSUMING
       IMPORTING analysis@deriv_domain

       connected_domain: ASSUMPTION connected?[T]

       not_one_element : ASSUMPTION not_one_element?[T]

     ENDASSUMING

     deriv_domain: LEMMA deriv_domain?[T]


     IMPORTING sincos, analysis@chain_rule, analysis@composition_continuous

     a,b,t: VAR T
     k,alpha: VAR real

     sin_continuous: LEMMA
         continuous?[T](LAMBDA (x: T): k * sin(alpha * x))

     cos_continuous: LEMMA
         continuous?[T](LAMBDA (x: T): k * cos(alpha * x))

     sin_derivable: LEMMA
         derivable?[T](LAMBDA (x: T): k * sin(alpha * x))

     cos_derivable: LEMMA
         derivable?[T](LAMBDA (x: T): k * cos(alpha * x))

     IMPORTING analysis@derivatives_lam[T]

     deriv_sin: LEMMA alpha /= 0 IMPLIES
         deriv[T](LAMBDA (x:T): k*sin(alpha*x)) =  
              (LAMBDA (t: T): k*alpha*cos(alpha*t))
    
     deriv_cos: LEMMA alpha /= 0 IMPLIES
         deriv[T](LAMBDA (x:T): k*cos(alpha*x)) = 
              (LAMBDA (t: T): -k*alpha*sin(alpha*t))

  END deriv_sincos

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

  % Assuming TCC generated (at line 24, column 4) for  analysis@derivatives[T]
      % generated from assumption derivatives.deriv_domain
  sin_derivable_TCC1: OBLIGATION deriv_domain?[T];

  % Assuming TCC generated (at line 26, column 4) for  analysis@derivatives[T]
      % generated from assumption derivatives.not_one_element
  sin_derivable_TCC2: OBLIGATION not_one_element?[T];

  % Subtype TCC generated (at line 41, column 16) for
      % LAMBDA (x: T): k * sin(alpha * x)
      % expected type  deriv_fun[T]
  deriv_sin_TCC1: OBLIGATION
    FORALL (alpha, k: real):
      alpha /= 0 IMPLIES derivable?[T](LAMBDA (x: T): k * sin(alpha * x));

  % Subtype TCC generated (at line 45, column 16) for
      % LAMBDA (x: T): k * cos(alpha * x)
      % expected type  deriv_fun[T]
  deriv_cos_TCC1: OBLIGATION
    FORALL (alpha, k: real):
      alpha /= 0 IMPLIES derivable?[T](LAMBDA (x: T): k * cos(alpha * x));


body:
  integral_indef_sincos[T: TYPE+ FROM real]: THEORY
  %------------------------------------------------------------------------------
  %
  %   Integration results for the kinematics library
  %
  %    Provides: the connection between the calculation of the position
  %              during a turn and the integration of speed values
  %
  %    Authors: Radu Siminiceanu    National Institute of Aerospace
  %             Rick Butler         NASA Langley
  %
  %------------------------------------------------------------------------------
  BEGIN

     ASSUMING
        IMPORTING analysis@deriv_domain_def

        connected_domain : ASSUMPTION connected?[T]

        not_one_element : ASSUMPTION not_one_element?[T]

        T_pred0         : ASSUMPTION T_pred(0)

     ENDASSUMING

     IMPORTING sincos,
     	     deriv_sincos, 
  	     analysis@fundamental_theorem,
  	     analysis@chain_rule,
  	     analysis@composition_continuous,
  	     analysis@continuous_lambda,
  	     analysis@derivatives_lam,
  	     analysis@indefinite_integral
  	     

     alpha, theta, k, a, b, v: VAR real
     w : VAR nzreal
     t0, t1, t2: VAR T

     derivable_sin_lin: LEMMA a /=0 IMPLIES
     	derivable?(LAMBDA (t: T): k / a * sin(a*t + b))

     derivable_cos_lin: LEMMA a /=0 IMPLIES
     	derivable?(LAMBDA (t: T): k / a * cos(a*t + b))

     deriv_sin_lin: LEMMA a /= 0 IMPLIES
          deriv[T](LAMBDA (t: T): k*sin(b+a*t)) =  
               (LAMBDA (u: T): k*a*cos(b+a*u))
    
     deriv_cos_lin: LEMMA a /= 0 IMPLIES
          deriv[T](LAMBDA (t: T): -k*cos(b+a*t)) = 
               (LAMBDA (u: T): k*a*sin(b+a*u))

     cos_lin_integrable: LEMMA alpha /= 0 
                      IMPLIES integrable?[T](LAMBDA (t: T): k * cos(theta + alpha * t))

     sin_lin_integrable: LEMMA alpha /=0 
     		    IMPLIES integrable?[T](LAMBDA (t: T): k * sin(theta + alpha * t))

     integral_sin: LEMMA (EXISTS (c:real):
         integral[T](LAMBDA (t: T): v*sin(theta + w*t)) = (LAMBDA (t: T): -(v/w)*cos(theta + w*t)) + const_fun(c))

     integral_cos: LEMMA (EXISTS (c:real):
         integral[T](LAMBDA (t: T): v*cos(theta + w*t)) = (LAMBDA (t: T): (v/w)*sin(theta + w*t)) + const_fun(c))


     Integral_sin: LEMMA
     	Integral(t1, t2, (LAMBDA (t: T): v*sin(theta + w*t))) = -(v/w)*(cos(theta + w*t2) - cos(theta + w*t1))

     Integral_cos: LEMMA
     	Integral(t1, t2, (LAMBDA (t: T): v*cos(theta + w*t))) = (v/w)*(sin(theta + w*t2) - sin(theta + w*t1))
    
  END integral_indef_sincos

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

  % Assuming TCC generated (at line 13, column 12) for
      % analysis@derivatives[T]
      % generated from assumption derivatives.deriv_domain
  derivable_sin_lin_TCC1: OBLIGATION
    FORALL (a: real): a /= 0 IMPLIES deriv_domain?[T];

  % Assuming TCC generated (at line 13, column 12) for
      % analysis@derivatives[T]
      % generated from assumption derivatives.not_one_element
  derivable_sin_lin_TCC2: OBLIGATION
    FORALL (a: real): a /= 0 IMPLIES not_one_element?[T];

  % Subtype TCC generated (at line 47, column 17) for
      % LAMBDA (t: T): k * sin(b + a * t)
      % expected type  deriv_fun[T]
  deriv_sin_lin_TCC1: OBLIGATION
    FORALL (a, b, k: real):
      a /= 0 IMPLIES derivable?[T](LAMBDA (t: T): k * sin(b + a * t));

  % Subtype TCC generated (at line 51, column 17) for
      % LAMBDA (t: T): -k * cos(b + a * t)
      % expected type  deriv_fun[T]
  deriv_cos_lin_TCC1: OBLIGATION
    FORALL (a, b, k: real):
      a /= 0 IMPLIES derivable?[T](LAMBDA (t: T): -k * cos(b + a * t));

  % Assuming TCC generated (at line 17, column 6) for
      % analysis@indefinite_integral[T]
      % generated from assumption indefinite_integral.connected_domain
  cos_lin_integrable_TCC1: OBLIGATION
    FORALL (alpha: real): alpha /= 0 IMPLIES connected?[T];

  % Subtype TCC generated (at line 61, column 19) for
      % LAMBDA (t: T): v * sin(theta + w * t)
      % expected type  f: integrable_fun[T]
  integral_sin_TCC1: OBLIGATION
    FORALL (theta, v: real, w: nzreal):
      integrable?[T](LAMBDA (t: T): v * sin(theta + w * t));

  % Assuming TCC generated (at line 17, column 6) for
      % analysis@indefinite_integral[T]
      % generated from assumption indefinite_integral.connected_domain
  integral_sin_TCC2: OBLIGATION connected?[T];

  % Assuming TCC generated (at line 20, column 6) for
      % analysis@indefinite_integral[T]
      % generated from assumption indefinite_integral.not_one_element
  integral_sin_TCC3: OBLIGATION not_one_element?[T];

  % Subtype TCC generated (at line 64, column 19) for
      % LAMBDA (t: T): v * cos(theta + w * t)
      % expected type  f: integrable_fun[T]
  integral_cos_TCC1: OBLIGATION
    FORALL (theta, v: real, w: nzreal):
      integrable?[T](LAMBDA (t: T): v * cos(theta + w * t));

  % Subtype TCC generated (at line 68, column 22) for
      % (LAMBDA (t: T): v * sin(theta + w * t))
      % expected type  Integrable_funs[T](t1, t2)
  Integral_sin_TCC1: OBLIGATION
    FORALL (t1, t2: T, theta, v: real, w: nzreal):
      Integrable?[T](t1, t2, LAMBDA (t: T): v * sin(theta + w * t));

  % Subtype TCC generated (at line 71, column 22) for
      % (LAMBDA (t: T): v * cos(theta + w * t))
      % expected type  Integrable_funs[T](t1, t2)
  Integral_cos_TCC1: OBLIGATION
    FORALL (t1, t2: T, theta, v: real, w: nzreal):
      Integrable?[T](t1, t2, LAMBDA (t: T): v * cos(theta + w * t));


body:
  integral_sincos[T : TYPE+ FROM real ] : THEORY
  %------------------------------------------------------------------------------
  %  Convenient forms of sin cos integrals.
  %
  %      Rick Butler 4/1/2010
  %------------------------------------------------------------------------------
  BEGIN
     ASSUMING
       IMPORTING analysis@deriv_domain

       connected_domain: ASSUMPTION connected?[T]

       not_one_element : ASSUMPTION not_one_element?[T]

     ENDASSUMING

     AUTO_REWRITE+ connected_domain
     AUTO_REWRITE+ not_one_element


     IMPORTING analysis@deriv_domain, deriv_sincos[T], analysis@fundamental_theorem[T]

     k,alpha: VAR real
     a,b: VAR T
    
     sin_Integrable: LEMMA
           Integrable?[T](a, b, LAMBDA (x: T): k * sin(alpha * x))

     cos_Integrable: LEMMA
           Integrable?[T](a, b, LAMBDA (x: T): k * cos(alpha * x))

     Integral_sin: LEMMA alpha /= 0 IMPLIES
           Integral[T](a,b, (LAMBDA (x:T): k*sin(alpha*x))) = -k/alpha*(cos(alpha*b) - cos(alpha*a)) 
   
    
     Integral_cos: LEMMA alpha /= 0 IMPLIES
           Integral[T](a,b, (LAMBDA (x:T): k*cos(alpha*x))) = k/alpha*(sin(alpha*b) - sin(alpha*a))


  END integral_sincos

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

  % Assuming TCC generated (at line 21, column 36) for  deriv_sincos[T]
      % generated from assumption deriv_sincos.connected_domain
  IMP_deriv_sincos_TCC1: OBLIGATION connected?[T];

  % Assuming TCC generated (at line 21, column 36) for  deriv_sincos[T]
      % generated from assumption deriv_sincos.not_one_element
  IMP_deriv_sincos_TCC2: OBLIGATION not_one_element?[T];

  % Subtype TCC generated (at line 33, column 27) for
      % (LAMBDA (x: T): k * sin(alpha * x))
      % expected type  Integrable_funs[T](a, b)
  Integral_sin_TCC1: OBLIGATION
    FORALL (a: T, alpha: real, b: T, k: real):
      alpha /= 0 IMPLIES
       Integrable?[T](a, b, LAMBDA (x: T): k * sin(alpha * x));

  % Subtype TCC generated (at line 37, column 27) for
      % (LAMBDA (x: T): k * cos(alpha * x))
      % expected type  Integrable_funs[T](a, b)
  Integral_cos_TCC1: OBLIGATION
    FORALL (a: T, alpha: real, b: T, k: real):
      alpha /= 0 IMPLIES
       Integrable?[T](a, b, LAMBDA (x: T): k * cos(alpha * x));


body:
  trig_ineq: THEORY

    BEGIN

    IMPORTING trig_basic

    a,b  : VAR real
    n    : VAR int

  % ------------------- Sign of sin, cos, and tan  -----------------------

    cos_gt_0    : LEMMA -pi/2 < a  AND a <  pi/2   IMPLIES cos(a) >  0
    sin_gt_0    : LEMMA 0 < a      AND a <  pi     IMPLIES sin(a) >  0
    sin_ge_0    : LEMMA 0 <= a     AND a <= pi     IMPLIES sin(a) >= 0
    cos_ge_0    : LEMMA -pi/2 <= a AND a <= pi/2   IMPLIES cos(a) >= 0
    sin_lt_0    : LEMMA pi < a     AND a <  2*pi   IMPLIES sin(a) <  0
    cos_lt_0    : LEMMA pi/2 < a   AND a <  3*pi/2 IMPLIES cos(a) <  0
    sin_le_0    : LEMMA pi <= a    AND a <= 2*pi   IMPLIES sin(a) <= 0
    cos_le_0    : LEMMA pi/2 <= a  AND a <= 3*pi/2 IMPLIES cos(a) <= 0
    tan_gt_0    : LEMMA 0 < a      AND a <  pi/2   IMPLIES tan(a) >  0
    tan_lt_0    : LEMMA -pi/2 < a  AND a <  0      IMPLIES tan(a) <  0

    tan_pi2_def   : LEMMA  -pi/2 < a AND a < pi/2   IMPLIES Tan?(a) 
    tan_npi_def   : LEMMA Tan?(n*pi)
    cos_ge_0_3pi2 : LEMMA 3*pi/2 <= a AND a <= 2*pi IMPLIES cos(a) >= 0 

  % -------------------- Strict Inequalities --------------------

    sin_increasing_imp : LEMMA
                       a <= pi/2 AND a >= -pi/2 AND
                       b <= pi/2 AND b >= -pi/2 AND
                       a > b 
                       => 
                       sin(a) > sin(b)

    sin_increasing : LEMMA
                       a <= pi/2 AND a >= -pi/2 AND
                       b <= pi/2 AND b >= -pi/2 IMPLIES
                       (sin(a) > sin(b)
                       <=> 
                       a > b)

    sin_decreasing : LEMMA
                       a <= 3*pi/2 AND a >= pi/2 AND
                       b <= 3*pi/2 AND b >= pi/2 IMPLIES
                       (sin(b) > sin(a)
                       <=> 
                       a > b)


    cos_increasing : LEMMA
                       a >= pi AND a <= 2*pi AND
                       b >= pi AND b <= 2*pi IMPLIES
                       (cos(a) > cos(b)
                       <=> 
                       a > b)

    cos_decreasing : LEMMA
                       a <= pi AND a >= 0 AND
                       b <= pi AND b >= 0 IMPLIES
                       (cos(b) > cos(a)
                       <=> 
                       a > b)

    tan_increasing_imp: LEMMA
                        -pi/2 < a AND a < pi/2 AND
                        -pi/2 < b AND b < pi/2 AND
                         a > b IMPLIES
                         tan(a) > tan(b)

    tan_increasing : LEMMA
                       -pi/2 < a AND a < pi/2 AND
                       -pi/2 < b AND b < pi/2 IMPLIES
                           (tan(a) > tan(b) <=> a > b)
                        
  % -------------------- Non-Strict Inequalities --------------------

    sin_incr  : LEMMA  a <= pi/2 AND a >= -pi/2 AND
                       b <= pi/2 AND b >= -pi/2 IMPLIES
                       (sin(a) >= sin(b) <=> a >= b)

    sin_decr  : LEMMA  a <= 3*pi/2 AND a >= pi/2 AND
                       b <= 3*pi/2 AND b >= pi/2 IMPLIES
                       (sin(b) >= sin(a) <=> a >= b)

    cos_incr  : LEMMA  a >= pi AND a <= 2*pi AND
                       b >= pi AND b <= 2*pi IMPLIES
                       (cos(a) >= cos(b) <=> a >= b)

    cos_decr  : LEMMA  a <= pi AND a >= 0 AND
                       b <= pi AND b >= 0 IMPLIES
                       (cos(b) >= cos(a) <=> a >= b)

    tan_incr  : LEMMA  -pi/2 < a AND a < pi/2 AND
                       -pi/2 < b AND b < pi/2 IMPLIES
                       (tan(a) >= tan(b) <=> a >= b)

  % -------------------- Some properties about sin --------------------

    sin_gt : LEMMA
      -pi/2 <= a AND a < 3*pi/2 AND
      -pi/2 <= b AND b <= pi/2 IMPLIES
     (sin(a) > sin(b) IFF b < a AND a < pi-b)

    sin_lt : LEMMA
      -pi/2 <= a AND a < 3*pi/2 AND
      -pi/2 <= b AND b <= pi/2 IMPLIES
     (sin(a) < sin(b) IFF b > a OR a > pi-b)

    sin_ge : LEMMA
      -pi/2 <= a AND a < 3*pi/2 AND
      -pi/2 <= b AND b <= pi/2 IMPLIES
     (sin(a) >= sin(b) IFF b <= a AND a <= pi-b)

    END trig_ineq

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

  % Subtype TCC generated (at line 20, column 61) for  a
      % expected type  (Tan?)
  tan_gt_0_TCC1: OBLIGATION
    FORALL (a: real): a < pi / 2 AND 0 < a IMPLIES Tan?(a);

  % Subtype TCC generated (at line 21, column 61) for  a
      % expected type  (Tan?)
  tan_lt_0_TCC1: OBLIGATION
    FORALL (a: real): a < 0 AND -pi / 2 < a IMPLIES Tan?(a);

  % Subtype TCC generated (at line 69, column 27) for  a
      % expected type  (Tan?)
  tan_increasing_imp_TCC1: OBLIGATION
    FORALL (a, b: real):
           a > b AND b < pi / 2 AND -pi / 2 < b AND a < pi / 2
       AND -pi / 2 < a
       IMPLIES Tan?(a);

  % Subtype TCC generated (at line 69, column 36) for  b
      % expected type  (Tan?)
  tan_increasing_imp_TCC2: OBLIGATION
    FORALL (a, b: real):
           a > b AND b < pi / 2 AND -pi / 2 < b AND a < pi / 2
       AND -pi / 2 < a
       IMPLIES Tan?(b);

  % Subtype TCC generated (at line 74, column 30) for  a
      % expected type  (Tan?)
  tan_increasing_TCC1: OBLIGATION
    FORALL (a, b: real):
      b < pi / 2 AND -pi / 2 < b AND a < pi / 2 AND -pi / 2 < a IMPLIES
       Tan?(a);

  % Subtype TCC generated (at line 74, column 39) for  b
      % expected type  (Tan?)
  tan_increasing_TCC2: OBLIGATION
    FORALL (a, b: real):
      b < pi / 2 AND -pi / 2 < b AND a < pi / 2 AND -pi / 2 < a IMPLIES
       Tan?(b);


body:
  atan2 : THEORY
  %-----------------------------------------------------------------------------
  %      atan2
  %      ----
  %         - defines two-argument inverse tangent (arctangent): atan2
  %-----------------------------------------------------------------------------
  BEGIN

    IMPORTING trig_basic, atan, asin, acos

    x,y   : VAR real
    a     : VAR {z:nnreal| z < 2*pi}
    nz    : VAR negreal
    pz    : VAR posreal

    %% Arc tangent of y/x taking into in account quadrants and indefinitions
    %% Polar angle of x + yI. 
    atan2(x:real,y:{z:real|x=0 => z/=0}): real
      = IF    x > 0 THEN IF y >= 0 THEN atan(y/x) ELSE 2*pi+atan(y/x) ENDIF
        ELSIF x = 0 THEN IF y >  0 THEN pi/2      ELSE 3*pi/2         ENDIF
                    ELSE pi + atan(y/x)                                    ENDIF

    atan2_0_2pi : LEMMA
      (x /= 0 OR y /= 0) IMPLIES
        (((x>=0 AND y>=0) => (0 <= atan2(x,y) AND atan2(x,y) <= pi/2))  AND
         ((x< 0 AND y>=0) => (pi/2 < atan2(x,y) AND atan2(x,y) <= pi)) AND
         ((x< 0 AND y< 0) => (pi < atan2(x,y)  AND atan2(x,y) < 3*pi/2)) AND
         ((x>=0 AND y< 0) => (3*pi/2 <= atan2(x,y)  AND atan2(x,y) < 2*pi)))


    atan2_ge_0_lt_2pi : LEMMA
      (x /= 0 OR y /= 0) IMPLIES
      atan2(x,y) >= 0 and
      atan2(x,y) < 2*pi



    nnreal_lt_2pi: NONEMPTY_TYPE = {x:nnreal | x < 2*pi} 

    JUDGEMENT atan2(x:real,y:{z:real|x=0 => z/=0}) HAS_TYPE nnreal_lt_2pi


    atan2_cancel_pos : LEMMA
      (x /= 0 OR y /= 0) IMPLIES atan2(x*pz,y*pz) = atan2(x,y)

    atan2_cancel_neg : LEMMA
      (x /= 0 OR y /= 0) IMPLIES
         atan2(x*nz,y*nz) =
             IF y > 0 OR (y = 0 AND x > 0) THEN atan2(x,y) + pi
                                           ELSE atan2(x,y) - pi ENDIF

    atan2_swap_pos : LEMMA
      x*y > 0 IMPLIES
      atan2(x,y) = atan2(y,x) + atan((y ^ 2 - x ^ 2) / (2 * (x * y)))

    atan2_swap_neg : LEMMA
      x*y < 0 IMPLIES
      atan2(x,y) =  atan2(y,x) + atan((y ^ 2 - x ^ 2) / (2 * (x * y))) + sign(x)*pi

    atan2_swap_zero : LEMMA
      (x = 0 AND y /= 0 IMPLIES
        atan2(x,y) = atan2(y,x) + pi/2) AND
      (y = 0 AND x /= 0 IMPLIES      
        atan2(x,y) = atan2(y,x) - pi/2)

    atan2_cos_sin : LEMMA
      atan2(cos(a),sin(a)) = a

    sin_atan2 : LEMMA
      (x /= 0 OR y /= 0) IMPLIES 
        sin(atan2(x,y)) = 
          IF x=0 THEN 
            IF y > 0 THEN 1 ELSE -1 ENDIF
          ELSE 
            LET yx = y/x IN 
            LET r = yx/sqrt((sq(yx)+1)) IN
              IF x > 0 THEN r
              ELSE -r
              ENDIF
          ENDIF

    cos_atan2 : LEMMA
      (x /= 0 OR y /= 0) IMPLIES
        cos(atan2(x,y)) = 
          IF x = 0 THEN 0 
          ELSE
            LET yx = y/x IN
            IF  x > 0 THEN 1/sqrt((sq(yx)+1)) 
            ELSE -1/sqrt((sq(yx)+1)) 
            ENDIF
          ENDIF

  END atan2

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

  % Subtype TCC generated (at line 19, column 45) for  x
      % expected type  nznum
  atan2_TCC1: OBLIGATION
    FORALL (x: real, y: {z: real | x = 0 => z /= 0}):
      y >= 0 AND x > 0 IMPLIES x /= 0;

  % Subtype TCC generated (at line 19, column 65) for  x
      % expected type  nznum
  atan2_TCC2: OBLIGATION
    FORALL (x: real, y: {z: real | x = 0 => z /= 0}):
      NOT y >= 0 AND x > 0 IMPLIES x /= 0;

  % Subtype TCC generated (at line 21, column 35) for  x
      % expected type  nznum
  atan2_TCC3: OBLIGATION
    FORALL (x: real, y: {z: real | x = 0 => z /= 0}):
      NOT x = 0 AND NOT x > 0 IMPLIES x /= 0;

  % Subtype TCC generated (at line 25, column 41) for  y
      % expected type  {z: real | x = 0 => z /= 0}
  atan2_0_2pi_TCC1: OBLIGATION
    FORALL (x, y: real):
      (x /= 0 OR y /= 0) AND y >= 0 AND x >= 0 IMPLIES x = 0 => y /= 0;

  % Subtype TCC generated (at line 26, column 43) for  y
      % expected type  {z: real | x = 0 => z /= 0}
  atan2_0_2pi_TCC2: OBLIGATION
    FORALL (x, y: real):
      (x /= 0 OR y /= 0) AND
       ((x >= 0 AND y >= 0) => (0 <= atan2(x, y) AND atan2(x, y) <= pi / 2))
        AND y >= 0 AND x < 0
       IMPLIES x = 0 => y /= 0;

  % Subtype TCC generated (at line 27, column 41) for  y
      % expected type  {z: real | x = 0 => z /= 0}
  atan2_0_2pi_TCC3: OBLIGATION
    FORALL (x, y: real):
           (x /= 0 OR y /= 0)
       AND ((x >= 0 AND y >= 0) =>
             (0 <= atan2(x, y) AND atan2(x, y) <= pi / 2))
       AND ((x < 0 AND y >= 0) =>
             (pi / 2 < atan2(x, y) AND atan2(x, y) <= pi))
       AND y < 0 AND x < 0
       IMPLIES x = 0 => y /= 0;

  % Subtype TCC generated (at line 28, column 46) for  y
      % expected type  {z: real | x = 0 => z /= 0}
  atan2_0_2pi_TCC4: OBLIGATION
    FORALL (x, y: real):
           (x /= 0 OR y /= 0)
       AND ((x >= 0 AND y >= 0) =>
             (0 <= atan2(x, y) AND atan2(x, y) <= pi / 2))
       AND ((x < 0 AND y >= 0) =>
             (pi / 2 < atan2(x, y) AND atan2(x, y) <= pi))
       AND ((x < 0 AND y < 0) =>
             (pi < atan2(x, y) AND atan2(x, y) < 3 * pi / 2))
       AND y < 0 AND x >= 0
       IMPLIES x = 0 => y /= 0;

  % Subtype TCC generated (at line 33, column 12) for  y
      % expected type  {z: real | x = 0 => z /= 0}
  atan2_ge_0_lt_2pi_TCC1: OBLIGATION
    FORALL (x, y: real): (x /= 0 OR y /= 0) IMPLIES x = 0 => y /= 0;

  % Existence TCC generated (at line 38, column 2) for
      % nnreal_lt_2pi: TYPE+ = {x: nnreal | x < 2 * pi}
  nnreal_lt_2pi_TCC1: OBLIGATION EXISTS (x1: {x: nnreal | x < 2 * pi}): TRUE;

  % Judgement subtype TCC generated (at line 40, column 12) for  atan2(x, y)
      % expected type  nnreal_lt_2pi
  atan2_TCC4: OBLIGATION
    FORALL (x: real, y: {z: real | x = 0 => z /= 0}):
      atan2(x, y) >= 0 AND atan2(x, y) < 2 * pi;

  % Subtype TCC generated (at line 44, column 42) for  y * pz
      % expected type  {z: real | x * pz = 0 => z /= 0}
  atan2_cancel_pos_TCC1: OBLIGATION
    FORALL (pz: posreal, x, y: real):
      (x /= 0 OR y /= 0) IMPLIES x * pz = 0 => y * pz /= 0;

  % Subtype TCC generated (at line 48, column 18) for  y * nz
      % expected type  {z: real | x * nz = 0 => z /= 0}
  atan2_cancel_neg_TCC1: OBLIGATION
    FORALL (nz: negreal, x, y: real):
      (x /= 0 OR y /= 0) IMPLIES x * nz = 0 => y * nz /= 0;

  % Subtype TCC generated (at line 54, column 12) for  y
      % expected type  {z: real | x = 0 => z /= 0}
  atan2_swap_pos_TCC1: OBLIGATION
    FORALL (x, y: real): x * y > 0 IMPLIES x = 0 => y /= 0;

  % Subtype TCC generated (at line 54, column 40) for  2
      % expected type  {i: int | y /= 0 OR i >= 0}
  atan2_swap_pos_TCC2: OBLIGATION
    FORALL (x, y: real): x * y > 0 IMPLIES y /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 54, column 48) for  2
      % expected type  {i: int | x /= 0 OR i >= 0}
  atan2_swap_pos_TCC3: OBLIGATION
    FORALL (x, y: real): x * y > 0 IMPLIES x /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 54, column 54) for  (2 * (x * y))
      % expected type  nznum
  atan2_swap_pos_TCC4: OBLIGATION
    FORALL (x, y: real): x * y > 0 IMPLIES (2 * (x * y)) /= 0;

  % Subtype TCC generated (at line 58, column 12) for  y
      % expected type  {z: real | x = 0 => z /= 0}
  atan2_swap_neg_TCC1: OBLIGATION
    FORALL (x, y: real): x * y < 0 IMPLIES x = 0 => y /= 0;

  % Subtype TCC generated (at line 58, column 41) for  2
      % expected type  {i: int | y /= 0 OR i >= 0}
  atan2_swap_neg_TCC2: OBLIGATION
    FORALL (x, y: real): x * y < 0 IMPLIES y /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 58, column 49) for  2
      % expected type  {i: int | x /= 0 OR i >= 0}
  atan2_swap_neg_TCC3: OBLIGATION
    FORALL (x, y: real): x * y < 0 IMPLIES x /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 58, column 55) for  (2 * (x * y))
      % expected type  nznum
  atan2_swap_neg_TCC4: OBLIGATION
    FORALL (x, y: real): x * y < 0 IMPLIES (2 * (x * y)) /= 0;

  % Subtype TCC generated (at line 62, column 14) for  y
      % expected type  {z: real | x = 0 => z /= 0}
  atan2_swap_zero_TCC1: OBLIGATION
    FORALL (x, y: real): y /= 0 AND x = 0 IMPLIES x = 0 => y /= 0;

  % Subtype TCC generated (at line 64, column 14) for  y
      % expected type  {z: real | x = 0 => z /= 0}
  atan2_swap_zero_TCC2: OBLIGATION
    FORALL (x, y: real):
      (x = 0 AND y /= 0 IMPLIES atan2(x, y) = atan2(y, x) + pi / 2) AND
       x /= 0 AND y = 0
       IMPLIES x = 0 => y /= 0;

  % Subtype TCC generated (at line 67, column 17) for  sin(a)
      % expected type  {z: real | cos(a) = 0 => z /= 0}
  atan2_cos_sin_TCC1: OBLIGATION
    FORALL (a: {z: nnreal | z < 2 * pi}): cos(a) = 0 => sin(a) /= 0;

  % Subtype TCC generated (at line 75, column 21) for  x
      % expected type  nznum
  sin_atan2_TCC1: OBLIGATION
    FORALL (x, y: real): (x /= 0 OR y /= 0) AND NOT x = 0 IMPLIES x /= 0;


body:
  to2pi :THEORY
  BEGIN

    IMPORTING atan2, 
              trig_ineq

    a,b   : VAR real
    alpha : VAR nnreal_lt_2pi
    beta  : VAR real
    k     : VAR int

    to2pi(a) : nnreal_lt_2pi =
      LET n = floor(a/(2*pi)) IN
      a - 2*n*pi

    to2pi_id : LEMMA
      to2pi(alpha) = alpha

    to2pi_period : LEMMA
      to2pi(a) = to2pi(a+2*k*pi)

    sin_id_to2pi : LEMMA
      sin(to2pi(a)) = sin(a)

    cos_id_to2pi : LEMMA
      cos(to2pi(a)) = cos(a)

    to2pi_to2pi : LEMMA
      to2pi(to2pi(a)+b) = to2pi(a+b)

    to2pi_to2pi_sub : LEMMA
      to2pi(b-to2pi(a)) = to2pi(b-a)

    to2pi_neg : LEMMA
      -2*pi <= a AND a < 0 IMPLIES to2pi(a) = a+2*pi

    to2pi_equal : LEMMA
      to2pi(a) = to2pi(b) IMPLIES
        EXISTS(k:int): a = b + k*2*pi

    to2pi_to2pi_add : LEMMA
      to2pi(to2pi(a)+b) = to2pi(a+b)

    to2pi_closed_diff :  LEMMA
      abs(to2pi(a) - to2pi(b)) < 2*pi

    to2pi_eq: LEMMA
      FORALL (k: int): a = b + 2*k*pi IMPLIES
      to2pi(a) = to2pi(b)

    to2pi_sep : LEMMA
      a < b AND b < a + 2*pi IMPLIES 
      ((EXISTS (k:int): (a < 2*k*pi AND 2*k*pi <= b))
       OR
       (EXISTS (k: int): (2*k*pi <= a AND b < 2*(k+1)*pi)))

    sin_gt_to2pi : LEMMA
      -pi/2 <= b AND b <= pi/2 IMPLIES
     (sin(a) > sin(b) IFF b < to2pi(a+pi/2)-pi/2 AND to2pi(a+pi/2)-pi/2 < pi-b)

    sin_lt_to2pi : LEMMA
      -pi/2 <= b AND b <= pi/2 IMPLIES
     (sin(a) < sin(b) IFF b > to2pi(a+pi/2)-pi/2 OR to2pi(a+pi/2)-pi/2 > pi-b)

    sin_ge_to2pi : LEMMA
      -pi/2 <= b AND b <= pi/2 IMPLIES
     (sin(a) >= sin(b) IFF b <= to2pi(a+pi/2)-pi/2 AND to2pi(a+pi/2)-pi/2 <= pi-b)

    cos_pos_to2pi : LEMMA
      cos(a) > 0 IFF -pi/2 < to2pi(a+pi/2)-pi/2 AND to2pi(a+pi/2)-pi/2 < pi/2

    cos_nneg_to2pi : LEMMA
      cos(a) >= 0 IFF -pi/2 <= to2pi(a+pi/2)-pi/2 AND to2pi(a+pi/2)-pi/2 <= pi/2

  END to2pi

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

  % Subtype TCC generated (at line 14, column 4) for  a - 2 * n * pi
      % expected type  nnreal_lt_2pi
  to2pi_TCC1: OBLIGATION
    FORALL (a: real, n: {i | i <= a / (2 * pi) & a / (2 * pi) < 1 + i}):
      n = floor(a / (2 * pi)) IMPLIES
       a - 2 * n * pi >= 0 AND a - 2 * n * pi < 2 * pi;


body:
  trig_inverses: THEORY
  %----------------------------------------------------------------------------
  % Interface to Inverse Trig Function
  %
  % Rick Butler 1/8/08
  %----------------------------------------------------------------------------
  BEGIN
     IMPORTING trig_basic, asin, acos, atan, atan2

    a: VAR real


  % nnreal_quad1_closed: NONEMPTY_TYPE = {x:nnreal | x <= pi/2} 
  % nnreal_quad1_open:   NONEMPTY_TYPE = {x:nnreal | x <  pi/2} 
  % real_abs_lt_pi:      NONEMPTY_TYPE = {x:real   | -pi/2 < x AND x < pi/2} 
  % posreal_lt_pi:       NONEMPTY_TYPE = {x:posreal| x < pi} 
  % nnreal_le_pi :       NONEMPTY_TYPE = {x:nnreal | x <= pi}     
  % real_abs_le1:        NONEMPTY_TYPE = {x:real | -1 <= x AND x <= 1}    
  % real_abs_lt1:        NONEMPTY_TYPE = {x:real | -1 < x  AND x <  1}    
  % real_abs_le_pi2:     NONEMPTY_TYPE = {x:real | -pi/2 <= x AND x <= pi/2}
  % real_abs_lt_pi:      NONEMPTY_TYPE = {x:real   | -pi/2 < x AND x < pi/2} 


  % ---------- ArcSine ----------------- (See asin.pvs)
  %
  %   asin(x:real_abs_le1): real_abs_le_pi2
  %
  %   asin_0:                 LEMMA asin(0)  = 0
  %   asin_sqrt_half:         LEMMA asin(sqrt(1/2)) = pi/4
  %   asin_1:                 LEMMA asin(1)  = pi/2
  %   asin_neg:               LEMMA asin(-x) = -asin(x)
  %   asin_minus1:            LEMMA asin(-1) = -pi/2
  %   asin_minus_sqrt_half:   LEMMA asin(-sqrt(1/2)) = -pi/4

      AUTO_REWRITE+ asin_0
      AUTO_REWRITE+ asin_1

  % ---------- ArcCosine ----------------- (See acos.pvs)
  %
  %   acos(x:real_abs_le1): nnreal_le_pi = pi/2 - asin(x)
  %
  %   acos_neg:               LEMMA acos(-x) = pi-acos(x)
  %   acos_0:                 LEMMA acos(0)  = pi/2
  %   acos_sqrt_half:         LEMMA acos(sqrt(1/2)) = pi/4
  %   acos_1:                 LEMMA acos(1)  = 0
  %   acos_minus1:            LEMMA acos(-1) = pi
  %   acos_minus_sqrt_half:   LEMMA acos(-sqrt(1/2)) = 3*pi/4

      AUTO_REWRITE+ acos_0
      AUTO_REWRITE+ acos_1


  % ---------- ArcTangent ----------------- (See atan.pvs)
  %
  %  atan(x:real): real_abs_lt_pi2 
  %
  %  atan_0                : LEMMA atan(0) = 0
  %  atan_inv              : LEMMA atan(1/px) = pi/2-atan(px)
  %  atan_inv_neg          : LEMMA atan(1/nx) = -pi/2-atan(nx)
  %  atan_neg              : LEMMA atan(-x)   = -atan(x) 
  %  acot_neg              : LEMMA acot(-nzx) = -acot(nzx)  

      AUTO_REWRITE+ atan_0

  %  --------- Inverse Relationships (See sincos_def)

  %   sin_asin: LEMMA sin(asin(x)) = x
  %   cos_acos: LEMMA cos(acos(x)) = x
  %   tan_atan: LEMMA tan(atan(a)) = a

  %   asin_sin: LEMMA FORALL (x:real_abs_le_pi2): asin(sin(x)) = x
  %   acos_cos: LEMMA FORALL (x:nnreal_le_pi):   acos(cos(x)) = x
  %   atan_tan: LEMMA FORALL (x:real_abs_lt_pi2): atan(tan(x)) = x


  %  --- The following provide additional names for the inverse functions
  %  --- that include their basic property in the type.  These are included
  %  --- for upward compatibility.

  %  -------------------- Arcsin --------------------

     arcsin(y: real_abs_le1): {x: real_abs_le_pi2 | y = sin(x)} = asin(y)

     sin_arcsin: LEMMA (FORALL (y: real_abs_le1): sin(arcsin(y)) = y)
     arcsin_sin: LEMMA (FORALL (x: real_abs_lt_pi2): arcsin(sin(x)) = x)

  %  -------------------- Arccos --------------------

     arccos(y: real_abs_le1): {x: nnreal_le_pi | y = cos(x)} = acos(y)

     cos_arccos: LEMMA (FORALL (y: real_abs_le1): cos(arccos(y)) = y)
     arccos_cos: LEMMA (FORALL (x: nnreal_le_pi): arccos(cos(x)) = x)

  %  -------------------- Arctan --------------------

     arctan_prep: LEMMA FORALL (x: real_abs_lt_pi2): Tan?(x);

     arctan(y: real): {x: real_abs_lt_pi2 | y = tan(x)} = atan(y)

     tan_arctan: LEMMA (FORALL (y: real): tan(arctan(y)) = y)
     arctan_tan: LEMMA (FORALL (x: real_abs_lt_pi2): arctan(tan(x)) = x)

  END trig_inverses

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

  % Subtype TCC generated (at line 82, column 64) for  asin(y)
      % expected type  {x: real_abs_le_pi2 | y = sin(x)}
  arcsin_TCC1: OBLIGATION FORALL (y: real_abs_le1): y = sin(asin(y));

  % Subtype TCC generated (at line 89, column 61) for  acos(y)
      % expected type  {x: nnreal_le_pi | y = cos(x)}
  arccos_TCC1: OBLIGATION FORALL (y: real_abs_le1): y = cos(acos(y));

  % Subtype TCC generated (at line 98, column 50) for  x
      % expected type  (Tan?)
  arctan_TCC1: OBLIGATION FORALL (x: real_abs_lt_pi2): Tan?(x);

  % Subtype TCC generated (at line 98, column 56) for  atan(y)
      % expected type  {x: real_abs_lt_pi2 | y = tan(x)}
  arctan_TCC2: OBLIGATION FORALL (y: real): y = tan(atan(y));

  % Subtype TCC generated (at line 100, column 44) for  arctan(y)
      % expected type  (Tan?)
  tan_arctan_TCC1: OBLIGATION FORALL (y: real): Tan?(arctan(y));


body:
  atan_values: THEORY
  %------------------------------------------------------------------------------
  %
  %  Rick Butler    NASA Langley
  % 
  %------------------------------------------------------------------------------
  BEGIN

    IMPORTING atan, trig_values, trig_inverses

    atan0        : LEMMA atan(0) = 0                   %% atan_0 already used

    atan1        : LEMMA atan(1) = pi/4                %% atan_1 already used

    atan_1sqrt3  : LEMMA atan(1/sqrt(3)) = pi/6

    atan_sqrt3   : LEMMA atan(sqrt(3))   = pi/3

    atan_m1sqrt3 : LEMMA atan(-1/sqrt(3)) = -pi/6

    atan_msqrt3  : LEMMA atan(-sqrt(3))   = -pi/3

    x: VAR real

    atan_gt_0    : LEMMA atan(x) > 0 IFF x > 0

  END atan_values


body:
  atan2_props: THEORY
  BEGIN

    IMPORTING atan2, trig_ineq

    atan2_is_0:    LEMMA FORALL (x:real,y:{z:real | x = 0 => z/=0}):
                             atan2(x,y) =   0    IFF (x > 0 AND y = 0)

    atan2_is_pi2:  LEMMA FORALL (x:real,y:{z:real | x = 0 => z/=0}):
                             atan2(x,y) =   pi/2 IFF (x = 0 AND y > 0)

    atan2_is_pi:   LEMMA FORALL (x:real,y:{z:real | x = 0 => z/=0}):
                             atan2(x,y) =   pi   IFF (x < 0 AND y = 0)

    atan2_is_3pi2: LEMMA FORALL (x:real,y:{z:real | x = 0 => z/=0}):
                             atan2(x,y) = 3*pi/2 IFF (x = 0 AND y < 0)

    atan2_quad1:   LEMMA FORALL (x:real,y:{z:real | x = 0 => z/=0}):
                             (0 < atan2(x,y) AND atan2(x,y) < pi/2) IFF
                                                                (x > 0 AND y > 0)

    atan2_quad2:   LEMMA FORALL (x:real,y:{z:real | x = 0 => z/=0}):
                             (pi/2 < atan2(x,y) AND atan2(x,y) < pi) IFF
                                                                (x < 0 AND y > 0)

    atan2_quad3:   LEMMA FORALL (x:real,y:{z:real | x = 0 => z/=0}):
                             (pi < atan2(x,y) AND atan2(x,y) < 3*pi/2) IFF
                                                                (x < 0 AND y < 0)

    atan2_quad4:   LEMMA FORALL (x:real,y:{z:real | x = 0 => z/=0}):
                             (3*pi/2 < atan2(x,y) AND atan2(x,y) < 2*pi) IFF
                                                                (x > 0 AND y < 0)


    %% ------------ atan2 values -------------------------------------


     IMPORTING trig_values, atan_values

     nzx: VAR nzreal

     atan2_0x      : LEMMA atan2(0,nzx) = IF nzx > 0 THEN pi/2 ELSE 3*pi/2 ENDIF
     atan2_x0      : LEMMA atan2(nzx,0) = IF nzx > 0 THEN 0 ELSE pi ENDIF

     atan2_11      : LEMMA atan2(1,1) = pi/4
     atan2_m11     : LEMMA atan2(-1,1) = 3*pi/4
     atan2_1m1     : LEMMA atan2(1,-1) = 7*pi/4
     atan2_m1m1    : LEMMA atan2(-1,-1) = 5*pi/4


     atan2_1sqrt3  : LEMMA atan2(1,sqrt(3)) = pi/3
     atan2_sqrt3   : LEMMA atan2(sqrt(3),1) = pi/6


     atan2_m1sqrt3 : LEMMA atan2(-1,sqrt(3)) = 2*pi/3
     atan2_sqrt3m1 : LEMMA atan2(sqrt(3),-1) = 11*pi/6


  END atan2_props

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

  % Subtype TCC generated (at line 43, column 35) for  0
      % expected type  {z: real | nzx = 0 => z /= 0}
  atan2_x0_TCC1: OBLIGATION FORALL (nzx: nzreal): nzx = 0 => 0 /= 0;

  % Subtype TCC generated (at line 52, column 39) for  1
      % expected type  {z: real | sqrt(3) = 0 => z /= 0}
  atan2_sqrt3_TCC1: OBLIGATION sqrt(3) = 0 => 1 /= 0;

  % Subtype TCC generated (at line 56, column 39) for  -1
      % expected type  {z: real | sqrt(3) = 0 => z /= 0}
  atan2_sqrt3m1_TCC1: OBLIGATION sqrt(3) = 0 => -1 /= 0;


body:
  trig_extra : THEORY
  %-----------------------------------------------------------------------------
  %      trig_extra
  %      ----------
  %         - reduction theorems
  %         - sum and product identities
  %         - half-angle identities and zeros
  %         - triple angle formulas
  %-----------------------------------------------------------------------------
  BEGIN

     IMPORTING trig_basic, trig_values


    a,b             : VAR real

  % ------------------------- Reduction Theorems -------------------------

    sin_minus_2pi    : LEMMA sin(a - 2*pi) = sin(a)  
    cos_minus_2pi    : LEMMA cos(a - 2*pi) = cos(a) 
    tan_minus_2pi    : LEMMA cos(a) /= 0 IMPLIES tan(a - 2*pi) = tan(a) 

    sin_minus_3pi2   : LEMMA sin(a - 3*pi/2) =   cos(a)
    cos_minus_3pi2   : LEMMA cos(a - 3*pi/2) = - sin(a)
    tan_minus_3pi2   : LEMMA sin(a) /= 0 AND cos(a) /= 0 
                                IMPLIES tan(a - 3*pi/2) = - 1/tan(a)

    sin_minus_pi     : LEMMA sin(a - pi) = - sin(a)
    cos_minus_pi     : LEMMA cos(a - pi) = - cos(a)
    tan_minus_pi     : LEMMA cos(a) /= 0 IMPLIES tan(a - pi) =   tan(a)

    sin_minus_pi2    : LEMMA sin(a - pi/2) = - cos(a)
    cos_minus_pi2    : LEMMA cos(a - pi/2) =   sin(a)
    tan_minus_pi2    : LEMMA sin(a) /= 0 AND cos(a) /= 0 
                                IMPLIES tan(a - pi/2) = - 1/tan(a)

    sin_2pi_minus    : LEMMA sin(2*pi - a) = - sin(a)
    cos_2pi_minus    : LEMMA cos(2*pi - a) =   cos(a)
    tan_2pi_minus    : LEMMA sin(a) /= 0 AND cos(a) /= 0 
                                IMPLIES tan(2*pi - a) =   - tan(a)
                                 
    sin_3pi2_minus   : LEMMA sin(3*pi/2 - a) = - cos(a)
    cos_3pi2_minus   : LEMMA cos(3*pi/2 - a) = - sin(a)
    tan_3pi2_minus   : LEMMA sin(a) /= 0 AND cos(a) /= 0 
  	                             IMPLIES tan(3*pi/2 - a) =   1/tan(a)
                                 
    sin_pi_minus     : LEMMA sin(pi - a) =   sin(a)
    cos_pi_minus     : LEMMA cos(pi - a) = - cos(a)
    tan_pi_minus     : LEMMA cos(a) /= 0 IMPLIES tan(pi - a) = - tan(a)
                                 
    sin_pi2_minus    : LEMMA sin(pi/2 - a) = cos(a)
    cos_pi2_minus    : LEMMA cos(pi/2 - a) = sin(a)
    tan_pi2_minus    : LEMMA sin(a) /= 0 AND cos(a) /= 0 
                                IMPLIES tan(pi/2 - a) = 1/tan(a)

  % ------------------------- Sum and Product Formulas -------------------------

    sin_times_cos    : LEMMA sin(a)*cos(b) = (sin(a+b) + sin(a-b))/2
    cos_times_cos    : LEMMA cos(a)*cos(b) = (cos(a+b) + cos(a-b))/2
    sin_times_sin    : LEMMA sin(a)*sin(b) = (cos(a-b) - cos(a+b))/2

    sin_sum          : LEMMA sin(a) + sin(b) =   2 * sin((a+b)/2)*cos((a-b)/2)
    sin_diff         : LEMMA sin(a) - sin(b) =   2 * cos((a+b)/2)*sin((a-b)/2)
    cos_sum          : LEMMA cos(a) + cos(b) =   2 * cos((a+b)/2)*cos((a-b)/2)
    cos_diff         : LEMMA cos(a) - cos(b) = - 2 * sin((a+b)/2)*sin((a-b)/2)

    tan_diff         : LEMMA Tan?(a) AND Tan?(b) IMPLIES
                                tan(a) - tan(b) = sin(a-b)/(cos(a)*cos(b))

  % ------------------------- Squares of sin and cos -------------------------

    sq_sin           : LEMMA sq(sin(a)) = (1-cos(2*a))/2
    sq_cos           : LEMMA sq(cos(a)) = (1+cos(2*a))/2
    sin_half_zeroes  : LEMMA sin(a/2) = 0 IFF 1-cos(a) = 0
    cos_half_zeroes  : LEMMA cos(a/2) = 0 IFF 1+cos(a) = 0
    cos_half_zeroes2 : LEMMA cos(a/2) = 0 IMPLIES sin(a) = 0
    sq_tan           : LEMMA (1+cos(2*a)) /= 0 
                                  IMPLIES sq(tan(a)) = (1-cos(2*a))/(1+cos(2*a))

  % ------------------------- Half Angle Formulas -------------------------

    IMPORTING trig_ineq 

    sin_half  : LEMMA 
                  ( 0 <= a/2 AND a/2 <= pi IMPLIES
                    sin(a/2) = sqrt((1-cos(a))/2))  AND
                  ( pi <= a/2 AND a/2 <= 2*pi IMPLIES
                    sin(a/2) = -sqrt((1-cos(a))/2))

    cos_half  : LEMMA 
                  ( 0 <= a/2 AND a/2 <= pi/2 IMPLIES
                    cos(a/2) = sqrt((1+cos(a))/2))  AND
                  ( pi/2 <= a/2 AND a/2 <= 3*pi/2 IMPLIES
                    cos(a/2) = -sqrt((1+cos(a))/2)) AND 
                  ( 3*pi/2 <= a/2 AND a/2 <= 2*pi IMPLIES
                    cos(a/2) = sqrt((1+cos(a))/2)) 

    tan_half  : LEMMA
                  cos(a) /= -1 IMPLIES tan(a/2) = sin(a)/(1 + cos(a)) 

    tan_half2 : LEMMA
                  sin(a) /= 0 IMPLIES tan(a/2) = (1 - cos(a))/sin(a)

  % ---------------------- Triple Angle Formulas ----------------------

    sin_3a      : LEMMA sin(3*a) = 3 * sin(a) - 4 * expt(sin(a),3)
    cos_3a      : LEMMA cos(3*a) = 4 * expt(cos(a),3) - 3 * cos(a)

  % ---------------------- Base equations ---------------------

    sin_eq_sin  : LEMMA sin(a) = sin(b) <=> 
                     (EXISTS (k: int): (a = b + 2*k*pi) OR (a = pi - b + 2*k*pi)) 

    cos_eq_cos  : LEMMA cos(a) = cos(b) <=> 
                     (EXISTS (k: int): (a = b + 2*k*pi) OR (a = -b + 2*k*pi)) 

    tan_eq_tan  : LEMMA Tan?(a) AND Tan?(b) IMPLIES
                        ( tan(a) = tan(b) <=> (EXISTS (k: int): (a = b + k*pi)) )

    sin_cos_eq: LEMMA FORALL (a,b: {x:nnreal | x < 2*pi}): 
                                 sin(a) = sin(b) AND cos(a) = cos(b)
                                 IMPLIES a = b

    sin_eq_cos: LEMMA sin(a) = cos(a) IMPLIES (EXISTS (i:int): a = pi/4 + i*pi)

    tan_eq_1  : LEMMA Tan?(a) AND tan(a) = 1 IMPLIES (EXISTS (i:int): a = pi/4 + i*pi)


    i,j: VAR integer

    sin_eq_pm1  : LEMMA sin(a) = (-1)^i IFF (EXISTS j: a = (i+2*j)*pi + pi/2)
    cos_eq_pm1  : LEMMA cos(a) = (-1)^i IFF (EXISTS j: a = (i+2*j)*pi)

  % --------------------- Superposition ----------------------

    A,B: VAR real
    C: VAR nzreal
    x,y,del,W, alpha: VAR real

    sin_plus_cos: LEMMA sq(C) = sq(A) + sq(B) AND sin(del) = B/C
                          AND cos(del) = A/C  IMPLIES
                          A*sin(x) + B*cos(x) = C*sin(x+del)

    spc_tan_prep: LEMMA A /= 0 AND Tan?(del) AND tan(del) = B/A AND 
                        sq(C) = sq(A) + sq(B) IMPLIES
                           sq(sin(del)) = sq(B/C) AND sq(cos(del)) = sq(A/C)

    IMPORTING atan2

    sin_plus_cos_atan2: LEMMA
       x /= 0 OR y /= 0 IMPLIES
         x*sin(alpha) + y*cos(alpha) = sqrt(sq(x)+sq(y))*sin(alpha + atan2(x,y))


                           

  %   sin_superpos: LEMMA A + B*cos(W) = C*cos(del) AND  % need to find f:
  %                           B*sin(W) = C*sin(del)      % del = f(A,B,C,W)
  %                       IMPLIES
  %                           A*sin(x) + B*sin(x+W) = C*sin(x+del)

  END trig_extra

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

  % Subtype TCC generated (at line 21, column 51) for  a - 2 * pi
      % expected type  (Tan?)
  tan_minus_2pi_TCC1: OBLIGATION
    FORALL (a: real): cos(a) /= 0 IMPLIES Tan?(a - 2 * pi);

  % Subtype TCC generated (at line 21, column 67) for  a
      % expected type  (Tan?)
  tan_minus_2pi_TCC2: OBLIGATION
    FORALL (a: real): cos(a) /= 0 IMPLIES Tan?(a);

  % Subtype TCC generated (at line 26, column 42) for  a - 3 * pi / 2
      % expected type  (Tan?)
  tan_minus_3pi2_TCC1: OBLIGATION
    FORALL (a: real):
      cos(a) /= 0 AND sin(a) /= 0 IMPLIES Tan?(a - 3 * pi / 2);

  % Subtype TCC generated (at line 26, column 60) for  tan(a)
      % expected type  nznum
  tan_minus_3pi2_TCC2: OBLIGATION
    FORALL (a: real): cos(a) /= 0 AND sin(a) /= 0 IMPLIES tan(a) /= 0;

  % Subtype TCC generated (at line 30, column 51) for  a - pi
      % expected type  (Tan?)
  tan_minus_pi_TCC1: OBLIGATION
    FORALL (a: real): cos(a) /= 0 IMPLIES Tan?(a - pi);

  % Subtype TCC generated (at line 35, column 42) for  a - pi / 2
      % expected type  (Tan?)
  tan_minus_pi2_TCC1: OBLIGATION
    FORALL (a: real): cos(a) /= 0 AND sin(a) /= 0 IMPLIES Tan?(a - pi / 2);

  % Subtype TCC generated (at line 40, column 42) for  2 * pi - a
      % expected type  (Tan?)
  tan_2pi_minus_TCC1: OBLIGATION
    FORALL (a: real): cos(a) /= 0 AND sin(a) /= 0 IMPLIES Tan?(2 * pi - a);

  % Subtype TCC generated (at line 45, column 42) for  3 * pi / 2 - a
      % expected type  (Tan?)
  tan_3pi2_minus_TCC1: OBLIGATION
    FORALL (a: real):
      cos(a) /= 0 AND sin(a) /= 0 IMPLIES Tan?(3 * pi / 2 - a);

  % Subtype TCC generated (at line 49, column 51) for  pi - a
      % expected type  (Tan?)
  tan_pi_minus_TCC1: OBLIGATION
    FORALL (a: real): cos(a) /= 0 IMPLIES Tan?(pi - a);

  % Subtype TCC generated (at line 54, column 42) for  pi / 2 - a
      % expected type  (Tan?)
  tan_pi2_minus_TCC1: OBLIGATION
    FORALL (a: real): cos(a) /= 0 AND sin(a) /= 0 IMPLIES Tan?(pi / 2 - a);

  % Subtype TCC generated (at line 68, column 58) for  (cos(a) * cos(b))
      % expected type  nznum
  tan_diff_TCC1: OBLIGATION
    FORALL (a, b: real): Tan?(b) AND Tan?(a) IMPLIES (cos(a) * cos(b)) /= 0;

  % Subtype TCC generated (at line 78, column 47) for  a
      % expected type  (Tan?)
  sq_tan_TCC1: OBLIGATION
    FORALL (a: real): (1 + cos(2 * a)) /= 0 IMPLIES Tan?(a);

  % Subtype TCC generated (at line 86, column 34) for  (1 - cos(a)) / 2
      % expected type  nnx: nonneg_real
  sin_half_TCC1: OBLIGATION
    FORALL (a: real):
      a / 2 <= pi AND 0 <= a / 2 IMPLIES (1 - cos(a)) / 2 >= 0;

  % Subtype TCC generated (at line 88, column 35) for  (1 - cos(a)) / 2
      % expected type  nnx: nonneg_real
  sin_half_TCC2: OBLIGATION
    FORALL (a: real):
      (0 <= a / 2 AND a / 2 <= pi IMPLIES
        sin(a / 2) = sqrt((1 - cos(a)) / 2))
       AND a / 2 <= 2 * pi AND pi <= a / 2
       IMPLIES (1 - cos(a)) / 2 >= 0;

  % Subtype TCC generated (at line 92, column 34) for  (1 + cos(a)) / 2
      % expected type  nnx: nonneg_real
  cos_half_TCC1: OBLIGATION
    FORALL (a: real):
      a / 2 <= pi / 2 AND 0 <= a / 2 IMPLIES (1 + cos(a)) / 2 >= 0;

  % Subtype TCC generated (at line 94, column 35) for  (1 + cos(a)) / 2
      % expected type  nnx: nonneg_real
  cos_half_TCC2: OBLIGATION
    FORALL (a: real):
      (0 <= a / 2 AND a / 2 <= pi / 2 IMPLIES
        cos(a / 2) = sqrt((1 + cos(a)) / 2))
       AND a / 2 <= 3 * pi / 2 AND pi / 2 <= a / 2
       IMPLIES (1 + cos(a)) / 2 >= 0;

  % Subtype TCC generated (at line 96, column 34) for  (1 + cos(a)) / 2
      % expected type  nnx: nonneg_real
  cos_half_TCC3: OBLIGATION
    FORALL (a: real):
      (0 <= a / 2 AND a / 2 <= pi / 2 IMPLIES
        cos(a / 2) = sqrt((1 + cos(a)) / 2))
       AND
       (pi / 2 <= a / 2 AND a / 2 <= 3 * pi / 2 IMPLIES
         cos(a / 2) = -sqrt((1 + cos(a)) / 2))
        AND a / 2 <= 2 * pi AND 3 * pi / 2 <= a / 2
       IMPLIES (1 + cos(a)) / 2 >= 0;

  % Subtype TCC generated (at line 99, column 41) for  a / 2
      % expected type  (Tan?)
  tan_half_TCC1: OBLIGATION
    FORALL (a: real): cos(a) /= -1 IMPLIES Tan?(a / 2);

  % Subtype TCC generated (at line 99, column 56) for  (1 + cos(a))
      % expected type  nznum
  tan_half_TCC2: OBLIGATION
    FORALL (a: real): cos(a) /= -1 IMPLIES (1 + cos(a)) /= 0;

  % Subtype TCC generated (at line 102, column 40) for  a / 2
      % expected type  (Tan?)
  tan_half2_TCC1: OBLIGATION
    FORALL (a: real): sin(a) /= 0 IMPLIES Tan?(a / 2);

  % Subtype TCC generated (at line 152, column 75) for  y
      % expected type  {z: real | x = 0 => z /= 0}
  sin_plus_cos_atan2_TCC1: OBLIGATION
    FORALL (x, y: real): x /= 0 OR y /= 0 IMPLIES x = 0 => y /= 0;


body:
  trig_approx: THEORY
  %-----------------------------------------------------------------------------
  %      trig_approx
  %      -----------
  %          - taylor series approximations to trig functions:
  %               sin_approx(a,n): sum first n terms of taylor expansion of sin
  %               cos_approx(a,n): sum first n terms of taylor expansion of cos
  %          - defines upper and lower bounds on trig functions:
  %
  %       Version 2 Foundational (DRL) 4/4/05
  %  
  %  CHANGES
  %    - Redefined sin_lb,sin_ub,cos_lb,cos_ub,tan_lb,tan_ub to make it 
  %      suitable for interval theory.
  %    - Removed lemmas SIN,COS,TAN. Use sin_bound_0_pi, cos_bound_npi2_pi2,
  %      tan_bound_0_pi2. Cesar Munoz (Nov 28 2003).
  %    - Added Hanne Gottliebsen's proofs for sin_bound_npi_0 and 
  %      cos_bound_npi_pi.
  %      Cesar Munoz (Feb 6 2004). 
  %    - Tan approximations moved to tan_approx due to circularity problems with
  %      trig_ineq. Cear Munoz (Feb 6 2004)
  %    - The theory has been completely revisited by David Lester (4/4/05)
  %
  %-----------------------------------------------------------------------------

    BEGIN

    IMPORTING  exp_term, sincos, trig_ineq, reals@sigma_nat,
               analysis@derivatives,trig_extra,analysis@derivative_props

    m,n:  VAR nat
    pm:   VAR posnat
    a:    VAR real
    px:   VAR posreal
    n0x:  VAR nzreal
    nnx:  VAR nnreal

    IMPORTING analysis@deriv_domains

    sin_term(a)(n): real = (-1)^n*a^(2*n+1)/factorial(2*n+1)

    sin_term_next       : LEMMA sin_term(a)(n+1) =
                                sin_term(a)(n) * -1 * a*a / ((2*n+3)*(2*n+2))

    sin_term_neg        : LEMMA sin_term(-a)(n) = -sin_term(a)(n)

    sin_terms_alternate : LEMMA 0 /= a IMPLIES (sin_term(a)(n+1) < 0 IFF
                                                  sin_term(a)(n) > 0)

    sin_term_nonzero    : LEMMA sin_term(a)(n) /= 0 IFF a /= 0
    sin_term_zero       : LEMMA sin_term(a)(n)  = 0 IFF a  = 0
    sin_term_gt0        : LEMMA sin_term(a)(n)  > 0 IFF
                             ((even?(n) AND a > 0) OR (odd?(n) AND a < 0))
    sin_term_lt0        : LEMMA sin_term(a)(n)  < 0 IFF
                             ((even?(n) AND a < 0) OR (odd?(n) AND a > 0))

    sin_tends_to_0      : LEMMA tends_to_0?(sin_term(a))

    cos_term(a)(n): real = IF n=0 THEN 1 ELSE (-1)^n*a^(2*n)/factorial(2*n) ENDIF

    cos_term_next       : LEMMA cos_term(a)(n+1) =
                                cos_term(a)(n) * -1 * a*a / ((2*n+2)*(2*n+1))

    cos_term_neg        : LEMMA cos_term(-a)(n) = cos_term(a)(n)

    cos_terms_alternate : LEMMA 0 /= a IMPLIES (cos_term(a)(n+1) < 0 IFF
                                                  cos_term(a)(n) > 0)

    cos_term_nonzero    : LEMMA cos_term(a)(n) /= 0 IFF (n  = 0   OR  a /= 0)
    cos_term_zero       : LEMMA cos_term(a)(n)  = 0 IFF (n /= 0   AND a  = 0)
    cos_term_gt0        : LEMMA cos_term(a)(n)  > 0 IFF
                                     (even?(n) AND (a /= 0 OR n = 0))
    cos_term_lt0        : LEMMA cos_term(a)(n)  < 0 IFF (odd?(n) AND a /= 0)

    cos_tends_to_0      : LEMMA tends_to_0?(cos_term(n0x))

    sin_term_deriv: LEMMA derivable?[real](LAMBDA a: sin_term(a)(n)) AND
        deriv[real](LAMBDA a: sin_term(a)(n)) = (LAMBDA a: cos_term(a)(n))

    cos_term_deriv: LEMMA derivable?[real](LAMBDA a: cos_term(a)(n)) AND
        deriv[real](LAMBDA a: cos_term(a)(n)) =
                        (LAMBDA a: IF n = 0 THEN 0 ELSE -sin_term(a)(n-1) ENDIF)

    sin_approx(a,n):real = sigma(0,n,sin_term(a))

    sin_approx_a0:     LEMMA sin_approx(0,n) = 0

    sin_approx_neg:    LEMMA sin_approx(-a,n) = -sin_approx(a,n) 

    sin_approx_next:   LEMMA sin_approx(a,n+2) - sin_approx(a,n) = 
                              sin_term(a)(n+1) * (1 - a*a/((2*n+5)*(2*n+4)))

    sin_approx_eq:     LEMMA a*a = (2*n+5)*(2*n+4) IMPLIES
                              sin_approx(a,n+2) = sin_approx(a,n)

    sin_approx_sin:    LEMMA abs(sin(a)-sin_approx(a,n)) <= abs(sin_term(a)(n+1))

    cos_approx(a,n):real = sigma(0,n,cos_term(a))

    cos_approx_a0:     LEMMA cos_approx(0,n) = 1

    cos_approx_neg:    LEMMA cos_approx(-a,n) = cos_approx(a,n) 

    cos_approx_cos:    LEMMA abs(cos(a)-cos_approx(a,n)) <= abs(cos_term(a)(n+1))

    cos_approx_next:   LEMMA cos_approx(a,n+2) - cos_approx(a,n) = 
                              cos_term(a)(n+1) * (1 - a*a/((2*n+4)*(2*n+3)))

    cos_approx_eq:     LEMMA a*a = (2*n+4)*(2*n+3) IMPLIES
                              cos_approx(a,n+2) = cos_approx(a,n)

    sin_approx_deriv: LEMMA derivable?[real](LAMBDA a: sin_approx(a,n)) AND
                      deriv[real](LAMBDA a: sin_approx(a,n))
                                                   = (LAMBDA a: cos_approx(a,n))

    cos_approx_deriv: LEMMA derivable?[real](LAMBDA a: cos_approx(a,n)) AND
                      deriv[real](LAMBDA a: cos_approx(a,n)) =
                        (LAMBDA a: IF n = 0 THEN 0 ELSE -sin_approx(a,n-1) ENDIF)

    sin_ub(a,n):real = IF a < 0 THEN sin_approx(a,2*n+1)
                                ELSE sin_approx(a,2*n)   ENDIF
    sin_lb(a,n):real = IF a < 0 THEN sin_approx(a,2*n)
                                ELSE sin_approx(a,2*n+1) ENDIF

    sin_lb_neg: LEMMA sin_lb(-a,n) = -sin_ub(a,n)
    sin_ub_neg: LEMMA sin_ub(-a,n) = -sin_lb(a,n)

    sin_lb_a0 : LEMMA sin_lb(0,n) = 0
    sin_ub_a0 : LEMMA sin_ub(0,n) = 0

    sin_lb_ub : LEMMA sin_lb(n0x,n) < sin_ub(n0x,n)

    sin_lb_inc: LEMMA px*px < (4*n+7)*(4*n+6) => sin_lb(px,n) < sin_lb(px,n+pm)
    sin_ub_dec: LEMMA px*px < (4*n+5)*(4*n+4) => sin_ub(px,n+pm) < sin_ub(px,n)

    sin_lb_lt : LEMMA px*px < (4*n+7)*(4*n+6) => sin_lb(px,n) < sin(px)
    sin_ub_lt : LEMMA px*px < (4*n+5)*(4*n+4) => sin(px) < sin_ub(px,n)

    sin_lb_gt : LEMMA px*px > (4*n+7)*(4*n+6) => sin_lb(px,n) < -1
    sin_ub_gt : LEMMA px*px > (4*n+5)*(4*n+4) => sin_ub(px,n) >  1

    sin_lb     : LEMMA sin_lb(n0x,n) < sin(n0x)
    sin_ub     : LEMMA sin(n0x) < sin_ub(n0x,n)
    sin_bounds : LEMMA sin_lb(a,n) <= sin(a) AND sin(a) <= sin_ub(a,n)

    sin_lb_gt0: LEMMA px*px < 6 => sin_lb(px,n) > 0

    cos_ub(a,n):real = cos_approx(a,2*n)
    cos_lb(a,n):real = cos_approx(a,2*n+1)

    cos_lb_neg: LEMMA cos_lb(-a,n) = cos_lb(a,n)
    cos_ub_neg: LEMMA cos_ub(-a,n) = cos_ub(a,n)

    cos_lb_a0 : LEMMA cos_lb(0,n) = 1
    cos_ub_a0 : LEMMA cos_ub(0,n) = 1

    cos_lb_ub: LEMMA cos_lb(n0x,n) < cos_ub(n0x,n)

    cos_lb_inc: LEMMA n0x*n0x<(4*n+6)*(4*n+5) => cos_lb(n0x,n) < cos_lb(n0x,n+pm)
    cos_ub_dec: LEMMA n0x*n0x<(4*n+4)*(4*n+3) => cos_ub(n0x,n+pm) < cos_ub(n0x,n)

    cos_lb_lt:  LEMMA n0x*n0x < (4*n+6)*(4*n+5) => cos_lb(n0x,n) < cos(n0x)
    cos_ub_lt:  LEMMA n0x*n0x < (4*n+4)*(4*n+3) => cos(n0x) < cos_ub(n0x,n)

    cos_lb_gt:  LEMMA n0x*n0x > (4*n+6)*(4*n+5)        => cos_lb(n0x,n) < -1
    cos_ub_gt:  LEMMA n0x*n0x > (4*n+4)*(4*n+3) & n>=1 => cos_ub(n0x,n) >  1

    cos_lb:     LEMMA cos_lb(n0x,n) < cos(n0x)
    cos_ub:     LEMMA cos(n0x) < cos_ub(n0x,pm)

    cos_bounds:  LEMMA cos_lb(a,n) <= cos(a) AND cos(a) <= cos_ub(a,n)

    sin_lb_deriv: LEMMA derivable?[nnreal](LAMBDA nnx: sin_lb(nnx,n)) AND
         deriv[nnreal](LAMBDA nnx: sin_lb(nnx,n)) = (LAMBDA nnx: cos_lb(nnx,n))

    sin_ub_deriv: LEMMA derivable?[nnreal](LAMBDA nnx: sin_ub(nnx,n)) AND
         deriv[nnreal](LAMBDA nnx: sin_ub(nnx,n)) = (LAMBDA nnx: cos_ub(nnx,n))

    cos_lb_deriv: LEMMA derivable?[real](LAMBDA a: cos_lb(a,n)) AND
         deriv[real](LAMBDA a: cos_lb(a,n))
           = (LAMBDA a: IF a < 0 THEN -sin_lb(a,n) ELSE -sin_ub(a,n) ENDIF)

    cos_ub_deriv: LEMMA derivable?[real](LAMBDA a: cos_ub(a,n)) AND
         deriv[real](LAMBDA a: cos_ub(a,n))
           = (LAMBDA a: IF n = 0 THEN 0 ELSIF
                           a < 0 THEN -sin_ub(a,n-1) ELSE -sin_lb(a,n-1) ENDIF)

    cos_lb_nn_strict_decreasing:
          LEMMA strict_decreasing?(LAMBDA (x:{x:nnreal| x <=  pi}): cos_lb(x,n))

    cos_lb_np_strict_increasing:
          LEMMA strict_increasing?(LAMBDA (x:{x:npreal| x >= -pi}): cos_lb(x,n))

    sin_px: LEMMA 1/500 > px => sin(px) > px*(1-1/1500000)

    % Approximation to guarantee cos_lb > 0
    Cos_pos_n : MACRO posnat = 5 

    cos_term_pi_lb: LEMMA n >= Cos_pos_n IMPLIES
                          cos_term(pi_lbn(n)/2)(2*n+2) < cos(pi_lbn(n)/2)

    cos_lb_pi2_eps: LEMMA px <= pi/2 AND
                          abs(cos_term(pi/2-px)(2*n+2)) < sin(px) =>
                          cos_lb(pi/2-px,n) > 0

    cos_lb_pi2_pos0 : LEMMA n=0 => NOT cos_lb(pi_lbn(n)/2,n) > 0

    cos_lb_pi2_pos1 : LEMMA n=1 => NOT cos_lb(pi_lbn(n)/2,n) > 0

    cos_lb_pi2_pos2 : LEMMA n=2 => NOT cos_lb(pi_lbn(n)/2,n) > 0

    cos_lb_pi2_pos : LEMMA
      n >= Cos_pos_n IMPLIES
      cos_lb(pi_lbn(n)/2,n) > 0

    % Approximation to guarantee sin_lb > 0
    Sin_pos_n : MACRO posnat = 11

    sin_term_pi_lb: LEMMA n >= Sin_pos_n IMPLIES
                          sin_term(pi_lbn(n+1))(2*n+2) < sin(pi_lbn(n+1))

    sin_lb_pi_not_pos: LEMMA
      FORALL (b9:below(11)):
      NOT sin_lb(pi_lbn(b9+1),b9) > 0

    sin_lb_pi_pos: LEMMA
      n >= Sin_pos_n IMPLIES
      sin_lb(pi_lbn(n+1),n) > 0

    pi_lb_est(n:nat): {rr:nnreal | rr < pi} =
      IF n < 12 THEN pi_lbn(n)-2/(n^3+1)
      ELSE pi_lbn(n) ENDIF

    pi_lb_est_le: LEMMA pi_lb_est(n) <= pi_lbn(n) AND pi_lb_est(n) <= pi

    sin_lb_pi_est_pos: LEMMA sin_lb(pi_lb_est(n+1),n) > 0

    sin_lb_pi_range_pos: LEMMA 
      px <= pi_lb_est(n+1) IMPLIES sin_lb(px,n) > 0

    % Monotonicity of cos_ub

    cos_ub_nn_strict_decreasing:
          LEMMA n>=1 IMPLIES 
  	strict_decreasing?(LAMBDA (x:{x:nnreal| x <=  pi_lb_est(n)}): cos_ub(x,n))

    cos_ub_np_strict_increasing:
          LEMMA n>=1 IMPLIES 
  	strict_increasing?(LAMBDA (x:{x:npreal| x >= -pi_lb_est(n)}): cos_ub(x,n))

    % Monotonicity of sin_lb and sin_ub

    sin_lb_increasing: LEMMA 
      strict_increasing?(LAMBDA (x:{x:real| -pi_lb_est(n)/2 <= x AND x <= pi_lb_est(n)/2}): sin_lb(x,n))

    sin_ub_increasing: LEMMA 
      strict_increasing?(LAMBDA (x:{x:real| -pi_lb_est(n)/2 <= x AND x <= pi_lb_est(n)/2}): sin_ub(x,n))

    sin_lb_nn_decreasing: LEMMA
      strict_decreasing?(LAMBDA (x:{x:real | pi/2 <= x AND x <= pi}): sin_lb(x,n))

    cos_term_pi_ub: LEMMA n >= Cos_pos_n IMPLIES
                          -cos_term(pi_ubn(n)/2)(2*n+1) < -cos(pi_ubn(n)/2)

    cos_ub_pi2_neg : LEMMA
      n >= Cos_pos_n IMPLIES
      cos_ub(pi_ubn(n)/2,n) < 0

    pi_ub_est(n:nat): {rr:nnreal | pi < rr AND rr < 3*pi/2} =
      IF n < 5 THEN pi_ubn(n)+1/(n+1)^4
      ELSE pi_ubn(n) ENDIF

    sin_ub_nn_decreasing: LEMMA n>=1 IMPLIES 
      strict_decreasing?(LAMBDA (x:{x:real | pi_ub_est(n)/2 <= x AND x <= pi_lb_est(n)}): sin_ub(x,n))

  END trig_approx

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

  % Subtype TCC generated (at line 40, column 35) for  (2 * n + 1)
      % expected type  {i: int | a /= 0 OR i >= 0}
  sin_term_TCC1: OBLIGATION
    FORALL (a: real, n: nat): a /= 0 OR (2 * n + 1) >= 0;

  % Subtype TCC generated (at line 59, column 54) for  (2 * n)
      % expected type  {i: int | a /= 0 OR i >= 0}
  cos_term_TCC1: OBLIGATION
    FORALL (a: real, n: nat): NOT n = 0 IMPLIES a /= 0 OR (2 * n) >= 0;

  % Assuming TCC generated (at line 24, column 4) for
      % analysis@derivatives[real]
      % generated from assumption derivatives.deriv_domain
  sin_term_deriv_TCC1: OBLIGATION deriv_domain?[real];

  % Assuming TCC generated (at line 26, column 4) for
      % analysis@derivatives[real]
      % generated from assumption derivatives.not_one_element
  sin_term_deriv_TCC2: OBLIGATION not_one_element?[real];

  % Subtype TCC generated (at line 82, column 67) for  n - 1
      % expected type  nat
  cos_term_deriv_TCC1: OBLIGATION
    FORALL (n: nat):
      derivable?[real](LAMBDA a: cos_term(a)(n)) IMPLIES
       NOT n = 0 IMPLIES n - 1 >= 0;

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

  % Subtype TCC generated (at line 118, column 68) for  n - 1
      % expected type  nat
  cos_approx_deriv_TCC1: OBLIGATION
    FORALL (n: nat):
      derivable?[real](LAMBDA a: cos_approx(a, n)) IMPLIES
       NOT n = 0 IMPLIES n - 1 >= 0;

  % Assuming TCC generated (at line 24, column 4) for
      % analysis@derivatives[nnreal]
      % generated from assumption derivatives.deriv_domain
  sin_lb_deriv_TCC1: OBLIGATION deriv_domain?[nnreal];

  % Assuming TCC generated (at line 26, column 4) for
      % analysis@derivatives[nnreal]
      % generated from assumption derivatives.not_one_element
  sin_lb_deriv_TCC2: OBLIGATION not_one_element?[nnreal];

  % Subtype TCC generated (at line 186, column 46) for  n - 1
      % expected type  nat
  cos_ub_deriv_TCC1: OBLIGATION
    FORALL (n: nat):
      derivable?[real](LAMBDA a: cos_ub(a, n)) IMPLIES
       (FORALL (a1): a1 < 0 AND NOT n = 0 IMPLIES n - 1 >= 0);

  % Subtype TCC generated (at line 186, column 66) for  n - 1
      % expected type  nat
  cos_ub_deriv_TCC2: OBLIGATION
    FORALL (n: nat):
      derivable?[real](LAMBDA a: cos_ub(a, n)) IMPLIES
       (FORALL (a1): NOT a1 < 0 AND NOT n = 0 IMPLIES n - 1 >= 0);

  % Subtype TCC generated (at line 231, column 34) for  3
      % expected type  {i: int | n /= 0 OR i >= 0}
  pi_lb_est_TCC1: OBLIGATION FORALL (n: nat): n < 12 IMPLIES n /= 0 OR 3 >= 0;

  % Subtype TCC generated (at line 231, column 19) for
      % pi_lbn(n) - 2 / (n ^ 3 + 1)
      % expected type  {rr: nnreal | rr < pi}
  pi_lb_est_TCC2: OBLIGATION
    FORALL (n: nat):
      n < 12 IMPLIES
       pi_lbn(n) - 2 / (n ^ 3 + 1) >= 0 AND pi_lbn(n) - 2 / (n ^ 3 + 1) < pi;

  % Subtype TCC generated (at line 232, column 9) for  pi_lbn(n)
      % expected type  {rr: nnreal | rr < pi}
  pi_lb_est_TCC3: OBLIGATION
    FORALL (n: nat): NOT n < 12 IMPLIES pi_lbn(n) < pi;

  % Subtype TCC generated (at line 270, column 36) for  4
      % expected type  {i: int | NOT 1 + n = 0 OR i >= 0}
  pi_ub_est_TCC1: OBLIGATION
    FORALL (n: nat): n < 5 IMPLIES NOT 1 + n = 0 OR 4 >= 0;

  % Subtype TCC generated (at line 270, column 18) for
      % pi_ubn(n) + 1 / (n + 1) ^ 4
      % expected type  {rr: nnreal | pi < rr AND rr < 3 * pi / 2}
  pi_ub_est_TCC2: OBLIGATION
    FORALL (n: nat):
      n < 5 IMPLIES
       pi < pi_ubn(n) + 1 / (n + 1) ^ 4 AND
        pi_ubn(n) + 1 / (n + 1) ^ 4 < 3 * pi / 2;

  % Subtype TCC generated (at line 271, column 9) for  pi_ubn(n)
      % expected type  {rr: nnreal | pi < rr AND rr < 3 * pi / 2}
  pi_ub_est_TCC3: OBLIGATION
    FORALL (n: nat):
      NOT n < 5 IMPLIES pi < pi_ubn(n) AND pi_ubn(n) < 3 * pi / 2;


body:
  law_cosines: THEORY
  BEGIN

  %   Version 1.2 27/10/03  Foundational Version David Lester

  %                                   (x2,y2)
  %                                      .
  %                                     / \
  %                                   /    \
  %                                 /       \
  %                               /          \
  %                      b      /             \
  %                           /                \    c
  %                         /                   \
  %                       /                      \
  %                     /                         \
  %                   /                            \
  %                 /                           ac  \
  %               /                                  \
  %               ------------------------------------ 
  %           (x0,y0)               a               (x1,y1)

    IMPORTING trig_basic, atan2

    x0,x1,x2,y0,y1,y2,ac : VAR real
    pz                   : VAR posreal

    sq_dist(x0,y0,x1,y1) : nonneg_real = sq(x0-x1)+sq(y0-y1)

    dist(x0,y0,x1,y1)    : nonneg_real = sqrt(sq_dist(x0,y0,x1,y1))

    distance_refl : LEMMA  dist(x0,y0,x0,y0) = 0

    distance_symm : LEMMA  dist(x0,y0,x1,y1) = dist(x1,y1,x0,y0)

    distance_trans: LEMMA  dist(x0,y0,x1,y1) = dist(x0+x2,y0+y2,x1+x2,y1+y2)

    distance_scale: LEMMA  pz*dist(x0,y0,x1,y1) = dist(pz*x0,pz*y0,pz*x1,pz*y1)

    distance_rot:   LEMMA  dist(x0,y0,x1,y1)
                             = dist(cos(ac)*x0-sin(ac)*y0, cos(ac)*y0+sin(ac)*x0,
                                    cos(ac)*x1-sin(ac)*y1, cos(ac)*y1+sin(ac)*x1)

    dot_product   : LEMMA
                       LET a = dist(x1,y1,x0,y0),
                           b = dist(x2,y2,x0,y0),
                           c = dist(x2,y2,x1,y1) IN
                       EXISTS (ac) : 
                           a*c*cos(ac) = ((x0-x1)*(x2-x1) + (y0-y1)*(y2-y1))

    Law_Cosines   : LEMMA
                       LET a = dist(x1,y1,x0,y0),
                           b = dist(x2,y2,x0,y0),
                           c = dist(x2,y2,x1,y1) IN
                           a*c*cos(ac) = ((x0-x1)*(x2-x1) + (y0-y1)*(y2-y1))
                       IMPLIES
                             sq(b) = sq(c) + sq(a) - 2*a*c*cos(ac)
                         
    triangle      : LEMMA  dist(x0,y0,x1,y1) <= 
                                dist(x2,y2,x1,y1) + dist(x2,y2,x0,y0)
   
  END law_cosines


body:
  trig: THEORY
  %------------------------------------------------------------------------
  %
  % A Pragmatic Nonfoundational Theory of Trigonometry
  %
  %       by Cesar Munoz
  %          Victor Carreno
  %          Ricky Butler
  %          Gilles Dowek
  %          Alfons Geser
  %          Ben Di Vito
  % 
  %      Version 1.0    3/27/01
  %
  %
  %------------------------------------------------------------------------

  BEGIN
     IMPORTING trig_basic,
               trig_values, 
               trig_ineq



  END trig


body:
  trig_full: THEORY
  %------------------------------------------------------------------------
  %
  % A Theory of Trigonometry
  %
  %       by Cesar Munoz
  %          Victor Carreno
  %          Ricky Butler
  %          Gilles Dowek
  %          Alfons Geser
  %          Ben Di Vito
  %          David Lester
  % 
  %------------------------------------------------------------------------

  BEGIN
     IMPORTING trig,

               trig_basic,    % basic properties 
               trig_values,   % values of functions for special arguments
               trig_ineq,     % trig inequalities
               trig_extra,    % sum and product, half-angle, reductions and zeros
               trig_approx,   % taylor series approximations to trig functions:
               tan_approx,    % Approximations for tangent
               atan_approx,   % Approximations for atan 
               law_cosines,   % law of cosines
               trig_degree,   % conversions to degrees
               trig_inverses, % inverse functions
               trig_rew,      % auto-rewrites
               asin,          % asin properties
               acos,          % acos properties
               atan,          % atan properties
               atan_values,   % atan for specific values
               atan2,         % two-argument arc tangent
               atan2_props,   % additional properties of atan2 and values
               jatan2,        % Java atan2

  % ---------------------- Foundational Development -----------------------

               sincos,        % continuity and differentiability of sin, cos
              
               sincos_phase,          % sin and cos from infinite series
               sincos,                % continuity, differentiality, and bounds
               sincos_quad,           % basic properties of sin cos
               tan_quad,              % definiton of tan from atan
               deriv_sincos

  END trig_full


body:
  top: THEORY
  %----------------------------------------------------------------------------
  %
  %    Vector Analysis Library
  %
  %    Some people will wonder why we did not exploit the more general notion of
  %    continuity in the topology library.  The main reason is that the vectors 
  %    library would then have to import a huge number of theories.  
  %
  %         Rick Butler        NASA Langley Research Center
  %         Anthony Narkawicz  NASA Langley Research Center
  %         Cesar Munoz        NASA Langley Research Center
  %
  %----------------------------------------------------------------------------
  BEGIN

       IMPORTING

  % ----- generic theories ----------------------------------------------------

  %    limit_real_vect,      % limit of functions over vectors
       limit_vect_real,      
       limit_vect,
  %    cont_real_vect,       % continuity of functions over vectors
  %    cont_vect_real,       
       cont_vect,
       metric_vect,
       deriv_sigma,
       deriv_dot_prod,
       deriv_real_vect,
       deriv_real_vect2,
       deriv_cont_2D,
       vect_metric_space,
       vect3_metric_space,
       vect3_Heine,

  % ----- specific theories ----------------------------------------------------
   
       limit_real_vect2,
  %    limit_real_vect3,
       limit_vect2_real,
       limit_vect3_real,
       limit_vect2_vect2,
       cont_real_vect2,
  %    cont_real_vect3,
       cont_vect2_real,
       cont_vect3_real,
       cont_vect2_vect2,
       vect2_cont_comp,
       vect2_cont_comp2,      %% handles [T1 -> T2] 
       vect2_cont_dot,
       vect_cont_2D,

       vect_deriv_2D,
       vect_chain_rule,
       four_vects_2D_continuity,
       vect2_metric_space,
       vect2_Heine,
       vect_vect_2D_continuity,

  % ------- trig functions: continuity and derivatives (axiomatic versions of trig_fnd)

       deriv_sincos_ax

  END top


body:
  deriv_sincos_ax[ T : TYPE FROM real ] : THEORY
  BEGIN

     ASSUMING
       IMPORTING analysis@deriv_domain

       connected_domain: ASSUMPTION connected?[T]

       not_one_element : ASSUMPTION not_one_element?[T]

     ENDASSUMING


     AUTO_REWRITE+ connected_domain
     AUTO_REWRITE+ not_one_element

     IMPORTING trig@trig_basic, analysis@derivatives

     a,b,t: VAR T
     k,alpha: VAR real


     sin_continuous: AXIOM
         continuous?[T](LAMBDA (x: T): k * sin(alpha * x))

     cos_continuous: AXIOM
         continuous?[T](LAMBDA (x: T): k * cos(alpha * x))

     sin_derivable: AXIOM
         derivable?[T](LAMBDA (x: T): k * sin(alpha * x))

     cos_derivable: AXIOM
         derivable?[T](LAMBDA (x: T): k * cos(alpha * x))

     deriv_sin: AXIOM alpha /= 0 IMPLIES
         deriv[T](LAMBDA (x:T): k*sin(alpha*x)) =  
              (LAMBDA (t: T): k*alpha*cos(alpha*t))
    
     deriv_cos: AXIOM alpha /= 0 IMPLIES
         deriv[T](LAMBDA (x:T): k*cos(alpha*x)) = 
              (LAMBDA (t: T): -k*alpha*sin(alpha*t))


  END deriv_sincos_ax

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

  % Assuming TCC generated (at line 24, column 4) for  analysis@derivatives[T]
      % generated from assumption derivatives.deriv_domain
  sin_derivable_TCC1: OBLIGATION deriv_domain?[T];

  % Assuming TCC generated (at line 26, column 4) for  analysis@derivatives[T]
      % generated from assumption derivatives.not_one_element
  sin_derivable_TCC2: OBLIGATION not_one_element?[T];

  % Subtype TCC generated (at line 36, column 16) for
      % LAMBDA (x: T): k * sin(alpha * x)
      % expected type  deriv_fun[T]
  deriv_sin_TCC1: OBLIGATION
    FORALL (alpha, k: real):
      alpha /= 0 IMPLIES derivable?[T](LAMBDA (x: T): k * sin(alpha * x));

  % Subtype TCC generated (at line 40, column 16) for
      % LAMBDA (x: T): k * cos(alpha * x)
      % expected type  deriv_fun[T]
  deriv_cos_TCC1: OBLIGATION
    FORALL (alpha, k: real):
      alpha /= 0 IMPLIES derivable?[T](LAMBDA (x: T): k * cos(alpha * x));


body:
  vect_vect_2D_continuity: THEORY

  %%% A theory of continuity for functions from [Vect2,Nz_vect2] into
  %%% both Vect2 and real

  BEGIN

    IMPORTING vectors@vectors_2D

    ffv,ggv,hhv : VAR [[Vect2,Nz_vect2]->Vect2]
    ffr,ggr,hhr : VAR [[Vect2,Nz_vect2]->real]
    s	      : VAR Vect2
    nzv	      : VAR Nz_vect2
    c	      : VAR real

    continuous_vvv?(ffv): bool =
      FORALL (epsil:posreal,s:Vect2,nzv:Nz_vect2): 
      EXISTS (ds, dv: posreal):
      FORALL (sp:Vect2,nzvp:Nz_vect2):
           norm(s - sp) < ds AND
           norm(nzv-nzvp) < dv
           IMPLIES
           norm(ffv(s, nzv) - ffv(sp,nzvp)) < epsil

    sum_vvv(ggv,hhv)(s,nzv): Vect2 = ggv(s,nzv)+hhv(s,nzv)

    diff_vvv(ggv,hhv)(s,nzv): Vect2 = ggv(s,nzv)-hhv(s,nzv)

    scal_vvv(c,hhv)(s,nzv): Vect2 = c*hhv(s,nzv)

    continuous_vvr?(ffr): bool =
      FORALL (epsil:posreal,s:Vect2,nzv:Nz_vect2): 
      EXISTS (ds, dv: posreal):
      FORALL (sp:Vect2,nzvp:Nz_vect2):
           norm(s - sp) < ds AND
           norm(nzv-nzvp) < dv
           IMPLIES
           abs(ffr(s, nzv) - ffr(sp,nzvp)) < epsil

    sum_vvr(ggr,hhr)(s,nzv): real = ggr(s,nzv)+hhr(s,nzv)

    diff_vvr(ggr,hhr)(s,nzv): real = ggr(s,nzv)-hhr(s,nzv)

    prod_vvr(ggr,hhr)(s,nzv): real = ggr(s,nzv)*hhr(s,nzv)

    max_vvr(ggr,hhr)(s,nzv): real = max(ggr(s,nzv),hhr(s,nzv))

    scal_vvr(c,hhr)(s,nzv): real = c*hhr(s,nzv)

    const_vvr(c)(s,nzv): real = c

    scal_vvr_vvv(ffr,ggv)(s,nzv): Vect2 = ffr(s,nzv)*ggv(s,nzv)

    dot_vvv(ffv,ggv)(s,nzv): real = ffv(s,nzv)*ggv(s,nzv)

    nzero_vvr?(ffr): bool = (FORALL (s,nzv): ffr(s,nzv)/=0)

    continuous_nz_vvr?(ffr): bool = continuous_vvr?(ffr) AND nzero_vvr?(ffr)

    ffvc,ggvc,hhvc: VAR (continuous_vvv?)
    ffrc,ggrc,hhrc: VAR (continuous_vvr?)
    ggnz		: VAR (nzero_vvr?)
    ggnzc		: VAR (continuous_nz_vvr?)

    div_vvr(ffr,ggnz)(s,nzv): real = ffr(s,nzv)/ggnz(s,nzv)

    norm_vvv(ffv)(s,nzv): nnreal = norm(ffv(s,nzv))



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

    sum_vvv_cont: LEMMA continuous_vvv?(sum_vvv(ffvc,ggvc))

    sum_vvr_cont: LEMMA continuous_vvr?(sum_vvr(ffrc,ggrc))

    diff_vvv_cont: LEMMA continuous_vvv?(diff_vvv(ffvc,ggvc))

    scal_vvv_cont: LEMMA continuous_vvv?(scal_vvv(c,ffvc))
    
    dot_vvv_cont: LEMMA continuous_vvr?(dot_vvv(ffvc,ggvc))

    prod_vvr_cont: LEMMA continuous_vvr?(prod_vvr(ffrc,ggrc))

    const_vvr_cont: LEMMA continuous_vvr?(const_vvr(c))

    scal_vvr_vvv_cont: LEMMA continuous_vvv?(scal_vvr_vvv(ffrc,ggvc))

    scal_vvr_cont: LEMMA continuous_vvr?(scal_vvr(c,ffrc))

    div_vvr_cont: LEMMA continuous_vvr?(div_vvr(ffrc,ggnzc))

    nzv_vvv_cont: LEMMA continuous_vvv?(LAMBDA (s,nzv): nzv)

    s_vvv_cont: LEMMA continuous_vvv?(LAMBDA (s,nzv): s)

    max_vvr_cont: LEMMA continuous_vvr?(max_vvr(ffrc,ggrc))

    norm_vvv_cont: LEMMA continuous_vvr?(norm_vvv(ffvc))




  END vect_vect_2D_continuity

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

  % Subtype TCC generated (at line 65, column 46) for  ggnz(s, nzv)
      % expected type  nznum
  div_vvr_TCC1: OBLIGATION
    FORALL (ggnz: (nzero_vvr?), s: Vect2, nzv: Nz_vect2): ggnz(s, nzv) /= 0;

  % Subtype TCC generated (at line 91, column 51) for  ggnzc
      % expected type  (nzero_vvr?)
  div_vvr_cont_TCC1: OBLIGATION
    FORALL (ggnzc: (continuous_nz_vvr?)): nzero_vvr?(ggnzc);


body:
  %------------------------------------------------------------------------------------------------
  %
  %       2-dimensional record-vectors form a metric space
  %
  %       Author: Anthony Narkawicz, NASA Langley
  %
  %       
  %       Version 1.0                     February 24, 2010
  %
  %------------------------------------------------------------------------------------------------


  vect2_metric_space: THEORY
  BEGIN

     IMPORTING vectors@distance_2D,analysis@metric_spaces[Vect2,dist]

     S: VAR set[Vect2]

     vect2_subset_metric_space     : THEOREM metric_space?[Vect2,dist](S)

     vect2_metric_space : COROLLARY metric_space?[Vect2,dist](fullset[Vect2])


  END vect2_metric_space

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

  % Assuming TCC generated (at line 16, column 33) for
      % analysis@metric_spaces[Vect2, dist]
      % generated from assumption metric_spaces.fullset_metric_space
  IMP_metric_spaces_TCC1: OBLIGATION
    metric_space?[Vect2, dist](fullset[Vect2]);


body:
  %------------------------------------------------------------------------------------------------
  %
  %       A Special Result On Continuous Functions R x R^2 -> R
  %
  %       Author: Anthony Narkawicz, NASA Langley
  %
  %       
  %       Version 1.0                     February 24, 2010
  %
  %------------------------------------------------------------------------------------------------


  vect2_Heine: THEORY
  BEGIN

     IMPORTING vect2_metric_space, 
               analysis@real_metric_space, 
               analysis@cross_metric_real_fun[real,real_dist,Vect2,dist], 
               analysis@continuity_ms[Vect2,dist,real,real_dist]

     f: VAR [[real,Vect2] -> real]

     curried_min_exists_2D: LEMMA FORALL (A: real, B: {x: real | A < x}):
      continuous?(f,fullset[[(closed_intv(A,B)),Vect2]])
       IMPLIES (FORALL (y: Vect2):  
          nonempty?[real]({r: real | EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):r = f(t, y)})
      AND below_bounded[real]({r: real | EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):r = f(t, y)})
      AND ext[real]({r: real | EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)): r = f(t, y)})
                (inf[real]({r: real | EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)): r = f(t, y)}))
      AND (EXISTS (tmin: (closed_intv(A,B))): FORALL (s: (closed_intv(A,B))): f(tmin,y) <= f(s,y)))

     curried_min_is_cont_2D: THEOREM FORALL (A: real, B: {x: real | A < x}): 
        continuous?(f,fullset[[(closed_intv(A,B)),Vect2]]) 
        IMPLIES
            LET unif_min_first(y: Vect2): real 
                = min({r: real | EXISTS (t: (closed_intv(A,B))): r = f(t,y)})
            IN continuous?(unif_min_first)

     curried_min_is_cont_2D_ed: THEOREM FORALL (A: real, B: {x: real | A < x}):
         (FORALL (x: (closed_intv(A,B)), y: Vect2, epsilon: posreal): 
            EXISTS (delta: posreal): 
               FORALL (z: (closed_intv(A,B)), w: Vect2): 
                 (real_dist(x,z) <= delta AND dist(y,w) <= delta) IMPLIES real_dist(f(x,y),f(z,w))<epsilon)
         IMPLIES
             LET unif_min_first(y: Vect2): real 
                 = min({r: real | EXISTS (t: (closed_intv(A,B))): r = f(t,y)})
             IN
                (FORALL (y: Vect2): FORALL (epsilon: posreal): 
                    EXISTS (delta: posreal): FORALL (q:Vect2):
                         dist(y,q) < delta IMPLIES real_dist(unif_min_first(y),unif_min_first(q)) < epsilon)


     % Uniform Continuity In The First Variable

     multiary_Heine_2D:   THEOREM FORALL (A: real, B: {x: real | A < x}):
        continuous?(f,fullset[[(closed_intv(A,B)),Vect2]]) 
        IMPLIES uniformly_continuous_in_first?(f,closed_intv(A,B),fullset[Vect2])


     multiary_Heine_2D_ed:   THEOREM FORALL (A: real, B: {x: real | A < x}):
       (FORALL (x: (closed_intv(A,B)), y: Vect2, epsilon: posreal): 
          EXISTS (delta: posreal): 
             FORALL (z: (closed_intv(A,B)), w: Vect2): (real_dist(x,z) <= delta AND dist(y,w) <= delta) 
                                                            IMPLIES real_dist(f(x,y),f(z,w))<epsilon)
       IMPLIES
          FORALL (y1: Vect2, epsilon: posreal): EXISTS (delta: posreal):
             FORALL (x1,x2: (closed_intv(A,B)), y2: Vect2): (real_dist(x1,x2) <= delta AND dist(y1,y2) <= delta) 
                IMPLIES real_dist(f(x1,y1),f(x2,y2))<epsilon

  END vect2_Heine

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

  % Assuming TCC generated (at line 18, column 13) for
      % analysis@cross_metric_real_fun[real, real_dist, Vect2, dist]
      % generated from assumption cross_metric_real_fun.fullset_metric_space1
  IMP_cross_metric_real_fun_TCC1: OBLIGATION
    metric_space?[real, real_dist](fullset[real]);

  % Assuming TCC generated (at line 18, column 13) for
      % analysis@cross_metric_real_fun[real, real_dist, Vect2, dist]
      % generated from assumption cross_metric_real_fun.fullset_metric_space2
  IMP_cross_metric_real_fun_TCC2: OBLIGATION
    metric_space?[Vect2, dist](fullset[Vect2]);

  % Subtype TCC generated (at line 24, column 42) for  B
      % expected type  {x: real | A <= x}
  curried_min_exists_2D_TCC1: OBLIGATION
    FORALL (A: real, B: {x: real | A < x}): A <= B;

  % Subtype TCC generated (at line 36, column 20) for
      % {r: real |
      %    EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)): r = f(t, y)}
      % expected type  min_set[real]
  curried_min_is_cont_2D_TCC1: OBLIGATION
    FORALL (f: [[real, Vect2] -> real], A: real, B: {x: real | A < x}):
      continuous?(f,
                  extend
                      [[real, Vect2],
                       [(LAMBDA (x: real): A <= x AND x <= B), Vect2], bool,
                       FALSE]
                      (fullset
                           [[(LAMBDA (x: real): A <= x AND x <= B), Vect2]]))
       IMPLIES
       (FORALL (y: Vect2):
          nonempty?[real]
              ({r: real |
                  EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                    r = f(t, y)})
           AND
           below_bounded[real]
               ({r: real |
                   EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                     r = f(t, y)})
            AND
            ext[real]
                ({r: real |
                    EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                      r = f(t, y)})
                (inf[real]
                     ({r: real |
                         EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                           r = f(t, y)})));

  % Subtype TCC generated (at line 46, column 21) for
      % {r: real |
      %    EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)): r = f(t, y)}
      % expected type  min_set[real]
  curried_min_is_cont_2D_ed_TCC1: OBLIGATION
    FORALL (f: [[real, Vect2] -> real], A: real, B: {x: real | A < x}):
      (FORALL (x: (LAMBDA (x: real): A <= x AND x <= B), y: Vect2,
               epsilon: posreal):
         EXISTS (delta: posreal):
           FORALL (z: (LAMBDA (x: real): A <= x AND x <= B), w: Vect2):
             (real_dist(x, z) <= delta AND dist(y, w) <= delta) IMPLIES
              real_dist(f(x, y), f(z, w)) < epsilon)
       IMPLIES
       (FORALL (y1: Vect2):
          nonempty?[real]
              ({r: real |
                  EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                    r = f(t, y1)})
           AND
           below_bounded[real]
               ({r: real |
                   EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                     r = f(t, y1)})
            AND
            ext[real]
                ({r: real |
                    EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                      r = f(t, y1)})
                (inf[real]
                     ({r: real |
                         EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                           r = f(t, y1)})));


body:
  four_vects_2D_continuity: THEORY

  %%% A theory of continuity for functions from [Vect2,Nz_vect2] into
  %%% both Vect2 and real

  BEGIN

    IMPORTING vectors@vectors_2D

    ffv,ggv,hhv : VAR [[Vect2,Vect2,Vect2,Vect2]->Vect2]
    ffr,ggr,hhr : VAR [[Vect2,Vect2,Vect2,Vect2]->real]
    so,vo,si,vi,
    nso,nvo,nsi,nvi : VAR Vect2
    nzv	      : VAR Nz_vect2
    c	      : VAR real

    continuous_vvv?(ffv): bool =
      FORALL (epsil:posreal,so,vo,si,vi): 
      EXISTS (dso,dvo,dsi,dvi: posreal):
      FORALL (nso,nvo,nsi,nvi):
           norm(so - nso) < dso AND
           norm(vo - nvo) < dvo AND
           norm(si - nsi) < dsi AND
           norm(vi - nvi) < dvi
           IMPLIES
           norm(ffv(so,vo,si,vi)-ffv(nso,nvo,nsi,nvi)) < epsil

    sum_vvv(ggv,hhv)(so,vo,si,vi): Vect2 = ggv(so,vo,si,vi)+hhv(so,vo,si,vi)

    diff_vvv(ggv,hhv)(so,vo,si,vi): Vect2 = ggv(so,vo,si,vi)-hhv(so,vo,si,vi)

    scal_vvv(c,hhv)(so,vo,si,vi): Vect2 = c*hhv(so,vo,si,vi)

    continuous_vvr?(ffr): bool =
      FORALL (epsil:posreal,so,vo,si,vi): 
      EXISTS (dso,dvo,dsi,dvi: posreal):
      FORALL (nso,nvo,nsi,nvi):
           norm(so - nso) < dso AND
           norm(vo - nvo) < dvo AND
           norm(si - nsi) < dsi AND
           norm(vi - nvi) < dvi
           IMPLIES
           abs(ffr(so,vo,si,vi)-ffr(nso,nvo,nsi,nvi)) < epsil

    sum_vvr(ggr,hhr)(so,vo,si,vi): real = ggr(so,vo,si,vi)+hhr(so,vo,si,vi)

    diff_vvr(ggr,hhr)(so,vo,si,vi): real = ggr(so,vo,si,vi)-hhr(so,vo,si,vi)

    prod_vvr(ggr,hhr)(so,vo,si,vi): real = ggr(so,vo,si,vi)*hhr(so,vo,si,vi)

    max_vvr(ggr,hhr)(so,vo,si,vi): real = max(ggr(so,vo,si,vi),hhr(so,vo,si,vi))

    scal_vvr(c,hhr)(so,vo,si,vi): real = c*hhr(so,vo,si,vi)

    const_vvr(c)(so,vo,si,vi): real = c

    scal_vvr_vvv(ffr,ggv)(so,vo,si,vi): Vect2 = ffr(so,vo,si,vi)*ggv(so,vo,si,vi)

    dot_vvv(ffv,ggv)(so,vo,si,vi): real = ffv(so,vo,si,vi)*ggv(so,vo,si,vi)

    nzero_vvr?(ffr): bool = (FORALL (so,vo,si,vi): ffr(so,vo,si,vi)/=0)

    continuous_nz_vvr?(ffr): bool = continuous_vvr?(ffr) AND nzero_vvr?(ffr)

    ffvc,ggvc,hhvc: VAR (continuous_vvv?)
    ffrc,ggrc,hhrc: VAR (continuous_vvr?)
    ggnz		: VAR (nzero_vvr?)
    ggnzc		: VAR (continuous_nz_vvr?)

    div_vvr(ffr,ggnz)(so,vo,si,vi): real = ffr(so,vo,si,vi)/ggnz(so,vo,si,vi)

    norm_vvv(ffv)(so,vo,si,vi): nnreal = norm(ffv(so,vo,si,vi))



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

    sum_vvv_cont: LEMMA continuous_vvv?(sum_vvv(ffvc,ggvc))

    sum_vvr_cont: LEMMA continuous_vvr?(sum_vvr(ffrc,ggrc))

    diff_vvv_cont: LEMMA continuous_vvv?(diff_vvv(ffvc,ggvc))

    scal_vvv_cont: LEMMA continuous_vvv?(scal_vvv(c,ffvc))
    
    dot_vvv_cont: LEMMA continuous_vvr?(dot_vvv(ffvc,ggvc))

    prod_vvr_cont: LEMMA continuous_vvr?(prod_vvr(ffrc,ggrc))

    const_vvr_cont: LEMMA continuous_vvr?(const_vvr(c))

    scal_vvr_vvv_cont: LEMMA continuous_vvv?(scal_vvr_vvv(ffrc,ggvc))

    scal_vvr_cont: LEMMA continuous_vvr?(scal_vvr(c,ffrc))

    div_vvr_cont: LEMMA continuous_vvr?(div_vvr(ffrc,ggnzc))

    input1_vvv_cont: LEMMA continuous_vvv?(LAMBDA (so,vo,si,vi): so)

    input2_vvv_cont: LEMMA continuous_vvv?(LAMBDA (so,vo,si,vi): vo)

    input3_vvv_cont: LEMMA continuous_vvv?(LAMBDA (so,vo,si,vi): si)

    input4_vvv_cont: LEMMA continuous_vvv?(LAMBDA (so,vo,si,vi): vi)

    max_vvr_cont: LEMMA continuous_vvr?(max_vvr(ffrc,ggrc))

    norm_vvv_cont: LEMMA continuous_vvr?(norm_vvv(ffvc))




  END four_vects_2D_continuity

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

  % Subtype TCC generated (at line 70, column 58) for  ggnz(so, vo, si, vi)
      % expected type  nznum
  div_vvr_TCC1: OBLIGATION
    FORALL (ggnz: (nzero_vvr?), so: Vect2, vo: Vect2, si: Vect2, vi: Vect2):
      ggnz(so, vo, si, vi) /= 0;

  % Subtype TCC generated (at line 96, column 51) for  ggnzc
      % expected type  (nzero_vvr?)
  div_vvr_cont_TCC1: OBLIGATION
    FORALL (ggnzc: (continuous_nz_vvr?)): nzero_vvr?(ggnzc);


body:
  vect_fun_ops_rv  [T: TYPE] : THEORY
  %------------------------------------------%
  %  Operations on functions : [ T -> Vect2]  %
  %------------------------------------------%
  BEGIN

     IMPORTING vectors@vectors_2D

     f, f1, f2: VAR [T -> Vect2]
     x : VAR T
     a,b : VAR real
     r: VAR [T -> real]
     v: VAR Vect2
     

     +(f1, f2) : MACRO [T -> Vect2]  = LAMBDA x : f1(x) + f2(x);
     -(f1)     : MACRO [T -> Vect2]  = LAMBDA x : -f1(x);
     -(f1, f2) : MACRO [T -> Vect2]  = LAMBDA x : f1(x) - f2(x);
     *(b,f1)   : MACRO [T -> Vect2]  = LAMBDA x : b*f1(x);            %% scalar product
     *(r,f)  : [T -> Vect2]          = LAMBDA (t:T): r(t)*f(t);
     *(f1,f2)  : MACRO [T -> real]   = LAMBDA x : f1(x)*f2(x);        %% dot product
   
     const_vfun(a) : MACRO [T -> Vect2] = (LAMBDA x : (a,a))
     const_vfun(v) : [T -> Vect2] = (LAMBDA x : v) ;

    %------------------
    %  Rewrite rules
    %------------------

    diff_function    : LEMMA f1 - f2 = f1 + (- f2)
    negneg_function  : LEMMA - (- f1) = f1

  END vect_fun_ops_rv


body:
  deriv_real_vect2 [ T : TYPE FROM real ] : THEORY
  BEGIN
    ASSUMING
      IMPORTING analysis@deriv_domain_def

       deriv_domain     : ASSUMPTION deriv_domain?[T]

       not_one_element  : ASSUMPTION not_one_element?[T]


    ENDASSUMING


    IMPORTING analysis@deriv_domain, analysis@derivatives[T],
              vectors@det_2D

    s,v : VAR Vect2
    a,r : VAR T

    derivable_rv?(V:[T->Vect2]): bool =
      derivable?(LAMBDA(a):V(a)`x) AND
      derivable?(LAMBDA(a):V(a)`y)

    differentiable_rv?(V:[T->Vect2]): MACRO bool = derivable_rv?(V)

    V : VAR (derivable_rv?)

    deriv_rv(V)(r) : Vect2 =
      (deriv(LAMBDA(a):V(a)`x,r),deriv(LAMBDA(a):V(a)`y,r))

  % ------- Properties of deriv

    deriv(V): [T -> Vect2] = (LAMBDA (r:T): deriv_rv(V)(r))

    AUTO_REWRITE- deriv_rv
    AUTO_REWRITE- deriv
    AUTO_REWRITE- derivable_rv?

    IMPORTING vect_fun_ops_rv

    f, f1, f2 : VAR (derivable_rv?)
    b,c : VAR real

    h: VAR deriv_fun[T]   %   h:[T -> real] AND derivable?(h)

    sum_derivable_rv   : LEMMA derivable_rv?(LAMBDA (x: T): f1(x) + f2(x))

    diff_derivable_rv  : LEMMA derivable_rv?(LAMBDA (x: T): f1(x) - f2(x))

    neg_derivable_rv   : LEMMA derivable_rv?(LAMBDA (x: T): -f(x))

    prod_derivable_rv  : LEMMA derivable_rv?(LAMBDA (x: T): h(x)*f(x))

    dot_derivable_rv   : LEMMA derivable?(LAMBDA (x: T): f1(x)*f2(x))

    sqv_derivable_rv   : LEMMA derivable?(LAMBDA (x: T): sqv(f(x)))


    const_derivable_rv : LEMMA derivable_rv?(LAMBDA (x: T): s) 

    scal_derivable_rv  : LEMMA derivable_rv?(LAMBDA (x: T): c * f(x))

    prod_id_derivable_rv: LEMMA derivable_rv?(LAMBDA (x: T): x * v)


    deriv_sum_vfun    : LEMMA deriv(LAMBDA (x: T): f1(x) + f2(x)) = deriv(f1) + deriv(f2)

    deriv_diff_vfun   : LEMMA deriv(LAMBDA (x: T): f1(x) - f2(x)) = deriv(f1) - deriv(f2)
   
    deriv_neg_vfun    : LEMMA deriv(LAMBDA (x:T): -f(x)) = -deriv(f)

    deriv_prod_vfun   : LEMMA deriv(LAMBDA (x: T): h(x) * f(x)) = deriv(h)*f + h*deriv(f)

    deriv_dot_vfun    : LEMMA deriv(LAMBDA (x: T): f1(x) * f2(x)) = deriv(f1)*f2 + f1*deriv(f2)

    deriv_sqv_vfun    : LEMMA 
       deriv(LAMBDA (x: T): sqv(f(x))) = (LAMBDA (x:T): 2*f(x)*deriv(f)(x)) 


    deriv_const_vfun  : LEMMA deriv(LAMBDA (x: T): s) = (LAMBDA (x:T): zero)

    deriv_scal_vfun   : LEMMA deriv(LAMBDA (x: T): c * f(x)) = c * deriv(f)

    deriv_prod_id_vfun: LEMMA deriv(LAMBDA (x: T): x * v) = (LAMBDA (x: T): v)


    d_sum_vfun   : LEMMA derivable_rv?(LAMBDA (x: T): f1(x) + f2(x)) AND
                         deriv(LAMBDA (x: T): f1(x) + f2(x)) = deriv(f1) + deriv(f2)

    d_diff_vfun  : LEMMA derivable_rv?(LAMBDA (x: T): f1(x) - f2(x)) AND 
                         deriv(LAMBDA (x: T): f1(x) - f2(x)) = deriv(f1) - deriv(f2)

    d_neg_vfun   : LEMMA derivable_rv?(LAMBDA (x: T): -f(x)) AND
                         deriv(LAMBDA (x:T): -f(x)) = -deriv(f)

    d_prod_vfun  : LEMMA derivable_rv?(LAMBDA (x: T): h(x)*f(x)) AND
                         deriv(LAMBDA (x: T): h(x) * f(x)) = deriv(h)*f + h*deriv(f)

    d_dot_vfun   : LEMMA derivable?(LAMBDA (x: T): f1(x)*f2(x)) AND
                         deriv(LAMBDA (x: T): f1(x) * f2(x)) = deriv(f1)*f2 + f1*deriv(f2)

    d_const_vfun : LEMMA derivable_rv?(LAMBDA (x: T): s) AND
                         deriv(LAMBDA (x: T): s) = (LAMBDA (x:T): zero)

    d_scal_vfun  : LEMMA derivable_rv?(LAMBDA (x: T): c * f(x)) AND
                         deriv(LAMBDA (x: T): c * f(x)) = c * deriv(f)



  END deriv_real_vect2

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

  % Assuming TCC generated (at line 14, column 35) for
      % analysis@derivatives[T]
      % generated from assumption derivatives.deriv_domain
  IMP_derivatives_TCC1: OBLIGATION deriv_domain?[T];

  % Assuming TCC generated (at line 14, column 35) for
      % analysis@derivatives[T]
      % generated from assumption derivatives.not_one_element
  IMP_derivatives_TCC2: OBLIGATION not_one_element?[T];

  % Subtype TCC generated (at line 29, column 28) for  r
      % expected type  {x_1 | derivable?(LAMBDA (a): V(a)`x, x_1)}
  deriv_rv_TCC1: OBLIGATION
    FORALL (V: (derivable_rv?), r: T): derivable?[T](LAMBDA (a): V(a)`x, r);

  % Subtype TCC generated (at line 29, column 54) for  r
      % expected type  {x | derivable?(LAMBDA (a): V(a)`y, x)}
  deriv_rv_TCC2: OBLIGATION
    FORALL (V: (derivable_rv?), r: T): derivable?[T](LAMBDA (a): V(a)`y, r);

  % Subtype TCC generated (at line 66, column 34) for
      % LAMBDA (x: T): f1(x) + f2(x)
      % expected type  (derivable_rv?)
  deriv_sum_vfun_TCC1: OBLIGATION
    FORALL (f1, f2: (derivable_rv?)):
      derivable_rv?(LAMBDA (x: T): f1(x) + f2(x));

  % Subtype TCC generated (at line 68, column 34) for
      % LAMBDA (x: T): f1(x) - f2(x)
      % expected type  (derivable_rv?)
  deriv_diff_vfun_TCC1: OBLIGATION
    FORALL (f1, f2: (derivable_rv?)):
      derivable_rv?(LAMBDA (x: T): f1(x) - f2(x));

  % Subtype TCC generated (at line 70, column 34) for  LAMBDA (x: T): -f(x)
      % expected type  (derivable_rv?)
  deriv_neg_vfun_TCC1: OBLIGATION
    FORALL (f: (derivable_rv?)): derivable_rv?(LAMBDA (x: T): -f(x));

  % Subtype TCC generated (at line 72, column 34) for
      % LAMBDA (x: T): h(x) * f(x)
      % expected type  (derivable_rv?)
  deriv_prod_vfun_TCC1: OBLIGATION
    FORALL (f: (derivable_rv?), h: deriv_fun[T]):
      derivable_rv?(LAMBDA (x: T): h(x) * f(x));

  % Subtype TCC generated (at line 74, column 34) for
      % LAMBDA (x: T): f1(x) * f2(x)
      % expected type  deriv_fun[T]
  deriv_dot_vfun_TCC1: OBLIGATION
    FORALL (f1, f2: (derivable_rv?)):
      derivable?[T](LAMBDA (x: T): f1(x) * f2(x));

  % Subtype TCC generated (at line 77, column 11) for
      % LAMBDA (x: T): sqv(f(x))
      % expected type  deriv_fun[T]
  deriv_sqv_vfun_TCC1: OBLIGATION
    FORALL (f: (derivable_rv?)): derivable?[T](LAMBDA (x: T): sqv(f(x)));

  % Subtype TCC generated (at line 80, column 34) for  LAMBDA (x: T): s
      % expected type  (derivable_rv?)
  deriv_const_vfun_TCC1: OBLIGATION
    FORALL (s: Vect2): derivable_rv?(LAMBDA (x: T): s);

  % Subtype TCC generated (at line 82, column 34) for  LAMBDA (x: T): c * f(x)
      % expected type  (derivable_rv?)
  deriv_scal_vfun_TCC1: OBLIGATION
    FORALL (c: real, f: (derivable_rv?)):
      derivable_rv?(LAMBDA (x: T): c * f(x));

  % Subtype TCC generated (at line 84, column 34) for  LAMBDA (x: T): x * v
      % expected type  (derivable_rv?)
  deriv_prod_id_vfun_TCC1: OBLIGATION
    FORALL (v: Vect2): derivable_rv?(LAMBDA (x: T): x * v);


body:
  vect_deriv_2D [ T : TYPE FROM real ] : THEORY
  BEGIN
    ASSUMING
        IMPORTING analysis@deriv_domain_def

       deriv_domain      : ASSUMPTION deriv_domain?[T]

       not_one_element  : ASSUMPTION not_one_element?[T]

    ENDASSUMING

    IMPORTING deriv_real_vect2[T]

    s   : VAR Vect2
    a,r: VAR T

    V : VAR (derivable_rv?)

    detsv(s,V)(r): real =
      det(s,V(r))

    detsv_diff : LEMMA
      derivable?(detsv(s,V))

    detsvp_deriv : LEMMA
      deriv(detsv(s,V))(r) = det(s,deriv_rv(V)(r))

    sqvdot_diff : LEMMA
      derivable?(LAMBDA(r):sqv(V(r)))

    sqvdot_deriv : LEMMA
      deriv(LAMBDA(r):sqv(V(r)))(r) = 2*V(r)*deriv_rv(V)(r)

  END vect_deriv_2D

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

  % Assuming TCC generated (at line 12, column 12) for  deriv_real_vect2[T]
      % generated from assumption deriv_real_vect2.deriv_domain
  IMP_deriv_real_vect2_TCC1: OBLIGATION deriv_domain?[T];

  % Assuming TCC generated (at line 12, column 12) for  deriv_real_vect2[T]
      % generated from assumption deriv_real_vect2.not_one_element
  IMP_deriv_real_vect2_TCC2: OBLIGATION not_one_element?[T];

  % Subtype TCC generated (at line 26, column 10) for  detsv(s, V)
      % expected type  deriv_fun[T]
  detsvp_deriv_TCC1: OBLIGATION
    FORALL (V: (derivable_rv?), s: Vect2): derivable?[T](detsv(s, V));

  % Subtype TCC generated (at line 32, column 10) for  LAMBDA (r): sqv(V(r))
      % expected type  deriv_fun[T]
  sqvdot_deriv_TCC1: OBLIGATION
    FORALL (V: (derivable_rv?)): derivable?[T](LAMBDA (r): sqv(V(r)));


body:
  vect_chain_rule [ T1, T2 : TYPE FROM real ] : THEORY
  BEGIN

    ASSUMING
      IMPORTING analysis@deriv_domain_def

      deriv_domain1    : ASSUMPTION deriv_domain?[T1]

      not_one_element1 : ASSUMPTION not_one_element?[T1]

      deriv_domain2    : ASSUMPTION deriv_domain?[T2]

      not_one_element2 : ASSUMPTION not_one_element?[T2]

    ENDASSUMING

    IMPORTING analysis@derivative_props, analysis@lim_of_composition, 
              vect_deriv_2D, analysis@chain_rule

    f: VAR [T1 -> T2]
    g : VAR [T2 -> Vect2]
    x : VAR T1
    DF, DG : VAR real

    composition_derivable_vfun : LEMMA derivable?(f) AND differentiable_rv?(g) 
                                         IMPLIES differentiable_rv?(g o f)

    ff : VAR { f | derivable?(f) }
    gg : VAR { g | differentiable_rv?(g) }

    IMPORTING vect_fun_ops_rv

    h: VAR [T1 -> Vect2]

    deriv_comp_vfun : LEMMA deriv(gg o ff) = deriv(ff)*(deriv(gg) o ff) 

  END vect_chain_rule

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

  % Assuming TCC generated (at line 14, column 12) for
      % analysis@derivatives[T1]
      % generated from assumption derivatives.deriv_domain
  composition_derivable_vfun_TCC1: OBLIGATION deriv_domain?[T1];

  % Assuming TCC generated (at line 14, column 12) for
      % analysis@derivatives[T1]
      % generated from assumption derivatives.not_one_element
  composition_derivable_vfun_TCC2: OBLIGATION not_one_element?[T1];

  % Assuming TCC generated (at line 12, column 12) for  deriv_real_vect2[T2]
      % generated from assumption deriv_real_vect2.deriv_domain
  composition_derivable_vfun_TCC3: OBLIGATION
    FORALL (f: [T1 -> T2]): derivable?(f) IMPLIES deriv_domain?[T2];

  % Assuming TCC generated (at line 12, column 12) for  deriv_real_vect2[T2]
      % generated from assumption deriv_real_vect2.not_one_element
  composition_derivable_vfun_TCC4: OBLIGATION
    FORALL (f: [T1 -> T2]): derivable?(f) IMPLIES not_one_element?[T2];

  % Assuming TCC generated (at line 12, column 12) for  deriv_real_vect2[T2]
      % generated from assumption deriv_real_vect2.deriv_domain
  gg_TCC1: OBLIGATION deriv_domain?[T2];

  % Assuming TCC generated (at line 12, column 12) for  deriv_real_vect2[T2]
      % generated from assumption deriv_real_vect2.not_one_element
  gg_TCC2: OBLIGATION not_one_element?[T2];

  % Subtype TCC generated (at line 35, column 32) for  gg o ff
      % expected type  (derivable_rv?)
  deriv_comp_vfun_TCC1: OBLIGATION
    FORALL (ff: {f | derivable?(f)}, gg: {g | derivable_rv?(g)}):
      derivable_rv?[T1](o[T1, T2, Vect2](gg, ff));


body:
  limit_real_vect2[ T : TYPE FROM real ]: THEORY
  BEGIN

    IMPORTING vectors@distance_2D, vect_fun_ops_rv[T],
              reals@abs_lems

    f, f1, f2: VAR [ T -> Vect2]
    g : VAR [T -> Vect2]
    e, epsilon, delta : VAR posreal
    a,b,x: VAR T
    l,l1,l2,b,c,y1,y2,v: VAR Vect2


  %   const_fun(v) : [T -> Vect2] = LAMBDA x : v ;

  %   +(f1, f2) : [T -> Vect2] = LAMBDA x : f1(x) + f2(x);
   
  %   -(f1)     : [T -> Vect2] = LAMBDA x : -f1(x);

  %   -(f1, f2) : [T -> Vect2] = LAMBDA x : f1(x) - f2(x);

  %    *(a, f2) : [T -> Vect2] = LAMBDA x : a * f2(x);   

  %%  *(f1, f2) : [real -> Vect2] = (LAMBDA x : f1(x) * f2(x));   %%% ???

    %---------------------------------------------------
    %  Convergence of f at a point a towards a limit l
    %---------------------------------------------------

    convergence(f, a, l) : bool = 
  %%        (FORALL e: EXISTS x: abs(x - a) < e) AND   % a has a ball containing T values
  	FORALL epsilon : EXISTS delta : 
  	    FORALL x: abs(x-a) < delta        
                   IMPLIES norm(f(x) - l) < epsilon

    cv_unique    : LEMMA convergence(f, a, l1) AND convergence(f, a, l2)
                        IMPLIES l1 = l2

    cv_in_domain : LEMMA convergence(f, x, l) IMPLIES l = f(x)

    %-------------------------------------------
    %  convergence and operations on functions
    %-------------------------------------------

    cv_sum   : LEMMA convergence(f1, a, l1) AND convergence(f2, a, l2)
                       IMPLIES convergence(f1 + f2, a, l1 + l2)

    cv_neg   : LEMMA convergence(f, a, l)
                       IMPLIES convergence(- f, a, - l)

    cv_diff  : LEMMA convergence(f1, a, l1) AND convergence(f2, a, l2)
                       IMPLIES convergence(f1 - f2, a, l1 - l2)

    cv_const : LEMMA convergence(const_vfun(b), a, b)


    cv_scal  : LEMMA convergence(f, a, l) 
                        IMPLIES convergence(b * f, a, b * l)

    %-------------------------
    %  f is convergent at a    
    %-------------------------

    convergent?(f, a) : bool = EXISTS l : convergence(f, a, l)

    lim(f, (x0 : {a | convergent?(f, a)})) : Vect2 =  
          choose(LAMBDA l: convergence(f, x0, l))

    lim_fun_lemma   : LEMMA FORALL f, (x0 : {a | convergent?(f, a)}) :
                            convergence(f, x0, lim(f, x0))

    lim_fun_def     : LEMMA FORALL f, l, (x0 : {a | convergent?(f, a)}) :
                               lim(f, x0) = l IFF convergence(f, x0, l)

    convergence_equiv    : LEMMA convergence(f, a, l) IFF 
                                    convergent?(f, a) AND lim(f, a) = l
          
    convergent_in_domain : LEMMA convergent?(f, x) IFF convergence(f, x, f(x))
          
    lim_in_domain        : LEMMA convergent?(f, x) IMPLIES lim(f, x) = f(x)
          

    %------------------------------------------
    %  Operations preserving convergence at a 
    %------------------------------------------

    sum_fun_convergent  : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 + f2, a)

    neg_fun_convergent : LEMMA convergent?(f, a) IMPLIES convergent?(- f, a)
          
    diff_fun_convergent : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 - f2, a)

    const_fun_convergent: LEMMA convergent?(const_vfun(b), a)
          

    %----------------------------
    %  Same things with lim(a)
    %----------------------------

    lim_sum_fun      : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 + f2, a) = lim(f1, a) + lim(f2, a)

    lim_neg_fun : LEMMA convergent?(f, a) 
                               IMPLIES lim(- f, a) = - lim(f, a)
          
    lim_diff_fun     : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 - f2, a) = lim(f1, a) - lim(f2, a)

  %   %-----------------------------
  %   %  Limit preserve order
  %   %-----------------------------

  %   convergence_order : LEMMA
  % 	FORALL f1, f2, a, l1, l2 :
  % 		convergence(f1, a, l1)
  % 	    AND convergence(f2, a, l2)
  % 	    AND (FORALL x : f1(x) <= f2(x))
  % 	IMPLIES l1 <= l2
    

  %   %-------------------------------------------
  %   %  Bounds on function are bounds on limits
  %   %-------------------------------------------

  %   convergence_lower_bound : COROLLARY
  % 	FORALL f, b, a, l :
  % 		convergence(f, a, l)
  % 	    AND (FORALL x : b <= f(x))
  % 	IMPLIES b <= l

  %   convergence_upper_bound : COROLLARY
  % 	FORALL f, b, a, l :
  % 		convergence(f, a, l)
  % 	    AND (FORALL x : f(x) <= b)
  % 	IMPLIES l <= b


  %   %--------------------
  %   %  Bounds on limits
  %   %--------------------

  %   lim_le1 : LEMMA
  %         convergent?(f, a) AND (FORALL x : f(x) <= b) IMPLIES lim(f, a) <= b

  %   lim_ge1 : LEMMA
  %         convergent?(f, a) AND (FORALL x : f(x) >= b) IMPLIES lim(f, a) >= b
    
  %   lim_order1 : LEMMA convergent?(f1, a) AND convergent?(f2, a)
  %                      AND (FORALL x : f1(x) <= f2(x)) 
  %                          IMPLIES lim(f1, a) <= lim(f2, a)

  END limit_real_vect2

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

  % Subtype TCC generated (at line 67, column 15) for
      % LAMBDA l: convergence(f, x0, l)
      % expected type  p: (nonempty?[Vect2])
  lim_TCC1: OBLIGATION
    FORALL (f: [T -> Vect2], (x0: {a | convergent?(f, a)})):
      nonempty?[Vect2](LAMBDA l: convergence(f, x0, l));

  % Subtype TCC generated (at line 103, column 50) for  a
      % expected type  {a | convergent?(LAMBDA (x: T): f1(x) + f2(x), a)}
  lim_sum_fun_TCC1: OBLIGATION
    FORALL (a: T, f1, f2: [T -> Vect2]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(LAMBDA (x: T): f1(x) + f2(x), a);

  % Subtype TCC generated (at line 106, column 46) for  a
      % expected type  {a | convergent?(LAMBDA (x: T): -f(x), a)}
  lim_neg_fun_TCC1: OBLIGATION
    FORALL (a: T, f: [T -> Vect2]):
      convergent?(f, a) IMPLIES convergent?(LAMBDA (x: T): -f(x), a);

  % Subtype TCC generated (at line 109, column 50) for  a
      % expected type  {a | convergent?(LAMBDA (x: T): f1(x) - f2(x), a)}
  lim_diff_fun_TCC1: OBLIGATION
    FORALL (a: T, f1, f2: [T -> Vect2]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(LAMBDA (x: T): f1(x) - f2(x), a);


body:
  cont_real_vect2[T : TYPE FROM real]: THEORY
  %------------------------------------------------------------------------------
  %  Continuous functions [T -> Vect2]   
  %
  %  Author: Rick Butler     NASA Langley Research Center  2/1/2009
  %
  %------------------------------------------------------------------------------
  BEGIN

    IMPORTING limit_real_vect2[T], analysis@continuous_functions[T],
              analysis@real_fun_supinf,
              reals@abs_lems, 
              analysis@epsilon_lemmas

              

    f, f1, f2      : VAR [T -> Vect2]
    g              : VAR [T -> Nz_vect2]
    u              : VAR Vect2
    a, b, x, x0    : VAR T
    epsilon, delta : VAR posreal
    n              : VAR nat
    hh             : VAR [T -> real]
   
    %--------------------
    %  Continuity at x0    
    %--------------------

  %%  continuous_rv?(f, x0) : bool = convergence(f, x0, f(x0))

    continuous_rv?(f, x0) : bool = 
  	FORALL epsilon : EXISTS delta : 
  	    FORALL x: abs(x-x0) < delta        
                   IMPLIES norm(f(x) - f(x0)) < epsilon

    continuous_rv?(f): bool = FORALL x0: continuous_rv?(f, x0)

    continuous_rv_on?(f:[T->Vect2], E: set[T]) : bool = 
        FORALL (x:(E)): continuous_rv?(f,x) 

    continuity_def : LEMMA
          continuous_rv?(f, x0) IFF convergence(f, x0, f(x0))


    continuity_def2 : LEMMA
          continuous_rv?(f, x0) IFF convergent?(f, x0)



    fx(f): MACRO [T-> real] =  (LAMBDA (t: T): f(t)`x)
    fy(f): MACRO [T-> real] =  (LAMBDA (t: T): f(t)`y)

    continuous_iff_comps: LEMMA continuous_rv?(f,a) IFF
                              continuous?(fx(f),a) AND continuous?(fy(f),a)
             


    cont_rv_iff_comps: LEMMA continuous_rv?(f) IFF
                              continuous?(fx(f)) AND continuous?(fy(f))
             


    %------------------------------------------
    %  Operations preserving continuity at x0 
    %------------------------------------------

    sum_continuous_rv  : LEMMA continuous_rv?(f1, x0) AND continuous_rv?(f2, x0)
                             IMPLIES continuous_rv?(f1 + f2, x0)

    diff_continuous_rv : LEMMA continuous_rv?(f1, x0) AND continuous_rv?(f2, x0)
                             IMPLIES continuous_rv?(f1 - f2, x0)

    const_continuous_rv: LEMMA continuous_rv?(LAMBDA x: u, x0)

    scal_continuous_rv : LEMMA continuous_rv?(f, x0) IMPLIES continuous_rv?(a * f, x0)

    prod_continuous_rv : LEMMA continuous?(hh,x0) AND                               
        continuous_rv?(f,x0) IMPLIES continuous_rv?(hh * f,x0)



    neg_continuous_rv  : LEMMA continuous_rv?(f, x0) IMPLIES continuous_rv?(- f, x0)

    %---------------------------------
    %  Continuity of f in its domain
    %---------------------------------


    sum_cont_rv_fun   : LEMMA continuous_rv?(f1) AND continuous_rv?(f2)
                             IMPLIES continuous_rv?(f1 + f2)
  	
    diff_cont_rv_fun  : LEMMA continuous_rv?(f1) AND continuous_rv?(f2)
                             IMPLIES continuous_rv?(f1 - f2)

    const_cont_rv_fun : LEMMA continuous_rv?(LAMBDA x: u)

    const_vfun_cont_rv: LEMMA continuous_rv?(const_vfun(u))

    scal_cont_rv_fun  : LEMMA continuous_rv?(f) IMPLIES continuous_rv?(a * f)

    prod_cont_rv_fun  : LEMMA continuous?(hh) AND                               
        continuous_rv?(f) IMPLIES continuous_rv?(hh * f)


    neg_cont_rv_fun  : LEMMA continuous_rv?(f) IMPLIES continuous_rv?(-f)


    %--- Properties ---%

    continuous_rv_fun: TYPE+ = { f | continuous_rv?(f) }

    nz_continuous_rv_fun: TYPE = { g | continuous_rv?(g) }

    h, h1, h2: VAR continuous_rv_fun
    h3: VAR nz_continuous_rv_fun

    sum_fun_continuous_rv : JUDGEMENT  +(h1, h2) HAS_TYPE continuous_rv_fun

    diff_fun_continuous_rv: JUDGEMENT  -(h1, h2) HAS_TYPE continuous_rv_fun

    const_fun_continuous_rv: JUDGEMENT const_vfun(u) HAS_TYPE continuous_rv_fun

    neg_fun_continuous_rv : JUDGEMENT -(h) HAS_TYPE continuous_rv_fun


  END cont_real_vect2

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

  % Existence TCC generated (at line 110, column 2) for
      % continuous_rv_fun: TYPE+ = {f | continuous_rv?(f)}
  continuous_rv_fun_TCC1: OBLIGATION
    EXISTS (x: {f | continuous_rv?(f)}): TRUE;

  % Judgement subtype TCC generated (at line 16, column 37) for
      % LAMBDA (x: T): h1(x) + h2(x)
      % expected type  continuous_rv_fun
  sum_fun_continuous_rv: OBLIGATION
    FORALL (h1, h2): continuous_rv?(LAMBDA (x: T): h1(x) + h2(x));

  % Judgement subtype TCC generated (at line 18, column 37) for
      % LAMBDA (x: T): h1(x) - h2(x)
      % expected type  continuous_rv_fun
  diff_fun_continuous_rv: OBLIGATION
    FORALL (h1, h2): continuous_rv?(LAMBDA (x: T): h1(x) - h2(x));

  % Judgement subtype TCC generated (at line 121, column 37) for  const_vfun(u)
      % expected type  continuous_rv_fun
  const_fun_continuous_rv: OBLIGATION
    FORALL (u): continuous_rv?(const_vfun[T](u));

  % Judgement subtype TCC generated (at line 17, column 37) for
      % LAMBDA (x: T): -h(x)
      % expected type  continuous_rv_fun
  neg_fun_continuous_rv: OBLIGATION
    FORALL (h): continuous_rv?(LAMBDA (x: T): -h(x));


body:
  limit_vect2_vect2: THEORY
  BEGIN

    IMPORTING vectors@vect2_fun_ops, 
              reals@abs_lems, 
              analysis@epsilon_lemmas

    f, f1, f2: VAR [ Vect2 -> Vect2]
    g : VAR [Vect2 -> nzreal]
    epsilon, delta : VAR posreal
    a,x,v: VAR Vect2
    l,l1,l2,b,c,y1,y2: VAR Vect2


    const_fun(v) : [Vect2 -> Vect2] = LAMBDA x : v ;

    +(f1, f2) : [Vect2 -> Vect2] = LAMBDA x : f1(x) + f2(x);
   
    -(f1)     : [Vect2 -> Vect2] = LAMBDA x : -f1(x);

    -(f1, f2) : [Vect2 -> Vect2] = LAMBDA x : f1(x) - f2(x);

  %%%  *(f1, f2) : [Vect2 -> Vect2] = LAMBDA x : f1(x) * f2(x);  


    %---------------------------------------------------
    %  Convergence of f at a point a towards a limit l
    %---------------------------------------------------

    convergence(f, a, l) : bool = 
  	FORALL epsilon : EXISTS delta : 
  	    FORALL x: norm(x-a) < delta        
                   IMPLIES norm(f(x) - l) < epsilon

    cv_unique    : LEMMA convergence(f, a, l1) AND convergence(f, a, l2)
                        IMPLIES l1 = l2

    cv_in_domain : LEMMA convergence(f, x, l) IMPLIES l = f(x)

    %-------------------------------------------
    %  convergence and operations on functions
    %-------------------------------------------

    cv_sum   : LEMMA convergence(f1, a, l1) AND convergence(f2, a, l2)
                       IMPLIES convergence(f1 + f2, a, l1 + l2)

    cv_neg   : LEMMA convergence(f, a, l)
                       IMPLIES convergence(- f, a, - l)

    cv_diff  : LEMMA convergence(f1, a, l1) AND convergence(f2, a, l2)
                       IMPLIES convergence(f1 - f2, a, l1 - l2)


  %   cv_prod  : LEMMA convergence(f1, a, l1) AND convergence(f2, a, l2)
  %                      IMPLIES convergence(f1 * f2, a, l1 * l2)

    cv_const : LEMMA convergence(const_fun(b), v, b)

  %   cv_scal  : LEMMA convergence(f, a, l)
  %                      IMPLIES convergence(b * f, a, b * l)

    %-------------------------
    %  f is convergent at a    
    %-------------------------

    convergent?(f, a) : bool = EXISTS l : convergence(f, a, l)

    lim(f, (x0 : {a | convergent?(f, a)})) : Vect2 =  
          choose(LAMBDA l : convergence(f, x0, l))

    lim_fun_lemma   : LEMMA FORALL f, (x0 : {a | convergent?(f, a)}) :
                            convergence(f, x0, lim(f, x0))

    lim_fun_def     : LEMMA FORALL f, l, (x0 : {a | convergent?(f, a)}) :
                               lim(f, x0) = l IFF convergence(f, x0, l)

    convergence_equiv    : LEMMA convergence(f, a, l) IFF 
                                    convergent?(f, a) AND lim(f, a) = l
          
    convergent_in_domain : LEMMA convergent?(f, x) IFF convergence(f, x, f(x))
          
    lim_in_domain        : LEMMA convergent?(f, x) IMPLIES lim(f, x) = f(x)
          

    %------------------------------------------
    %  Operations preserving convergence at a 
    %------------------------------------------

    sum_fun_convergent  : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 + f2, a)

    neg_fun_convergent : LEMMA convergent?(f, a) IMPLIES convergent?(- f, a)
          
    diff_fun_convergent : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 - f2, a)

  %   prod_fun_convergent : LEMMA convergent?(f1, a) AND convergent?(f2, a)
  %                                 IMPLIES convergent?(f1 * f2, a)

    const_fun_convergent: LEMMA convergent?(const_fun(b), v)
          
  %  scal_fun_convergent : LEMMA convergent?(f, a) IMPLIES convergent?(b * f, a)
          
    %----------------------------
    %  Same things with lim(a)
    %----------------------------

    lim_sum_fun      : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 + f2, a) = lim(f1, a) + lim(f2, a)

    lim_neg_fun : LEMMA convergent?(f, a) 
                               IMPLIES lim(- f, a) = - lim(f, a)
          
    lim_diff_fun     : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 - f2, a) = lim(f1, a) - lim(f2, a)

  %   lim_prod_fun     : LEMMA convergent?(f1, a) AND convergent?(f2, a)
  %                              IMPLIES lim(f1 * f2, a) = lim(f1, a) * lim(f2, a)

    lim_const_fun    : LEMMA lim(const_fun(b), v) = b

  %   lim_scal_fun     : LEMMA convergent?(f, a) 
  %                              IMPLIES lim(b * f, a) = b * lim(f, a)
          
  %   %-----------------------------
  %   %  Limit preserve order
  %   %-----------------------------

  %   convergence_order : LEMMA
  % 	FORALL f1, f2, a, l1, l2 :
  % 		convergence(f1, a, l1)
  % 	    AND convergence(f2, a, l2)
  % 	    AND (FORALL x : f1(x) <= f2(x))
  % 	IMPLIES l1 <= l2
    

  %   %-------------------------------------------
  %   %  Bounds on function are bounds on limits
  %   %-------------------------------------------

  %   convergence_lower_bound : COROLLARY
  % 	FORALL f, b, a, l :
  % 		convergence(f, a, l)
  % 	    AND (FORALL x : b <= f(x))
  % 	IMPLIES b <= l

  %   convergence_upper_bound : COROLLARY
  % 	FORALL f, b, a, l :
  % 		convergence(f, a, l)
  % 	    AND (FORALL x : f(x) <= b)
  % 	IMPLIES l <= b


  %   %--------------------
  %   %  Bounds on limits
  %   %--------------------

  %   lim_le1 : LEMMA
  %         convergent?(f, a) AND (FORALL x : f(x) <= b) IMPLIES lim(f, a) <= b

  %   lim_ge1 : LEMMA
  %         convergent?(f, a) AND (FORALL x : f(x) >= b) IMPLIES lim(f, a) >= b
    
  %   lim_order1 : LEMMA convergent?(f1, a) AND convergent?(f2, a)
  %                      AND (FORALL x : f1(x) <= f2(x)) 
  %                          IMPLIES lim(f1, a) <= lim(f2, a)

  END limit_vect2_vect2

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

  % Subtype TCC generated (at line 69, column 15) for
      % LAMBDA l: convergence(f, x0, l)
      % expected type  p: (nonempty?[Vect2])
  lim_TCC1: OBLIGATION
    FORALL (f: [Vect2 -> Vect2], (x0: {a | convergent?(f, a)})):
      nonempty?[Vect2](LAMBDA l: convergence(f, x0, l));

  % Subtype TCC generated (at line 109, column 50) for  a
      % expected type  {a | convergent?(f1 + f2, a)}
  lim_sum_fun_TCC1: OBLIGATION
    FORALL (a: Vect2, f1, f2: [Vect2 -> Vect2]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(f1 + f2, a);

  % Subtype TCC generated (at line 112, column 46) for  a
      % expected type  {a | convergent?(-f, a)}
  lim_neg_fun_TCC1: OBLIGATION
    FORALL (a: Vect2, f: [Vect2 -> Vect2]):
      convergent?(f, a) IMPLIES convergent?(-f, a);

  % Subtype TCC generated (at line 115, column 50) for  a
      % expected type  {a | convergent?(f1 - f2, a)}
  lim_diff_fun_TCC1: OBLIGATION
    FORALL (a: Vect2, f1, f2: [Vect2 -> Vect2]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(f1 - f2, a);

  % Subtype TCC generated (at line 120, column 45) for  v
      % expected type  {a | convergent?(const_fun(b), a)}
  lim_const_fun_TCC1: OBLIGATION
    FORALL (b, v: Vect2): convergent?(const_fun(b), v);


body:
  cont_vect2_vect2: THEORY
  %------------------------------------------------------------------------------
  %  Continuous functions [ Vect2 -> real]   
  %
  %  Author: Rick Butler     NASA Langley Research Center  2/1/2009
  %
  %------------------------------------------------------------------------------
  BEGIN

    IMPORTING limit_vect2_vect2   

    f, f1, f2      : VAR [Vect2 -> Vect2]
    g              : VAR [Vect2 -> Nz_vect2]
    u              : VAR Vect2
    x, x0          : VAR Vect2
    epsilon, delta : VAR posreal
    n              : VAR nat
   
    %--------------------
    %  Continuity at x0    
    %--------------------

    continuous_vv?(f, x0) : bool = 
  	FORALL epsilon : EXISTS delta : 
  	    FORALL x: norm(x-x0) < delta        
                   IMPLIES norm(f(x) - f(x0)) < epsilon

    continuity_def : LEMMA
          continuous_vv?(f, x0) IFF convergence(f, x0, f(x0))

    continuity_def2 : LEMMA
          continuous_vv?(f, x0) IFF convergent?(f, x0)


    %------------------------------------------
    %  Operations preserving continuity at x0 
    %------------------------------------------

    sum_continuous_vv  : LEMMA continuous_vv?(f1, x0) AND continuous_vv?(f2, x0)
                             IMPLIES continuous_vv?(f1 + f2, x0)

    diff_continuous_vv : LEMMA continuous_vv?(f1, x0) AND continuous_vv?(f2, x0)
                             IMPLIES continuous_vv?(f1 - f2, x0)

    const_continuous_vv: LEMMA continuous_vv?(const_fun(u), x0)

    identity_continuous_vv: LEMMA continuous_vv?((LAMBDA(x):x),x0)

    neg_continuous_vv  : LEMMA continuous_vv?(f, x0) IMPLIES continuous_vv?(- f, x0)

    %---------------------------------
    %  Continuity of f in its domain
    %---------------------------------

    continuous_vv?(f): bool = FORALL x0: continuous_vv?(f, x0)

    sum_cont_vv_fun  : LEMMA continuous_vv?(f1) AND continuous_vv?(f2)
                             IMPLIES continuous_vv?(f1 + f2)

    diff_cont_vv_fun : LEMMA continuous_vv?(f1) AND continuous_vv?(f2)
                             IMPLIES continuous_vv?(f1 - f2)

    const_cont_vv_fun: LEMMA continuous_vv?(const_fun(u))

    neg_cont_vv_fun  : LEMMA continuous_vv?(f) IMPLIES continuous_vv?(-f)

    id_cont_vv_fun   : LEMMA continuous_vv?((LAMBDA(x):x))


    %--- Properties ---%

    continuous_vv_fun: TYPE+ = { f | continuous_vv?(f) }

    nz_continuous_vv_fun: TYPE = { g | continuous_vv?(g) }

    h, h1, h2: VAR continuous_vv_fun
    h3: VAR nz_continuous_vv_fun

    sum_fun_continuous_vv : JUDGEMENT  +(h1, h2) HAS_TYPE continuous_vv_fun

    diff_fun_continuous_vv: JUDGEMENT  -(h1, h2) HAS_TYPE continuous_vv_fun

    const_fun_continuous_vv: JUDGEMENT const_fun(u) HAS_TYPE continuous_vv_fun

    neg_fun_continuous_vv : JUDGEMENT -(h) HAS_TYPE continuous_vv_fun



  END cont_vect2_vect2

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

  % Existence TCC generated (at line 72, column 2) for
      % continuous_vv_fun: TYPE+ = {f | continuous_vv?(f)}
  continuous_vv_fun_TCC1: OBLIGATION
    EXISTS (x: {f | continuous_vv?(f)}): TRUE;

  % Judgement subtype TCC generated (at line 79, column 37) for  h1 + h2
      % expected type  continuous_vv_fun
  sum_fun_continuous_vv: OBLIGATION FORALL (h1, h2): continuous_vv?(h1 + h2);

  % Judgement subtype TCC generated (at line 81, column 37) for  h1 - h2
      % expected type  continuous_vv_fun
  diff_fun_continuous_vv: OBLIGATION FORALL (h1, h2): continuous_vv?(h1 - h2);

  % Judgement subtype TCC generated (at line 83, column 37) for  const_fun(u)
      % expected type  continuous_vv_fun
  const_fun_continuous_vv: OBLIGATION
    FORALL (u): continuous_vv?(const_fun(u));

  % Judgement subtype TCC generated (at line 85, column 36) for  -h
      % expected type  continuous_vv_fun
  neg_fun_continuous_vv: OBLIGATION FORALL (h): continuous_vv?(-h);


body:
  limit_vect2_real: THEORY
  BEGIN

    IMPORTING vectors@vect2_fun_ops, 
              reals@abs_lems, 
              analysis@epsilon_lemmas

    f, f1, f2: VAR [ Vect2 -> real]
    g : VAR [Vect2 -> nzreal]
    epsilon, delta : VAR posreal
    a,x,v: VAR Vect2
    l,l1,l2,b,c,y1,y2: VAR real

    %---------------------------------------------------
    %  Convergence of f at a point a towards a limit l
    %---------------------------------------------------

    convergence(f, a, l) : bool = 
  	FORALL epsilon : EXISTS delta : 
  	    FORALL x: %%% 0 < norm(x-a) AND
                        norm(x-a) < delta          %% AND x in dom(f)
                   IMPLIES abs(f(x) - l) < epsilon

    cv_unique    : LEMMA convergence(f, a, l1) AND convergence(f, a, l2)
                        IMPLIES l1 = l2

    cv_in_domain : LEMMA convergence(f, x, l) IMPLIES l = f(x)

    %-------------------------------------------
    %  convergence and operations on functions
    %-------------------------------------------

    cv_sum   : LEMMA convergence(f1, a, l1) AND convergence(f2, a, l2)
                       IMPLIES convergence(f1 + f2, a, l1 + l2)

    cv_neg   : LEMMA convergence(f, a, l)
                       IMPLIES convergence(- f, a, - l)

    cv_diff  : LEMMA convergence(f1, a, l1) AND convergence(f2, a, l2)
                       IMPLIES convergence(f1 - f2, a, l1 - l2)


    cv_prod  : LEMMA convergence(f1, a, l1) AND convergence(f2, a, l2)
                       IMPLIES convergence(f1 * f2, a, l1 * l2)

    cv_const : LEMMA convergence(const_fun(b), v, b)

    cv_scal  : LEMMA convergence(f, a, l)
                       IMPLIES convergence(b * f, a, b * l)


    cv_inv   : LEMMA convergence(g, a, l) AND l /= 0
                       IMPLIES convergence(1 / g, a, 1 / l)

    cv_div   : LEMMA convergence(f, a, l1) AND convergence(g, a, l2) AND l2 /= 0
                       IMPLIES convergence(f / g, a, l1 / l2)

    %-------------------------
    %  f is convergent at a    
    %-------------------------

    convergent?(f, a) : bool = EXISTS l : convergence(f, a, l)

    lim(f, (x0 : {a | convergent?(f, a)})) : real =  
          choose(LAMBDA l : convergence(f, x0, l))

    lim_fun_lemma   : LEMMA FORALL f, (x0 : {a | convergent?(f, a)}) :
                            convergence(f, x0, lim(f, x0))

    lim_fun_def     : LEMMA FORALL f, l, (x0 : {a | convergent?(f, a)}) :
                               lim(f, x0) = l IFF convergence(f, x0, l)

    convergence_equiv    : LEMMA convergence(f, a, l) IFF 
                                    convergent?(f, a) AND lim(f, a) = l
          
    convergent_in_domain : LEMMA convergent?(f, x) IFF convergence(f, x, f(x))
          
    lim_in_domain        : LEMMA convergent?(f, x) IMPLIES lim(f, x) = f(x)
          

    %------------------------------------------
    %  Operations preserving convergence at a 
    %------------------------------------------

    sum_fun_convergent  : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 + f2, a)

    neg_fun_convergent : LEMMA convergent?(f, a) IMPLIES convergent?(- f, a)
          
    diff_fun_convergent : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 - f2, a)

    prod_fun_convergent : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 * f2, a)

    const_fun_convergent: LEMMA convergent?(const_fun(b), v)
          
    scal_fun_convergent : LEMMA convergent?(f, a) IMPLIES convergent?(b * f, a)
          
    inv_fun_convergent  : LEMMA convergent?(g, a) AND lim(g, a) /= 0
                                   IMPLIES convergent?(1/g, a)

    div_fun_convergent  : LEMMA convergent?(f, a) AND convergent?(g, a)
                                  AND lim(g, a) /= 0 IMPLIES convergent?(f / g, a)


    %----------------------------
    %  Same things with lim(a)
    %----------------------------

    lim_sum_fun      : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 + f2, a) = lim(f1, a) + lim(f2, a)

    lim_neg_fun : LEMMA convergent?(f, a) 
                               IMPLIES lim(- f, a) = - lim(f, a)
          
    lim_diff_fun     : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 - f2, a) = lim(f1, a) - lim(f2, a)

    lim_prod_fun     : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 * f2, a) = lim(f1, a) * lim(f2, a)

    lim_const_fun    : LEMMA lim(const_fun(b), v) = b

    lim_scal_fun     : LEMMA convergent?(f, a) 
                               IMPLIES lim(b * f, a) = b * lim(f, a)
          
    lim_inv_fun      : LEMMA convergent?(g, a) AND lim(g, a) /= 0
                               IMPLIES lim(1/g, a) = 1/lim(g, a)

    lim_div_fun      : LEMMA convergent?(f, a) AND convergent?(g, a) AND lim(g, a) /= 0
                               IMPLIES lim(f / g, a) = lim(f, a)/lim(g, a)


    %-----------------------------
    %  Limit preserve order
    %-----------------------------

    convergence_order : LEMMA
  	FORALL f1, f2, a, l1, l2 :
  		convergence(f1, a, l1)
  	    AND convergence(f2, a, l2)
  	    AND (FORALL x : f1(x) <= f2(x))
  	IMPLIES l1 <= l2
    

    %-------------------------------------------
    %  Bounds on function are bounds on limits
    %-------------------------------------------

    convergence_lower_bound : COROLLARY
  	FORALL f, b, a, l :
  		convergence(f, a, l)
  	    AND (FORALL x : b <= f(x))
  	IMPLIES b <= l

    convergence_upper_bound : COROLLARY
  	FORALL f, b, a, l :
  		convergence(f, a, l)
  	    AND (FORALL x : f(x) <= b)
  	IMPLIES l <= b


    %--------------------
    %  Bounds on limits
    %--------------------

    lim_le1 : LEMMA
          convergent?(f, a) AND (FORALL x : f(x) <= b) IMPLIES lim(f, a) <= b

    lim_ge1 : LEMMA
          convergent?(f, a) AND (FORALL x : f(x) >= b) IMPLIES lim(f, a) >= b
    
    lim_order1 : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                       AND (FORALL x : f1(x) <= f2(x)) 
                           IMPLIES lim(f1, a) <= lim(f2, a)

  END limit_vect2_real

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

  % Subtype TCC generated (at line 65, column 15) for
      % LAMBDA l: convergence(f, x0, l)
      % expected type  p: (nonempty?[real])
  lim_TCC1: OBLIGATION
    FORALL (f: [Vect2 -> real], (x0: {a | convergent?(f, a)})):
      nonempty?[real](LAMBDA l: convergence(f, x0, l));

  % Subtype TCC generated (at line 112, column 50) for  a
      % expected type  {a | convergent?(f1 + f2, a)}
  lim_sum_fun_TCC1: OBLIGATION
    FORALL (a: Vect2, f1, f2: [Vect2 -> real]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(f1 + f2, a);

  % Subtype TCC generated (at line 115, column 46) for  a
      % expected type  {a | convergent?(-f, a)}
  lim_neg_fun_TCC1: OBLIGATION
    FORALL (a: Vect2, f: [Vect2 -> real]):
      convergent?(f, a) IMPLIES convergent?(-f, a);

  % Subtype TCC generated (at line 118, column 50) for  a
      % expected type  {a | convergent?(f1 - f2, a)}
  lim_diff_fun_TCC1: OBLIGATION
    FORALL (a: Vect2, f1, f2: [Vect2 -> real]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(f1 - f2, a);

  % Subtype TCC generated (at line 121, column 50) for  a
      % expected type  {a | convergent?(f1 * f2, a)}
  lim_prod_fun_TCC1: OBLIGATION
    FORALL (a: Vect2, f1, f2: [Vect2 -> real]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(f1 * f2, a);

  % Subtype TCC generated (at line 123, column 45) for  v
      % expected type  {a | convergent?(const_fun(b), a)}
  lim_const_fun_TCC1: OBLIGATION
    FORALL (b: real, v: Vect2): convergent?(const_fun(b), v);

  % Subtype TCC generated (at line 126, column 48) for  a
      % expected type  {a | convergent?(b * f, a)}
  lim_scal_fun_TCC1: OBLIGATION
    FORALL (a: Vect2, b: real, f: [Vect2 -> real]):
      convergent?(f, a) IMPLIES convergent?(b * f, a);

  % Subtype TCC generated (at line 129, column 46) for  a
      % expected type  {a | convergent?(1 / g, a)}
  lim_inv_fun_TCC1: OBLIGATION
    FORALL (a: Vect2, g: [Vect2 -> nzreal]):
      lim(g, a) /= 0 AND convergent?(g, a) IMPLIES convergent?(1 / g, a);

  % Subtype TCC generated (at line 132, column 48) for  a
      % expected type  {a | convergent?(f / g, a)}
  lim_div_fun_TCC1: OBLIGATION
    FORALL (a: Vect2, f: [Vect2 -> real], g: [Vect2 -> nzreal]):
      lim(g, a) /= 0 AND convergent?(g, a) AND convergent?(f, a) IMPLIES
       convergent?(f / g, a);


body:
  cont_vect2_real: THEORY
  %------------------------------------------------------------------------------
  %  Continuous functions [ Vect2 -> real]   
  %
  %  Author: Rick Butler     NASA Langley Research Center  2/1/2009
  %
  %------------------------------------------------------------------------------
  BEGIN

    IMPORTING limit_vect2_real

    f, f1, f2      : VAR [Vect2 -> real]
    g              : VAR [Vect2 -> nzreal]
    u              : VAR real
    x, x0          : VAR Vect2
    epsilon, delta : VAR posreal
    n              : VAR nat
   
    %--------------------
    %  Continuity at x0    
    %--------------------

    continuous_vr?(f, x0) : bool = 
          FORALL epsilon : EXISTS delta : FORALL x :
                  norm(x - x0) < delta IMPLIES abs(f(x) - f(x0)) < epsilon

    continuity_def : LEMMA
          continuous_vr?(f, x0) IFF convergence(f, x0, f(x0))

    continuity_def2 : LEMMA
          continuous_vr?(f, x0) IFF convergent?(f, x0)


    %------------------------------------------
    %  Operations preserving continuity at x0 
    %------------------------------------------

    sum_continuous_vr  : LEMMA continuous_vr?(f1, x0) AND continuous_vr?(f2, x0)
                             IMPLIES continuous_vr?(f1 + f2, x0)

    diff_continuous_vr : LEMMA continuous_vr?(f1, x0) AND continuous_vr?(f2, x0)
                             IMPLIES continuous_vr?(f1 - f2, x0)

    prod_continuous_vr : LEMMA continuous_vr?(f1, x0) AND continuous_vr?(f2, x0)
                             IMPLIES continuous_vr?(f1 * f2, x0)

    const_continuous_vr: LEMMA continuous_vr?(const_fun(u), x0)

    scal_continuous_vr : LEMMA continuous_vr?(f, x0) IMPLIES continuous_vr?(u * f, x0)
                  
    neg_continuous_vr  : LEMMA continuous_vr?(f, x0) IMPLIES continuous_vr?(- f, x0)

    div_continuous_vr  : LEMMA continuous_vr?(f, x0) AND continuous_vr?(g, x0) 
                              IMPLIES continuous_vr?(f/g, x0)

    inv_continuous_vr  : LEMMA continuous_vr?(g, x0) IMPLIES continuous_vr?(1/g, x0)
    
    expt_continuous_vr : LEMMA continuous_vr?(f, x0) IMPLIES continuous_vr?(f^n, x0)


    %---------------------------------
    %  Continuity of f in its domain
    %---------------------------------

    continuous_vr?(f): bool = FORALL x0: continuous_vr?(f, x0)

  % ------------ Alternate forms and names for convenience ---------------

    sum_cont_vr_fun  : LEMMA continuous_vr?(f1) AND continuous_vr?(f2)
                             IMPLIES continuous_vr?(f1 + f2)

    diff_cont_vr_fun : LEMMA continuous_vr?(f1) AND continuous_vr?(f2)
                             IMPLIES continuous_vr?(f1 - f2)

    prod_cont_vr_fun : LEMMA continuous_vr?(f1) AND continuous_vr?(f2)
                             IMPLIES continuous_vr?(f1 * f2)

    const_cont_vr_fun: LEMMA continuous_vr?(const_fun(u))

    scal_cont_vr_fun : LEMMA continuous_vr?(f) IMPLIES continuous_vr?(u * f)
                  
    neg_cont_vr_fun  : LEMMA continuous_vr?(f) IMPLIES continuous_vr?(-f)

    div_cont_vr_fun  : LEMMA continuous_vr?(f) AND continuous_vr?(g) 
                              IMPLIES continuous_vr?(f/g)

    inv_cont_vr_fun  : LEMMA continuous_vr?(g) IMPLIES continuous_vr?(1/g)
    
    expt_cont_vr_fun : LEMMA continuous_vr?(f) IMPLIES continuous_vr?(f^n)


    %--- Properties ---%



    continuous_vr_fun: TYPE+ = { f | continuous_vr?(f) }

    nz_continuous_vr_fun: TYPE = { g | continuous_vr?(g) }

    h, h1, h2: VAR continuous_vr_fun
    h3: VAR nz_continuous_vr_fun


    sum_fun_continuous_vr : JUDGEMENT  +(h1, h2) HAS_TYPE continuous_vr_fun

    diff_fun_continuous_vr: JUDGEMENT  -(h1, h2) HAS_TYPE continuous_vr_fun

    prod_fun_continuous_vr: JUDGEMENT  *(h1, h2) HAS_TYPE continuous_vr_fun

    const_fun_continuous_vr: JUDGEMENT const_fun(u) HAS_TYPE continuous_vr_fun

    scal_fun_continuous_vr: JUDGEMENT  *(u, h) HAS_TYPE continuous_vr_fun

    neg_fun_continuous_vr : JUDGEMENT -(h) HAS_TYPE continuous_vr_fun

    div_fun_continuous_vr : JUDGEMENT /(h, h3) HAS_TYPE continuous_vr_fun

    inv_fun_continuous_vr : LEMMA continuous_vr?(1/h3)

    expt_fun_continuous_vr: LEMMA continuous_vr?(f) IMPLIES continuous_vr?(f^n)



  END cont_vect2_real

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

  % Existence TCC generated (at line 96, column 2) for
      % continuous_vr_fun: TYPE+ = {f | continuous_vr?(f)}
  continuous_vr_fun_TCC1: OBLIGATION
    EXISTS (x: {f | continuous_vr?(f)}): TRUE;

  % Judgement subtype TCC generated (at line 104, column 37) for  h1 + h2
      % expected type  continuous_vr_fun
  sum_fun_continuous_vr: OBLIGATION FORALL (h1, h2): continuous_vr?(h1 + h2);

  % Judgement subtype TCC generated (at line 106, column 37) for  h1 - h2
      % expected type  continuous_vr_fun
  diff_fun_continuous_vr: OBLIGATION FORALL (h1, h2): continuous_vr?(h1 - h2);

  % Judgement subtype TCC generated (at line 108, column 37) for  h1 * h2
      % expected type  continuous_vr_fun
  prod_fun_continuous_vr: OBLIGATION FORALL (h1, h2): continuous_vr?(h1 * h2);

  % Judgement subtype TCC generated (at line 110, column 37) for  const_fun(u)
      % expected type  continuous_vr_fun
  const_fun_continuous_vr: OBLIGATION
    FORALL (u): continuous_vr?(const_fun(u));

  % Judgement subtype TCC generated (at line 112, column 37) for  u * h
      % expected type  continuous_vr_fun
  scal_fun_continuous_vr: OBLIGATION FORALL (h, u): continuous_vr?(u * h);

  % Judgement subtype TCC generated (at line 114, column 36) for  -h
      % expected type  continuous_vr_fun
  neg_fun_continuous_vr: OBLIGATION FORALL (h): continuous_vr?(-h);

  % Judgement subtype TCC generated (at line 116, column 36) for  h / h3
      % expected type  continuous_vr_fun
  div_fun_continuous_vr: OBLIGATION FORALL (h, h3): continuous_vr?(h / h3);


body:
  vect2_cont_dot[T: TYPE from real] : THEORY
  %----------------------------------------------------------------------------
  %
  %   AUTHOR: Rick Butler         NASA langley Research Center
  %
  %   The proofs in this theory are tricky.
  %   
  %   f,g: [real -> vect2] are continuous
  %
  %     || f(x) * g(x) - f(x0) * g(x0) || <= ||f(x) || || f(x) * g(x) - g(x0) || 
  %                                          + || g(x0) || || f(x)  - f(x0) || 
  %
  %     need || f(x)  - f(x0) || < eps/(2*||g(x0)||)
  %
  %     need || g(x)  - g(x0) || < eps/(2*r) where || f(x) || < r near x0
  %
  %     EXISTS delta1: | x - x0 | < delta1 IMPLIES
  %                                   || f(x)|| < ||f(x0)|| + 1 = r
  %
  %     EXISTS delta2: | x - x0 | < delta2 IMPLIES
  %                       || f(x)  - f(x0) || < eps/(2*||g(x0)||)
  %
  %     EXISTS delta3: | x - x0 | < delta3 IMPLIES
  %               || g(x)  - g(x0) || < eps/(2*r) 
  %
  %     let delta = min(delta1,delta2,delta3)
  %
  %     || f(x) * g(x) - f(x0) * g(x0) || <= ||f(x) || || f(x) * g(x) - g(x0) || 
  %                                          + || g(x0) || || f(x)  - f(x0) || 
  %                                  < r * eps    + eps || g(x0)||
  %                                        ---      ---
  %                                         2r     (2||g(x0)||)  
  %                                  = eps                    
  %
  %----------------------------------------------------------------------------
  BEGIN 

    IMPORTING cont_vect2_real, 
              cont_vect2_vect2,
              analysis@continuous_lambda[T], 
              cont_real_vect2[T] 

    frr : VAR [T -> real]
    continuous_rr?(frr): MACRO bool = continuous?(frr)

    v   : VAR Vect2
    x,y : VAR T

     vv,vv1,vv2 : VAR { f:[Vect2->Vect2] | continuous_vv?(f) }
     vr,vr1,vr2 : VAR { f:[Vect2->real] | continuous_vr?(f) }
     rr         : VAR continuous_fun
     rv,rv1,rv2 : VAR { f:[T->Vect2] | continuous_rv?(f) }

    dot_cont_vr : LEMMA 
      continuous_vr?(LAMBDA(v):vv1(v)*vv2(v)) 

    dot_cont_rr : LEMMA 
      continuous?[T](LAMBDA(x):rv1(x)*rv2(x)) 

    scal_cont_rv : LEMMA 
      continuous_rv?(LAMBDA(x):rr(x)*rv(x)) 

    scal_cont_vv : LEMMA 
      continuous_vv?(LAMBDA(v):vr(v)*vv(v)) 

    scal_scal_cont_rv : LEMMA 
      continuous_rv?(LAMBDA(x):y*rv(x))

  END vect2_cont_dot


body:
  vect2_cont_comp[T: TYPE FROM real]: THEORY
  %------------------------------------------------------------------------------
  %
  %   AUTHOR: Cesar Munoz         NASA langley Research Center
  %           Rick Butler         NASA langley Research Center
  %
  %  Note that rT, frT could be generalized to [T1 -> T2], see vect2_cont_comp2
  %  
  %
  %------------------------------------------------------------------------------
  BEGIN 

    IMPORTING cont_vect2_real, 
              cont_vect2_vect2,
              analysis@continuous_lambda[T], 
              cont_real_vect2[T] 


    fvv,fvv1,fvv2 : VAR [Vect2->Vect2]
    fvr : VAR [Vect2->real]
    fvT : VAR [Vect2->T]
    frr : VAR [T->real]
    frT : VAR [T->T]
    frv : VAR [T->Vect2]
    v,u : VAR Vect2
    x,y : VAR T
    nzx : VAR {t: T | t /= 0}

    ;o(fvv1,fvv2): [Vect2->Vect2] = LAMBDA (v): fvv1(fvv2(v))

    ;o(frv,fvT)  : [Vect2->Vect2] = LAMBDA (v): frv(fvT(v))

    ;o(fvr,fvv)  : [Vect2->real]  = LAMBDA (v): fvr(fvv(v))

    ;o(frr,fvT)  : [Vect2->real]  = LAMBDA (v): frr(fvT(v))

    ;o(fvv,frv)  : [T->Vect2]  = LAMBDA (x): fvv(frv(x))

    ;o(frv,frT)  : [T->Vect2]  = LAMBDA (x): frv(frT(x))

    ;o(fvr,frv)  : [T->real]   = LAMBDA (x): fvr(frv(x))

    vv,vv1,vv2 : VAR { f:[Vect2->Vect2] | continuous_vv?(f) }
    vr         : VAR { f:[Vect2->real] | continuous_vr?(f) }
    vT         : VAR { f:[Vect2->T] | continuous_vr?(f) }
    rr         : VAR { f:[T->real] | continuous?(f) }
    rT         : VAR { f:[T->T] | continuous?(f) }
    rv,rv1,rv2 : VAR { f:[T->Vect2] | continuous_rv?(f) }

    comp_vv_vv_cont : LEMMA
      continuous_vv?(vv1 o vv2)

    comp_rv_vr_cont : LEMMA
      continuous_vv?(rv o vT)

    comp_vr_vv_cont : LEMMA
       continuous_vr?(vr o vv)

    comp_rr_vr_cont : LEMMA
      continuous_vr?(rr o vT)

    comp_vv_rv_cont : LEMMA
      continuous_rv?(vv o rv)

    comp_rv_rr_cont : LEMMA
      continuous_rv?(rv o rT)

    comp_vr_rv_cont : LEMMA
      continuous?(vr o rv)

  END vect2_cont_comp


body:
  vect_cont_2D : THEORY
  BEGIN 

    IMPORTING analysis@continuous_lambda[real], 
              vect2_cont_comp[real],
              vect2_cont_dot[real]

    v,u : VAR Vect2
    x,y : VAR real
    nzx : VAR nzreal

    vv,vv1,vv2 : VAR continuous_vv_fun
    vr,vr1,vr2 : VAR continuous_vr_fun
    rr,rr1,rr2 : VAR continuous_fun
    rv,rv1,rv2 : VAR continuous_rv_fun

  %   The following proved in vect2_cont_comp
  %
  %   comp_vv_vv_cont : LEMMA
  %     continuous_vv(vv1 o vv2)
  %
  %   comp_rv_vr_cont : LEMMA
  %     continuous_vv(rv o vr)
  %
  %   comp_vr_vv_cont : LEMMA
  %      continuous_vr(vr o vv)
  %
  %   comp_rr_vr_cont : LEMMA
  %     continuous_vr(rr o vr)
  %
  %   comp_vv_rv_cont : LEMMA
  %     continuous_rv(vv o rv)
  %
  %   comp_rv_rr_cont : LEMMA
  %     continuous_rv(rv o rr)
  %
  %   comp_vr_rv_cont : LEMMA
  %     continuous_rr(vr o rv)

    const_cont_vv : LEMMA
      continuous_vv?(LAMBDA(v):u)

    const_cont_rv : LEMMA
      continuous_rv?(LAMBDA(x):v)

    const_cont_vr : LEMMA
       continuous_vr?(LAMBDA(v):x)

    pair_cont_rv : LEMMA
      continuous_rv?(LAMBDA(x):mk_vect2(rr1(x),rr2(x)))

    pair_cont_vv : LEMMA
      continuous_vv?(LAMBDA(v):mk_vect2(vr1(v),vr2(v)))

    x_cont_vr : LEMMA
      continuous_vr?(LAMBDA(v):x(v))

    y_cont_vr : LEMMA
      continuous_vr?(LAMBDA(v):y(v))

    id_cont_vv : LEMMA
      continuous_vv?(LAMBDA(v):v)

  %   The following proved in vect2_continuity
  %
  %  dot_cont_vr : LEMMA 
  %    continuous_vr?(LAMBDA(v):vv1(v)*vv2(v)) 
  %
  %  dot_cont_rr : LEMMA 
  %    continuous_rr(LAMBDA(x):rv1(x)*rv2(x)) 

    mult_cont_vr : LEMMA 
      continuous_vr?(LAMBDA(v):vr1(v)*vr2(v)) 

    scal_mult_cont_vr : LEMMA
      continuous_vr?(LAMBDA(v):x*vr(v))

    div_cont_vr : LEMMA 
      FORALL (vnz:[Vect2->nzreal]):
        continuous_vr?(vnz) IMPLIES
        continuous_vr?(LAMBDA(v):vr(v)/vnz(v)) 

    scal_div1_cont_vr : LEMMA
      continuous_vr?(LAMBDA(v):vr(v)/nzx)

    scal_div2_cont_vr : LEMMA
      FORALL (vnz:[Vect2->nzreal]): 
        continuous_vr?(vnz) IMPLIES
        continuous_vr?(LAMBDA(v):x/vnz(v))

    add_cont_vv : LEMMA 
      continuous_vv?(LAMBDA(v):vv1(v)+vv2(v))

    add_cont_vr : LEMMA 
      continuous_vr?(LAMBDA(v):vr1(v)+vr2(v))

    add_cont_rv : LEMMA 
      continuous_rv?(LAMBDA(x):rv1(x)+rv2(x))

    sub_cont_vv : LEMMA 
      continuous_vv?(LAMBDA(v):vv1(v)-vv2(v))

    sub_cont_vr : LEMMA 
      continuous_vr?(LAMBDA(v):vr1(v)-vr2(v))

    sub_cont_rv : LEMMA 
      continuous_rv?(LAMBDA(x):rv1(x)-rv2(x))

    neg_cont_vr : LEMMA 
      continuous_vr?(LAMBDA(v):-vr(v)) 

    neg_cont_vv : LEMMA 
      continuous_vv?(LAMBDA(v):-vv(v)) 

    neg_cont_rv : LEMMA 
      continuous_rv?(LAMBDA(x):-rv(x)) 

  %   The following proved in vect2_continuity
  %
  %  scal_cont_rv : LEMMA 
  %    continuous_rv?(LAMBDA(x):rr(x)*rv(x)) 
  %
  %  scal_cont_vv : LEMMA 
  %    continuous_vv?(LAMBDA(v):vr(v)*vv(v)) 
  %
  %  scal_scal_cont_rv : LEMMA 
  %    continuous_rv?LAMBDA(x):y*rv(x))

    scal_scal_cont_vv : LEMMA 
      continuous_vv?(LAMBDA(v):y*vv(v))

    % Useful judgements

    sqv_cont : JUDGEMENT
      sqv HAS_TYPE continuous_vr_fun

    neg_cont : JUDGEMENT
      vectors_2D.- HAS_TYPE continuous_vv_fun

    % Useful compositons

    abs_cont_vr : LEMMA
      continuous_vr?(LAMBDA(v):abs(vr(v)))

    max_cont_vr : LEMMA
      continuous_vr?(LAMBDA(v):max(vr1(v),vr2(v)))

    min_cont_vr : LEMMA
      continuous_vr?(LAMBDA(v):min(vr1(v),vr2(v)))

    sq_cont_vr : LEMMA
      continuous_vr?(LAMBDA(v):sq(vr(v)))

    sqv_cont_vr : LEMMA
      continuous_vr?(LAMBDA(v):sqv(vv(v)))

    sqv_cont_rr : LEMMA
      continuous_rr?(LAMBDA(x):sqv(rv(x)))

  END vect_cont_2D

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

  % Judgement subtype TCC generated (at line 135, column 4) for  sqv
      % expected type  continuous_vr_fun
  sqv_cont: OBLIGATION continuous_vr?(sqv);

  % Judgement subtype TCC generated (at line 138, column 4) for  vectors_2D.-
      % expected type  continuous_vv_fun
  neg_cont: OBLIGATION continuous_vv?(vectors_2D.-);


body:
  vect2_cont_comp2[T1,T2: TYPE FROM real]: THEORY
  %------------------------------------------------------------------------------
  %
  %  Note that rT, frT could be generalized to [T1 -> T2]
  %  Perhaps this should be done in anotrher theory with importings T1,T2
  %
  %------------------------------------------------------------------------------
  BEGIN 

    IMPORTING cont_vect2_real, 
              cont_real_vect2 



    fvT : VAR [Vect2->T1]
    ftt : VAR [T1->T2]
    frv : VAR [T2->Vect2]

    v: VAR Vect2
    x: VAR T1

    ;o(ftt,fvT)  : [Vect2->T2]  = LAMBDA (v): ftt(fvT(v))

    ;o(frv,ftt)  : [T1->Vect2]  = LAMBDA (x): frv(ftt(x))

    vT         : VAR { f:[Vect2->T1] | continuous_vr?(f) }
    tt         : VAR { f:[T1->T2] | continuous?(f) }
    rv         : VAR { f:[T2->Vect2] | continuous_rv?(f) }


    comp_tt_vt_cont : LEMMA
      continuous_vr?(tt o vT)

    comp_rv_tt_cont : LEMMA
      continuous_rv?(rv o tt)

  END vect2_cont_comp2


body:
  limit_vect3_real: THEORY
  BEGIN

    IMPORTING vectors@vect3_fun_ops, 
              reals@abs_lems, 
              analysis@epsilon_lemmas

    f, f1, f2: VAR [ Vect3 -> real]
    g : VAR [Vect3 -> nzreal]
    epsilon, delta : VAR posreal
    a,x,v: VAR Vect3
    l,l1,l2,b,c,y1,y2: VAR real

    %---------------------------------------------------
    %  Convergence of f at a point a towards a limit l
    %---------------------------------------------------

    convergence(f, a, l) : bool = 
  	FORALL epsilon : EXISTS delta : 
  	    FORALL x: %%% 0 < norm(x-a) AND
                        norm(x-a) < delta          %% AND x in dom(f)
                   IMPLIES abs(f(x) - l) < epsilon

    cv_unique    : LEMMA convergence(f, a, l1) AND convergence(f, a, l2)
                        IMPLIES l1 = l2

    cv_in_domain : LEMMA convergence(f, x, l) IMPLIES l = f(x)

    %-------------------------------------------
    %  convergence and operations on functions
    %-------------------------------------------

    cv_sum   : LEMMA convergence(f1, a, l1) AND convergence(f2, a, l2)
                       IMPLIES convergence(f1 + f2, a, l1 + l2)

    cv_neg   : LEMMA convergence(f, a, l)
                       IMPLIES convergence(- f, a, - l)

    cv_diff  : LEMMA convergence(f1, a, l1) AND convergence(f2, a, l2)
                       IMPLIES convergence(f1 - f2, a, l1 - l2)


    cv_prod  : LEMMA convergence(f1, a, l1) AND convergence(f2, a, l2)
                       IMPLIES convergence(f1 * f2, a, l1 * l2)

    cv_const : LEMMA convergence(const_fun(b), v, b)

    cv_scal  : LEMMA convergence(f, a, l)
                       IMPLIES convergence(b * f, a, b * l)


    cv_inv   : LEMMA convergence(g, a, l) AND l /= 0
                       IMPLIES convergence(1 / g, a, 1 / l)

    cv_div   : LEMMA convergence(f, a, l1) AND convergence(g, a, l2) AND l2 /= 0
                       IMPLIES convergence(f / g, a, l1 / l2)

    %-------------------------
    %  f is convergent at a    
    %-------------------------

    convergent?(f, a) : bool = EXISTS l : convergence(f, a, l)

    lim(f, (x0 : {a | convergent?(f, a)})) : real =  
          epsilon(LAMBDA l : convergence(f, x0, l))

    lim_fun_lemma   : LEMMA FORALL f, (x0 : {a | convergent?(f, a)}) :
                            convergence(f, x0, lim(f, x0))

    lim_fun_def     : LEMMA FORALL f, l, (x0 : {a | convergent?(f, a)}) :
                               lim(f, x0) = l IFF convergence(f, x0, l)

    convergence_equiv    : LEMMA convergence(f, a, l) IFF 
                                    convergent?(f, a) AND lim(f, a) = l
          
    convergent_in_domain : LEMMA convergent?(f, x) IFF convergence(f, x, f(x))
          
    lim_in_domain        : LEMMA convergent?(f, x) IMPLIES lim(f, x) = f(x)
          

    %------------------------------------------
    %  Operations preserving convergence at a 
    %------------------------------------------

    sum_fun_convergent  : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 + f2, a)

    neg_fun_convergent : LEMMA convergent?(f, a) IMPLIES convergent?(- f, a)
          
    diff_fun_convergent : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 - f2, a)

    prod_fun_convergent : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 * f2, a)

    const_fun_convergent: LEMMA convergent?(const_fun(b), v)
          
    scal_fun_convergent : LEMMA convergent?(f, a) IMPLIES convergent?(b * f, a)
          
    inv_fun_convergent  : LEMMA convergent?(g, a) AND lim(g, a) /= 0
                                   IMPLIES convergent?(1/g, a)

    div_fun_convergent  : LEMMA convergent?(f, a) AND convergent?(g, a)
                                  AND lim(g, a) /= 0 IMPLIES convergent?(f / g, a)


    %----------------------------
    %  Same things with lim(a)
    %----------------------------

    lim_sum_fun      : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 + f2, a) = lim(f1, a) + lim(f2, a)

    lim_neg_fun : LEMMA convergent?(f, a) 
                               IMPLIES lim(- f, a) = - lim(f, a)
          
    lim_diff_fun     : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 - f2, a) = lim(f1, a) - lim(f2, a)

    lim_prod_fun     : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 * f2, a) = lim(f1, a) * lim(f2, a)

    lim_const_fun    : LEMMA lim(const_fun(b), v) = b

    lim_scal_fun     : LEMMA convergent?(f, a) 
                               IMPLIES lim(b * f, a) = b * lim(f, a)
          
    lim_inv_fun      : LEMMA convergent?(g, a) AND lim(g, a) /= 0
                               IMPLIES lim(1/g, a) = 1/lim(g, a)

    lim_div_fun      : LEMMA convergent?(f, a) AND convergent?(g, a) AND lim(g, a) /= 0
                               IMPLIES lim(f / g, a) = lim(f, a)/lim(g, a)


    %-----------------------------
    %  Limit preserve order
    %-----------------------------

    convergence_order : LEMMA
  	FORALL f1, f2, a, l1, l2 :
  		convergence(f1, a, l1)
  	    AND convergence(f2, a, l2)
  	    AND (FORALL x : f1(x) <= f2(x))
  	IMPLIES l1 <= l2
    

    %-------------------------------------------
    %  Bounds on function are bounds on limits
    %-------------------------------------------

    convergence_lower_bound : COROLLARY
  	FORALL f, b, a, l :
  		convergence(f, a, l)
  	    AND (FORALL x : b <= f(x))
  	IMPLIES b <= l

    convergence_upper_bound : COROLLARY
  	FORALL f, b, a, l :
  		convergence(f, a, l)
  	    AND (FORALL x : f(x) <= b)
  	IMPLIES l <= b


    %--------------------
    %  Bounds on limits
    %--------------------

    lim_le1 : LEMMA
          convergent?(f, a) AND (FORALL x : f(x) <= b) IMPLIES lim(f, a) <= b

    lim_ge1 : LEMMA
          convergent?(f, a) AND (FORALL x : f(x) >= b) IMPLIES lim(f, a) >= b
    
    lim_order1 : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                       AND (FORALL x : f1(x) <= f2(x)) 
                           IMPLIES lim(f1, a) <= lim(f2, a)

  END limit_vect3_real

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

  % Subtype TCC generated (at line 112, column 50) for  a
      % expected type  {a | convergent?(f1 + f2, a)}
  lim_sum_fun_TCC1: OBLIGATION
    FORALL (a: Vect3, f1, f2: [Vect3 -> real]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(f1 + f2, a);

  % Subtype TCC generated (at line 115, column 46) for  a
      % expected type  {a | convergent?(-f, a)}
  lim_neg_fun_TCC1: OBLIGATION
    FORALL (a: Vect3, f: [Vect3 -> real]):
      convergent?(f, a) IMPLIES convergent?(-f, a);

  % Subtype TCC generated (at line 118, column 50) for  a
      % expected type  {a | convergent?(f1 - f2, a)}
  lim_diff_fun_TCC1: OBLIGATION
    FORALL (a: Vect3, f1, f2: [Vect3 -> real]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(f1 - f2, a);

  % Subtype TCC generated (at line 121, column 50) for  a
      % expected type  {a | convergent?(f1 * f2, a)}
  lim_prod_fun_TCC1: OBLIGATION
    FORALL (a: Vect3, f1, f2: [Vect3 -> real]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(f1 * f2, a);

  % Subtype TCC generated (at line 123, column 45) for  v
      % expected type  {a | convergent?(const_fun(b), a)}
  lim_const_fun_TCC1: OBLIGATION
    FORALL (b: real, v: Vect3): convergent?(const_fun(b), v);

  % Subtype TCC generated (at line 126, column 48) for  a
      % expected type  {a | convergent?(b * f, a)}
  lim_scal_fun_TCC1: OBLIGATION
    FORALL (a: Vect3, b: real, f: [Vect3 -> real]):
      convergent?(f, a) IMPLIES convergent?(b * f, a);

  % Subtype TCC generated (at line 129, column 46) for  a
      % expected type  {a | convergent?(1 / g, a)}
  lim_inv_fun_TCC1: OBLIGATION
    FORALL (a: Vect3, g: [Vect3 -> nzreal]):
      lim(g, a) /= 0 AND convergent?(g, a) IMPLIES convergent?(1 / g, a);

  % Subtype TCC generated (at line 132, column 48) for  a
      % expected type  {a | convergent?(f / g, a)}
  lim_div_fun_TCC1: OBLIGATION
    FORALL (a: Vect3, f: [Vect3 -> real], g: [Vect3 -> nzreal]):
      lim(g, a) /= 0 AND convergent?(g, a) AND convergent?(f, a) IMPLIES
       convergent?(f / g, a);


body:
  cont_vect3_real: THEORY
  %------------------------------------------------------------------------------
  %  Continuous functions [ Vect3 -> real]   
  %
  %  Author: Rick Butler     NASA Langley Research Center  2/1/2009
  %
  %------------------------------------------------------------------------------
  BEGIN

    IMPORTING limit_vect3_real

    f, f1, f2      : VAR [Vect3 -> real]
    g              : VAR [Vect3 -> nzreal]
    u              : VAR real
    x, x0          : VAR Vect3
    epsilon, delta : VAR posreal
    n              : VAR nat
   
    %--------------------
    %  Continuity at x0    
    %--------------------

    continuous_vr?(f, x0) : bool = 
        FORALL epsilon : EXISTS delta : FORALL x :
           norm(x - x0) < delta IMPLIES abs(f(x) - f(x0)) < epsilon

    continuity_def : LEMMA
          continuous_vr?(f, x0) IFF convergence(f, x0, f(x0))

    continuity_def2 : LEMMA
          continuous_vr?(f, x0) IFF convergent?(f, x0)


    %------------------------------------------
    %  Operations preserving continuity at x0 
    %------------------------------------------

    sum_continuous_vr  : LEMMA continuous_vr?(f1, x0) AND continuous_vr?(f2, x0)
                             IMPLIES continuous_vr?(f1 + f2, x0)

    diff_continuous_vr : LEMMA continuous_vr?(f1, x0) AND continuous_vr?(f2, x0)
                             IMPLIES continuous_vr?(f1 - f2, x0)

    prod_continuous_vr : LEMMA continuous_vr?(f1, x0) AND continuous_vr?(f2, x0)
                             IMPLIES continuous_vr?(f1 * f2, x0)

    const_continuous_vr: LEMMA continuous_vr?(const_fun(u), x0)

    scal_continuous_vr : LEMMA continuous_vr?(f, x0) IMPLIES continuous_vr?(u * f, x0)
                  
    neg_continuous_vr  : LEMMA continuous_vr?(f, x0) IMPLIES continuous_vr?(- f, x0)

    div_continuous_vr  : LEMMA continuous_vr?(f, x0) AND continuous_vr?(g, x0) 
                              IMPLIES continuous_vr?(f/g, x0)

    inv_continuous_vr  : LEMMA continuous_vr?(g, x0) IMPLIES continuous_vr?(1/g, x0)
    
    expt_continuous_vr : LEMMA continuous_vr?(f, x0) IMPLIES continuous_vr?(f^n, x0)


    %---------------------------------
    %  Continuity of f in its domain
    %---------------------------------

    continuous_vr?(f): bool = FORALL x0: continuous_vr?(f, x0)

  % ------------ Alternate forms and names for convenience ---------------

    sum_cont_vr_fun  : LEMMA continuous_vr?(f1) AND continuous_vr?(f2)
                             IMPLIES continuous_vr?(f1 + f2)

    diff_cont_vr_fun : LEMMA continuous_vr?(f1) AND continuous_vr?(f2)
                             IMPLIES continuous_vr?(f1 - f2)

    prod_cont_vr_fun : LEMMA continuous_vr?(f1) AND continuous_vr?(f2)
                             IMPLIES continuous_vr?(f1 * f2)

    const_cont_vr_fun: LEMMA continuous_vr?(const_fun(u))

    scal_cont_vr_fun : LEMMA continuous_vr?(f) IMPLIES continuous_vr?(u * f)
                  
    neg_cont_vr_fun  : LEMMA continuous_vr?(f) IMPLIES continuous_vr?(-f)

    div_cont_vr_fun  : LEMMA continuous_vr?(f) AND continuous_vr?(g) 
                              IMPLIES continuous_vr?(f/g)

    inv_cont_vr_fun  : LEMMA continuous_vr?(g) IMPLIES continuous_vr?(1/g)
    
    expt_cont_vr_fun : LEMMA continuous_vr?(f) IMPLIES continuous_vr?(f^n)



    %--- Properties ---%

    continuous_vr_fun: TYPE+ = { f | continuous_vr?(f) }

    nz_continuous_vr_fun: TYPE = { g | continuous_vr?(g) }

    h, h1, h2: VAR continuous_vr_fun
    h3: VAR nz_continuous_vr_fun

    sum_fun_continuous_vr : JUDGEMENT  +(h1, h2) HAS_TYPE continuous_vr_fun

    diff_fun_continuous_vr: JUDGEMENT  -(h1, h2) HAS_TYPE continuous_vr_fun

    prod_fun_continuous_vr: JUDGEMENT  *(h1, h2) HAS_TYPE continuous_vr_fun

    const_fun_continuous_vr: JUDGEMENT const_fun(u) HAS_TYPE continuous_vr_fun

    scal_fun_continuous_vr: JUDGEMENT  *(u, h) HAS_TYPE continuous_vr_fun

    neg_fun_continuous_vr : JUDGEMENT -(h) HAS_TYPE continuous_vr_fun

    div_fun_continuous_vr : JUDGEMENT /(h, h3) HAS_TYPE continuous_vr_fun

    inv_fun_continuous_vr : LEMMA continuous_vr?(1/h3)

    expt_fun_continuous_vr: LEMMA continuous_vr?(f) IMPLIES continuous_vr?(f^n)



  END cont_vect3_real

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

  % Existence TCC generated (at line 95, column 2) for
      % continuous_vr_fun: TYPE+ = {f | continuous_vr?(f)}
  continuous_vr_fun_TCC1: OBLIGATION
    EXISTS (x: {f | continuous_vr?(f)}): TRUE;

  % Judgement subtype TCC generated (at line 102, column 37) for  h1 + h2
      % expected type  continuous_vr_fun
  sum_fun_continuous_vr: OBLIGATION FORALL (h1, h2): continuous_vr?(h1 + h2);

  % Judgement subtype TCC generated (at line 104, column 37) for  h1 - h2
      % expected type  continuous_vr_fun
  diff_fun_continuous_vr: OBLIGATION FORALL (h1, h2): continuous_vr?(h1 - h2);

  % Judgement subtype TCC generated (at line 106, column 37) for  h1 * h2
      % expected type  continuous_vr_fun
  prod_fun_continuous_vr: OBLIGATION FORALL (h1, h2): continuous_vr?(h1 * h2);

  % Judgement subtype TCC generated (at line 108, column 37) for  const_fun(u)
      % expected type  continuous_vr_fun
  const_fun_continuous_vr: OBLIGATION
    FORALL (u): continuous_vr?(const_fun(u));

  % Judgement subtype TCC generated (at line 110, column 37) for  u * h
      % expected type  continuous_vr_fun
  scal_fun_continuous_vr: OBLIGATION FORALL (h, u): continuous_vr?(u * h);

  % Judgement subtype TCC generated (at line 112, column 36) for  -h
      % expected type  continuous_vr_fun
  neg_fun_continuous_vr: OBLIGATION FORALL (h): continuous_vr?(-h);

  % Judgement subtype TCC generated (at line 114, column 36) for  h / h3
      % expected type  continuous_vr_fun
  div_fun_continuous_vr: OBLIGATION FORALL (h, h3): continuous_vr?(h / h3);


body:
  %------------------------------------------------------------------------------------------------
  %
  %       3-dimensional record-vectors form a metric space
  %
  %       Author: Anthony Narkawicz, NASA Langley
  %
  %       
  %       Version 1.0                     September 16, 2009
  %
  %------------------------------------------------------------------------------------------------


  vect3_metric_space: THEORY
  BEGIN

     IMPORTING vectors@distance_3D,analysis@metric_spaces[Vect3,dist]

     S: VAR set[Vect3]

     vect3_subset_metric_space     : THEOREM metric_space?[Vect3,dist](S)

     vect3_metric_space : COROLLARY metric_space?[Vect3,dist](fullset[Vect3])


  END vect3_metric_space

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

  % Assuming TCC generated (at line 16, column 33) for
      % analysis@metric_spaces[Vect3, dist]
      % generated from assumption metric_spaces.fullset_metric_space
  IMP_metric_spaces_TCC1: OBLIGATION
    metric_space?[Vect3, dist](fullset[Vect3]);


body:
  %------------------------------------------------------------------------------------------------
  %
  %       A Special Result On Continuous Functions R x R^3 -> R
  %
  %       Author: Anthony Narkawicz, NASA Langley
  %
  %       
  %       Version 1.0                     September 16, 2009
  %
  %------------------------------------------------------------------------------------------------


  vect3_Heine: THEORY
  BEGIN

     IMPORTING vect3_metric_space, 
               analysis@real_metric_space, 
               analysis@cross_metric_real_fun[real,real_dist,Vect3,dist], 
               analysis@continuity_ms[Vect3,dist,real,real_dist]

     f: VAR [[real,Vect3] -> real]

     curried_min_exists_3D: LEMMA FORALL (A: real, B: {x: real | A < x}):
      continuous?(f,fullset[[(closed_intv(A,B)),Vect3]])
       IMPLIES (FORALL (y: Vect3):  
          nonempty?[real]({r: real | EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):r = f(t, y)})
      AND below_bounded[real]({r: real | EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):r = f(t, y)})
      AND ext[real]({r: real | EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)): r = f(t, y)})
                (inf[real]({r: real | EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)): r = f(t, y)}))
      AND (EXISTS (tmin: (closed_intv(A,B))): FORALL (s: (closed_intv(A,B))): f(tmin,y) <= f(s,y)))

     curried_min_is_cont_3D: THEOREM FORALL (A: real, B: {x: real | A < x}): 
        continuous?(f,fullset[[(closed_intv(A,B)),Vect3]]) 
        IMPLIES
            LET unif_min_first(y: Vect3): real 
                = min({r: real | EXISTS (t: (closed_intv(A,B))): r = f(t,y)})
            IN continuous?(unif_min_first)

     curried_min_is_cont_3D_ed: THEOREM FORALL (A: real, B: {x: real | A < x}):
         (FORALL (x: (closed_intv(A,B)), y: Vect3, epsilon: posreal): 
            EXISTS (delta: posreal): 
               FORALL (z: (closed_intv(A,B)), w: Vect3): 
                 (real_dist(x,z) <= delta AND dist(y,w) <= delta) IMPLIES real_dist(f(x,y),f(z,w))<epsilon)
         IMPLIES
             LET unif_min_first(y: Vect3): real 
                 = min({r: real | EXISTS (t: (closed_intv(A,B))): r = f(t,y)})
             IN
                (FORALL (y: Vect3): FORALL (epsilon: posreal): 
                    EXISTS (delta: posreal): FORALL (q:Vect3):
                         dist(y,q) < delta IMPLIES real_dist(unif_min_first(y),unif_min_first(q)) < epsilon)


     % Uniform Continuity In The First Variable

     multiary_Heine_3D:   THEOREM FORALL (A: real, B: {x: real | A < x}):
        continuous?(f,fullset[[(closed_intv(A,B)),Vect3]]) 
        IMPLIES uniformly_continuous_in_first?(f,closed_intv(A,B),fullset[Vect3])


     multiary_Heine_3D_ed:   THEOREM FORALL (A: real, B: {x: real | A < x}):
       (FORALL (x: (closed_intv(A,B)), y: Vect3, epsilon: posreal): 
          EXISTS (delta: posreal): 
             FORALL (z: (closed_intv(A,B)), w: Vect3): (real_dist(x,z) <= delta AND dist(y,w) <= delta) 
                                                            IMPLIES real_dist(f(x,y),f(z,w))<epsilon)
       IMPLIES
          FORALL (y1: Vect3, epsilon: posreal): EXISTS (delta: posreal):
             FORALL (x1,x2: (closed_intv(A,B)), y2: Vect3): (real_dist(x1,x2) <= delta AND dist(y1,y2) <= delta) 
                IMPLIES real_dist(f(x1,y1),f(x2,y2))<epsilon

  END vect3_Heine

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

  % Assuming TCC generated (at line 18, column 13) for
      % analysis@cross_metric_real_fun[real, real_dist, Vect3, dist]
      % generated from assumption cross_metric_real_fun.fullset_metric_space1
  IMP_cross_metric_real_fun_TCC1: OBLIGATION
    metric_space?[real, real_dist](fullset[real]);

  % Assuming TCC generated (at line 18, column 13) for
      % analysis@cross_metric_real_fun[real, real_dist, Vect3, dist]
      % generated from assumption cross_metric_real_fun.fullset_metric_space2
  IMP_cross_metric_real_fun_TCC2: OBLIGATION
    metric_space?[Vect3, dist](fullset[Vect3]);

  % Subtype TCC generated (at line 24, column 42) for  B
      % expected type  {x: real | A <= x}
  curried_min_exists_3D_TCC1: OBLIGATION
    FORALL (A: real, B: {x: real | A < x}): A <= B;

  % Subtype TCC generated (at line 36, column 20) for
      % {r: real |
      %    EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)): r = f(t, y)}
      % expected type  min_set[real]
  curried_min_is_cont_3D_TCC1: OBLIGATION
    FORALL (f: [[real, Vect3] -> real], A: real, B: {x: real | A < x}):
      continuous?(f,
                  extend
                      [[real, Vect3],
                       [(LAMBDA (x: real): A <= x AND x <= B), Vect3], bool,
                       FALSE]
                      (fullset
                           [[(LAMBDA (x: real): A <= x AND x <= B), Vect3]]))
       IMPLIES
       (FORALL (y: Vect3):
          nonempty?[real]
              ({r: real |
                  EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                    r = f(t, y)})
           AND
           below_bounded[real]
               ({r: real |
                   EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                     r = f(t, y)})
            AND
            ext[real]
                ({r: real |
                    EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                      r = f(t, y)})
                (inf[real]
                     ({r: real |
                         EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                           r = f(t, y)})));

  % Subtype TCC generated (at line 46, column 21) for
      % {r: real |
      %    EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)): r = f(t, y)}
      % expected type  min_set[real]
  curried_min_is_cont_3D_ed_TCC1: OBLIGATION
    FORALL (f: [[real, Vect3] -> real], A: real, B: {x: real | A < x}):
      (FORALL (x: (LAMBDA (x: real): A <= x AND x <= B), y: Vect3,
               epsilon: posreal):
         EXISTS (delta: posreal):
           FORALL (z: (LAMBDA (x: real): A <= x AND x <= B), w: Vect3):
             (real_dist(x, z) <= delta AND dist(y, w) <= delta) IMPLIES
              real_dist(f(x, y), f(z, w)) < epsilon)
       IMPLIES
       (FORALL (y1: Vect3):
          nonempty?[real]
              ({r: real |
                  EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                    r = f(t, y1)})
           AND
           below_bounded[real]
               ({r: real |
                   EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                     r = f(t, y1)})
            AND
            ext[real]
                ({r: real |
                    EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                      r = f(t, y1)})
                (inf[real]
                     ({r: real |
                         EXISTS (t: (LAMBDA (x: real): A <= x AND x <= B)):
                           r = f(t, y1)})));


body:
  %------------------------------------------------------------------------------------------------
  %
  %       n-dimensional real vectors form a metric space
  %
  %       Author: Anthony Narkawicz, NASA Langley
  %
  %       
  %       Version 1.0                     September 2, 2009
  %
  %------------------------------------------------------------------------------------------------


  vect_metric_space[n: posnat]: THEORY
  BEGIN

     IMPORTING vectors@distance[n],analysis@metric_spaces[Vector[n],dist]

     S: VAR set[Vector[n]]

     vectors_metric_space     : THEOREM metric_space?[Vector[n],dist](S)

     vect_subset_metric_space : COROLLARY metric_space?[Vector[n],dist](fullset[Vector[n]])


  END vect_metric_space

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

  % Assuming TCC generated (at line 16, column 33) for
      % analysis@metric_spaces[Vector[n], dist]
      % generated from assumption metric_spaces.fullset_metric_space
  IMP_metric_spaces_TCC1: OBLIGATION
    metric_space?[Vector[n], dist[n]](fullset[Vector[n]]);


body:
  deriv_cont_2D [T: TYPE from real]: THEORY
  BEGIN 

    ASSUMING
        IMPORTING analysis@deriv_domain_def

        deriv_domain     : ASSUMPTION deriv_domain?[T]

        not_one_element  : ASSUMPTION not_one_element?[T]

    ENDASSUMING


    IMPORTING cont_real_vect2, deriv_real_vect2, analysis@derivatives

    v,u : VAR Vect2
    x,y : VAR real
    nzx : VAR nzreal

    f: VAR [T -> Vect2]


    derivable_rv_cont_rv: LEMMA derivable_rv?(f) IMPLIES continuous_rv?(f)


  END deriv_cont_2D

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

  % Assuming TCC generated (at line 14, column 29) for  deriv_real_vect2[T]
      % generated from assumption deriv_real_vect2.deriv_domain
  derivable_rv_cont_rv_TCC1: OBLIGATION deriv_domain?[T];

  % Assuming TCC generated (at line 14, column 29) for  deriv_real_vect2[T]
      % generated from assumption deriv_real_vect2.not_one_element
  derivable_rv_cont_rv_TCC2: OBLIGATION not_one_element?[T];


body:
  vect_fun_ops  [T: TYPE, n: posnat ] : THEORY
  %------------------------------------------%
  %  Operations on functions : [ T -> Vect[n]]  %
  %------------------------------------------%
  BEGIN

     IMPORTING vectors@vectors[n]

     f, f1, f2: VAR [T -> Vector[n]]
     h: VAR [T -> real]
     x : VAR T
     a,b : VAR real

     +(f1, f2) : MACRO [T -> Vector[n]]  = LAMBDA x : f1(x) + f2(x);
     -(f1)     : MACRO [T -> Vector[n]]  = LAMBDA x : -f1(x);
     -(f1, f2) : MACRO [T -> Vector[n]]  = LAMBDA x : f1(x) - f2(x);
     *(b,f1)   : MACRO [T -> Vector[n]]  = LAMBDA x : b*f1(x);                %% scalar product
     *(h,f)    : MACRO [T -> Vector[n]]   = LAMBDA (t:T): h(t)*f(t);
     *(f1,f2)  : MACRO [T -> real]       = LAMBDA x : f1(x)*f2(x);            %% dot product
   
    const_vfun(a) : MACRO [T -> Vector[n]] = (LAMBDA x : (LAMBDA (i: below(n)): a))

    %------------------
    %  Rewrite rules
    %------------------

    diff_function    : LEMMA f1 - f2 = f1 + (- f2)
    negneg_function  : LEMMA - (- f1) = f1

  END vect_fun_ops


body:
  deriv_real_vect_def [T: TYPE FROM real, n: posnat ] : THEORY
  %------------------------------------------------------------------------------
  % Derivatives of Vector-Valued Functions
  %
  %    Author:  Rick Butler     NASA Langley Research Center
  %
  %  This is the point-wise version.  Users should probably rely primarily on
  %  the theory deriv_real_vect.
  %------------------------------------------------------------------------------
  BEGIN

    ASSUMING

      IMPORTING analysis@deriv_domain_def

      deriv_domain     : ASSUMPTION deriv_domain?[T]

      not_one_element  : ASSUMPTION not_one_element?[T]

    ENDASSUMING


    CONVERSION+ singleton

    IMPORTING analysis@derivatives[T]  

    IMPORTING vectors@vectors[n], vect_fun_ops

    f, f1, f2, fp : VAR [T -> Vector[n]]
    g : VAR [T -> Nz_vector[n]]
    x : VAR T
    u : VAR nzreal
    a,b : VAR real
    l, l1, l2 : VAR real

    const_vfun(a) : MACRO [T -> Vector[n]] = (LAMBDA x : (LAMBDA (i: below(n)): a))

    derivable?(f, x) : bool = FORALL (i: below[n]): derivable?(LAMBDA (t:T): f(t)(i),x)

    deriv(f, (x0 : { x | derivable?(f, x) })) : Vector[n] = 
                  (LAMBDA (i: below(n)): deriv(LAMBDA (t:T): f(t)(i), x0 ))
   
    sum_derivable      : LEMMA derivable?(f1, x) AND derivable?(f2, x)
                               IMPLIES derivable?(f1 + f2, x)

    diff_derivable     : LEMMA derivable?(f1, x) AND derivable?(f2, x)
                               IMPLIES derivable?(f1 - f2, x)

    neg_derivable      : LEMMA derivable?(f, x) IMPLIES derivable?(- f, x)

    scal_derivable     : LEMMA derivable?(f, x) IMPLIES derivable?(b * f, x)

    const_derivable    : LEMMA derivable?(const_vfun(b), x)

    deriv_sum   	     : LEMMA derivable?(f1, x) AND derivable?(f2, x) IMPLIES
                	          deriv(f1 + f2, x) = deriv(f1, x) + deriv(f2, x)

    deriv_neg   	     : LEMMA derivable?(f, x) IMPLIES 
                	          deriv(- f, x) = - deriv(f, x)

    deriv_diff  	     : LEMMA derivable?(f1, x) AND derivable?(f2, x) IMPLIES
                	             deriv(f1 - f2, x) = deriv(f1, x) - deriv(f2, x)

    deriv_const 	      : LEMMA deriv(const_vfun(b), x) = zero[n]

    deriv_scal  	      : LEMMA derivable?(f, x) IMPLIES deriv(b * f, x) = b * deriv(f, x)

  END deriv_real_vect_def

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

  % Assuming TCC generated (at line 25, column 12) for
      % analysis@derivatives[T]
      % generated from assumption derivatives.deriv_domain
  IMP_derivatives_TCC1: OBLIGATION deriv_domain?[T];

  % Assuming TCC generated (at line 25, column 12) for
      % analysis@derivatives[T]
      % generated from assumption derivatives.not_one_element
  IMP_derivatives_TCC2: OBLIGATION not_one_element?[T];

  % Subtype TCC generated (at line 41, column 68) for  x0
      % expected type  {x | derivable?(LAMBDA (t: T): f(t)(i), x)}
  deriv_TCC1: OBLIGATION
    FORALL (f: [T -> Vector[n]], (x0: {x | derivable?(f, x)}), i: below(n)):
      derivable?[T](LAMBDA (t: T): f(t)(i), x0);

  % Subtype TCC generated (at line 56, column 40) for  x
      % expected type  {x_1 | derivable?(LAMBDA (x: T): f1(x) + f2(x), x_1)}
  deriv_sum_TCC1: OBLIGATION
    FORALL (f1, f2: [T -> Vector[n]], x1: T):
      derivable?(f2, x1) AND derivable?(f1, x1) IMPLIES
       derivable?(LAMBDA (x: T): (+[n])(f1(x), f2(x)), x1);

  % Subtype TCC generated (at line 59, column 36) for  x
      % expected type  {x_1 | derivable?(LAMBDA (x: T): -f(x), x_1)}
  deriv_neg_TCC1: OBLIGATION
    FORALL (f: [T -> Vector[n]], x1: T):
      derivable?(f, x1) IMPLIES derivable?(LAMBDA (x: T): -f(x), x1);

  % Subtype TCC generated (at line 62, column 43) for  x
      % expected type  {x_1 | derivable?(LAMBDA (x: T): f1(x) - f2(x), x_1)}
  deriv_diff_TCC1: OBLIGATION
    FORALL (f1, f2: [T -> Vector[n]], x1: T):
      derivable?(f2, x1) AND derivable?(f1, x1) IMPLIES
       derivable?(LAMBDA (x: T): (-[n])(f1(x), f2(x)), x1);

  % Subtype TCC generated (at line 64, column 50) for  x
      % expected type  {x_1 |
                     %          derivable?(LAMBDA
                     %                     (x):
                     %                     LAMBDA (i: below(n)): b,
                     %                     x_1)}
  deriv_const_TCC1: OBLIGATION
    FORALL (b: real, x: T):
      derivable?(LAMBDA (x_1: T): LAMBDA (i: below(n)): b, x);

  % Subtype TCC generated (at line 66, column 67) for  x
      % expected type  {x_1 | derivable?(LAMBDA (x: T): b * f(x), x_1)}
  deriv_scal_TCC1: OBLIGATION
    FORALL (b: real, f: [T -> Vector[n]], x1: T):
      derivable?(f, x1) IMPLIES derivable?(LAMBDA (x: T): *[n](b, f(x)), x1);


body:
  deriv_sigma[T: TYPE FROM real] : THEORY
  BEGIN

    ASSUMING

      IMPORTING analysis@deriv_domain_def

      deriv_domain     : ASSUMPTION deriv_domain?[T]

      not_one_element  : ASSUMPTION not_one_element?[T]

    ENDASSUMING

    CONVERSION+ singleton

    IMPORTING analysis@derivatives[T], reals@sigma_below, deriv_real_vect_def, reals@sigma_below_sub

    x,y: VAR T
    n: VAR nat 
    m: VAR posnat

    sigma_derivable: LEMMA  
       FORALL (h: [T -> [Index[m] -> real]]):
       (FORALL (i: below[m]): derivable?(LAMBDA (t: T): h(t)(i), y)) IMPLIES
       derivable?((LAMBDA (x: T): sigma(0, m - 1, LAMBDA (i: Index[m]): h(x)(i))), y)

    deriv_sigma: LEMMA n > 0 IMPLIES
       FORALL (h: [T -> [Index[n] -> real]]):
       (FORALL (i: below[n]): derivable?(LAMBDA (t: T): h(t)(i), y))
       IMPLIES
       deriv(LAMBDA (x: T): sigma(0, n - 1, LAMBDA (i: Index[n]): h(x)(i)),y)
          = sigma(0, n - 1, LAMBDA (i: Index[n]): deriv(h, y)(i))

  END deriv_sigma

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

  % Assuming TCC generated (at line 16, column 12) for
      % analysis@derivatives[T]
      % generated from assumption derivatives.deriv_domain
  IMP_derivatives_TCC1: OBLIGATION deriv_domain?[T];

  % Assuming TCC generated (at line 16, column 12) for
      % analysis@derivatives[T]
      % generated from assumption derivatives.not_one_element
  IMP_derivatives_TCC2: OBLIGATION not_one_element?[T];

  % Subtype TCC generated (at line 25, column 38) for  0
      % expected type  T_low[Index[m]]
  sigma_derivable_TCC1: OBLIGATION
    FORALL (m: posnat, y: T, h: [T -> [Index[m] -> real]]):
      (FORALL (i: below[m]): derivable?(LAMBDA (t: T): h(t)(i), y)) IMPLIES
       (FORALL (x: T): 0 >= 0 AND 0 < m OR (EXISTS (j: Index[m]): j <= 0));

  % Subtype TCC generated (at line 25, column 41) for  m - 1
      % expected type  T_high[Index[m]]
  sigma_derivable_TCC2: OBLIGATION
    FORALL (m: posnat, y: T, h: [T -> [Index[m] -> real]]):
      (FORALL (i: below[m]): derivable?(LAMBDA (t: T): h(t)(i), y)) IMPLIES
       (FORALL (x: T):
          m - 1 >= 0 AND m - 1 < m OR (EXISTS (j: Index[m]): m - 1 <= j));

  % Assuming TCC generated (at line 21, column 12) for  reals@sigma[Index[m]]
      % generated from assumption sigma.connected_domain
  sigma_derivable_TCC3: OBLIGATION
    FORALL (m: posnat, y1: T, h: [T -> [Index[m] -> real]]):
      (FORALL (i: below[m]): derivable?(LAMBDA (t: T): h(t)(i), y1)) IMPLIES
       (FORALL (x: T):
          FORALL (x, y: Index[m]), (z: integer):
            x <= z AND z <= y IMPLIES z >= 0 AND z < m);

  % Subtype TCC generated (at line 31, column 32) for  0
      % expected type  T_low[Index[n]]
  deriv_sigma_TCC1: OBLIGATION
    FORALL (n: nat, y: T):
      n > 0 IMPLIES
       (FORALL (h: [T -> [Index[n] -> real]]):
          (FORALL (i: below[n]): derivable?(LAMBDA (t: T): h(t)(i), y))
           IMPLIES
           (FORALL (x: T):
              0 >= 0 AND 0 < n OR (EXISTS (j: Index[n]): j <= 0)));

  % Subtype TCC generated (at line 31, column 35) for  n - 1
      % expected type  T_high[Index[n]]
  deriv_sigma_TCC2: OBLIGATION
    FORALL (n: nat, y: T):
      n > 0 IMPLIES
       (FORALL (h: [T -> [Index[n] -> real]]):
          (FORALL (i: below[n]): derivable?(LAMBDA (t: T): h(t)(i), y))
           IMPLIES
           (FORALL (x: T):
              n - 1 >= 0 AND n - 1 < n OR
               (EXISTS (j: Index[n]): n - 1 <= j)));

  % Assuming TCC generated (at line 21, column 12) for  reals@sigma[Index[n]]
      % generated from assumption sigma.connected_domain
  deriv_sigma_TCC3: OBLIGATION
    FORALL (n: nat, y1: T):
      n > 0 IMPLIES
       (FORALL (h: [T -> [Index[n] -> real]]):
          (FORALL (i: below[n]): derivable?(LAMBDA (t: T): h(t)(i), y1))
           IMPLIES
           (FORALL (x: T):
              FORALL (x, y: Index[n]), (z: integer):
                x <= z AND z <= y IMPLIES z >= 0 AND z < n));

  % Subtype TCC generated (at line 31, column 73) for  y
      % expected type  {x_1 |
                     %          derivable?(LAMBDA
                     %                     (x: T):
                     %                     sigma
                     %                     (0,
                     %                      n - 1,
                     %                      LAMBDA (i: Index[n]): h(x)(i)),
                     %                     x_1)}
  deriv_sigma_TCC4: OBLIGATION
    FORALL (n: nat, y: T):
      n > 0 IMPLIES
       (FORALL (h: [T -> [Index[n] -> real]]):
          (FORALL (i: below[n]): derivable?(LAMBDA (t: T): h(t)(i), y))
           IMPLIES
           derivable?[T]
               (LAMBDA (x: T):
                  sigma[Index[n]](0, n - 1, LAMBDA (i: Index[n]): h(x)(i)),
                y));

  % Subtype TCC generated (at line 32, column 16) for  0
      % expected type  T_low[Index[n]]
  deriv_sigma_TCC5: OBLIGATION
    FORALL (n: nat, y: T):
      n > 0 IMPLIES
       (FORALL (h: [T -> [Index[n] -> real]]):
          (FORALL (i: below[n]): derivable?(LAMBDA (t: T): h(t)(i), y))
           IMPLIES 0 >= 0 AND 0 < n OR (EXISTS (j: Index[n]): j <= 0));

  % Subtype TCC generated (at line 32, column 19) for  n - 1
      % expected type  T_high[Index[n]]
  deriv_sigma_TCC6: OBLIGATION
    FORALL (n: nat, y: T):
      n > 0 IMPLIES
       (FORALL (h: [T -> [Index[n] -> real]]):
          (FORALL (i: below[n]): derivable?(LAMBDA (t: T): h(t)(i), y))
           IMPLIES
           n - 1 >= 0 AND n - 1 < n OR (EXISTS (j: Index[n]): n - 1 <= j));

  % Subtype TCC generated (at line 32, column 57) for  y
      % expected type  {x | derivable?[T, n](h, x)}
  deriv_sigma_TCC7: OBLIGATION
    FORALL (n: nat, y: T):
      n > 0 IMPLIES
       (FORALL (h: [T -> [Index[n] -> real]]):
          (FORALL (i: below[n]): derivable?(LAMBDA (t: T): h(t)(i), y))
           IMPLIES (FORALL (i1: Index[n]): derivable?[T, n](h, y)));

  % Assuming TCC generated (at line 21, column 12) for  reals@sigma[Index[n]]
      % generated from assumption sigma.connected_domain
  deriv_sigma_TCC8: OBLIGATION
    FORALL (n: nat, y1: T):
      n > 0 IMPLIES
       (FORALL (h: [T -> [Index[n] -> real]]):
          (FORALL (i: below[n]): derivable?(LAMBDA (t: T): h(t)(i), y1))
           IMPLIES
           (FORALL (x, y: Index[n]), (z: integer):
              x <= z AND z <= y IMPLIES z >= 0 AND z < n));


body:
  deriv_dot_prod[T: TYPE FROM real, n: posnat ] : THEORY
  BEGIN


    ASSUMING

      IMPORTING analysis@deriv_domain_def

      deriv_domain     : ASSUMPTION deriv_domain?[T]

      not_one_element  : ASSUMPTION not_one_element?[T]

    ENDASSUMING


    IMPORTING analysis@derivatives[T],
              vectors@vectors[n], 
              deriv_real_vect_def[T,n],
              deriv_sigma[T]

    f, f1, f2, fp : VAR [T -> Vector[n]]
    x : VAR T
    u : VAR nzreal
    a,b : VAR real

    dot_prod_derivable  : LEMMA derivable?(f1, x) AND derivable?(f2, x)
                                 IMPLIES derivable?(f1 * f2, x)


    deriv_dot_prod      : LEMMA derivable?(f1, x) AND derivable?(f2, x) IMPLIES
                           deriv(f1 * f2, x) = deriv(f1, x) * f2(x) 
                                               + deriv(f2, x) * f1(x)


  END deriv_dot_prod

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

  % Assuming TCC generated (at line 16, column 12) for
      % analysis@derivatives[T]
      % generated from assumption derivatives.deriv_domain
  IMP_derivatives_TCC1: OBLIGATION deriv_domain?[T];

  % Assuming TCC generated (at line 16, column 12) for
      % analysis@derivatives[T]
      % generated from assumption derivatives.not_one_element
  IMP_derivatives_TCC2: OBLIGATION not_one_element?[T];

  % Subtype TCC generated (at line 31, column 40) for  x
      % expected type  {x_1 | derivable?(LAMBDA (x: T): f1(x) * f2(x), x_1)}
  deriv_dot_prod_TCC1: OBLIGATION
    FORALL (f1, f2: [T -> Vector[n]], x1: T):
      derivable?(f2, x1) AND derivable?(f1, x1) IMPLIES
       derivable?[T](LAMBDA (x: T): *[n](f1(x), f2(x)), x1);


body:
  deriv_real_vect[T: TYPE FROM real, n: posnat ] : THEORY
  %------------------------------------------------------------------------------
  % Derivatives of Vector-Valued Functions
  %
  %    Author:  Rick Butler     NASA Langley Research Center
  %
  %------------------------------------------------------------------------------
  BEGIN


    ASSUMING

      IMPORTING analysis@deriv_domain_def

      deriv_domain     : ASSUMPTION deriv_domain?[T]

      not_one_element  : ASSUMPTION not_one_element?[T]

    ENDASSUMING

    IMPORTING deriv_real_vect_def[T,n], deriv_dot_prod[T,n]

    f, f1, f2, fp : VAR [T -> Vector[n]]
    g : VAR [T -> nzreal]
    x : VAR T
    u : VAR nzreal
    b : VAR real
    l, l1, l2 : VAR real

    h:[T -> real] 

    derivable?(f) : bool = FORALL x : derivable?(f, x)

    deriv_vfun    : TYPE = { f:[T -> Vector[n]] | derivable?(f) }

    nz_deriv_vfun : TYPE = { g:[T -> Nz_vector[n]] | derivable?(g) }

    deriv(ff: deriv_vfun) : [T -> Vector[n]] = LAMBDA x : deriv(ff, x)



    sum_derivable_vfun     : LEMMA derivable?(f1) AND derivable?(f2)
                               IMPLIES derivable?(f1 + f2)

    neg_derivable_vfun     : LEMMA derivable?(f) IMPLIES derivable?(- f)

    diff_derivable_vfun    : LEMMA derivable?(f1) AND derivable?(f2)
                               IMPLIES derivable?(f1 - f2)

  %%  prod_derivable_rv       : LEMMA derivable?(h) IMPLIES derivable?(LAMBDA (x: T): h(x)*f(x))

    dot_derivable_vfun      : LEMMA derivable?(f1) AND derivable?(f2)
                               IMPLIES derivable?(f1 * f2)

    scal_derivable_vfun    : LEMMA derivable?(f) IMPLIES derivable?(b * f)

    const_derivable_vfun   : LEMMA derivable?(const_vfun(b))

    inv_derivable_vfun     : LEMMA derivable?(g) IMPLIES derivable?(1/g)



    ff, ff1, ff2 : VAR deriv_vfun
    hh: VAR deriv_fun[T]   
    derivable_sum    : JUDGEMENT +(ff1, ff2) HAS_TYPE deriv_vfun
    derivable_diff   : JUDGEMENT -(ff1, ff2) HAS_TYPE deriv_vfun
    derivable_scal   : JUDGEMENT *(b, ff) HAS_TYPE deriv_vfun
    derivable_neg    : JUDGEMENT -(ff) HAS_TYPE deriv_vfun
    derivable_const  : JUDGEMENT const_vfun(b) HAS_TYPE deriv_vfun


    %-----------------------------------
    %  Derivative vector-valued function
    %-----------------------------------


    deriv_sum_vfun      : LEMMA deriv(ff1 + ff2) = deriv(ff1) + deriv(ff2)

    deriv_neg_vfun      : LEMMA deriv(- ff) = - deriv(ff)

    deriv_diff_vfun     : LEMMA deriv(ff1 - ff2) = deriv(ff1) - deriv(ff2)

  %%  deriv_prod_vfun     : LEMMA deriv(LAMBDA (x: T): hh(x) * ff1(x)) = deriv(hh)*ff1 + hh*deriv(ff1)

    deriv_dot_vfun      : LEMMA deriv(ff1 * ff2) = deriv(ff1) * ff2 + deriv(ff2) * ff1

    deriv_scal_vfun     : LEMMA deriv(b * ff) = b * deriv(ff)

    deriv_const_vfun    : LEMMA deriv(const_vfun(b)) = const_vfun(0)

  END deriv_real_vect

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

  % Assuming TCC generated (at line 21, column 12) for
      % deriv_real_vect_def[T, n]
      % generated from assumption deriv_real_vect_def.deriv_domain
  IMP_deriv_real_vect_def_TCC1: OBLIGATION deriv_domain?[T];

  % Assuming TCC generated (at line 21, column 12) for
      % deriv_real_vect_def[T, n]
      % generated from assumption deriv_real_vect_def.not_one_element
  IMP_deriv_real_vect_def_TCC2: OBLIGATION not_one_element?[T];

  % Subtype TCC generated (at line 38, column 66) for  x
      % expected type  {x | derivable?(ff, x)}
  deriv_TCC1: OBLIGATION FORALL (ff: deriv_vfun, x): derivable?[T, n](ff, x);

  % Judgement subtype TCC generated (at line 14, column 41) for
      % LAMBDA (x: T): ff1(x) + ff2(x)
      % expected type  deriv_vfun
  derivable_sum: OBLIGATION
    FORALL (ff1, ff2): derivable?(LAMBDA (x: T): (+[n])(ff1(x), ff2(x)));

  % Judgement subtype TCC generated (at line 16, column 41) for
      % LAMBDA (x: T): ff1(x) - ff2(x)
      % expected type  deriv_vfun
  derivable_diff: OBLIGATION
    FORALL (ff1, ff2): derivable?(LAMBDA (x: T): (-[n])(ff1(x), ff2(x)));

  % Judgement subtype TCC generated (at line 17, column 41) for
      % LAMBDA (x: T): b * ff(x)
      % expected type  deriv_vfun
  derivable_scal: OBLIGATION
    FORALL (b, ff): derivable?(LAMBDA (x: T): *[n](b, ff(x)));

  % Judgement subtype TCC generated (at line 15, column 41) for
      % LAMBDA (x: T): -ff(x)
      % expected type  deriv_vfun
  derivable_neg: OBLIGATION FORALL (ff): derivable?(LAMBDA (x: T): -ff(x));

  % Judgement subtype TCC generated (at line 36, column 44) for
      % LAMBDA (x: T): LAMBDA (i: below(n)): b
      % expected type  deriv_vfun
  derivable_const: OBLIGATION
    FORALL (b): derivable?(LAMBDA (x: T): LAMBDA (i: below(n)): b);

  % Subtype TCC generated (at line 19, column 41) for
      % LAMBDA (x: T): ff1(x) * ff2(x)
      % expected type  deriv_fun[T]
  deriv_dot_vfun_TCC1: OBLIGATION
    FORALL (ff1, ff2: deriv_vfun):
      derivable?[T](LAMBDA (x: T): *[n](ff1(x), ff2(x)));


body:
  limit_vect[n,m:posnat]: THEORY
  BEGIN

    IMPORTING vectors@vectors, 
              reals@abs_lems, 
              analysis@epsilon_lemmas

    f, f1, f2: VAR [ Vector[n] -> Vector[m] ]
    a,b,x,v : VAR Vector[n]
    l,l1,l2 : VAR Vector[m]
    epsilon, delta : VAR posreal
    k : VAR real

    ;+(f1, f2)(v) : MACRO Vector[m] = f1(v) + f2(v)
   
    ;-(f)(v): MACRO Vector[m] = -f(v)

    ;-(f1, f2)(v) : MACRO Vector[m] = f1(v) - f2(v)

    ;*(k, f)(v) : MACRO Vector[m] = k*f(v)

    ;*(f1,f2)(v) : MACRO real = f1(v)*f2(v)

    const_fun(l)(x): Vector[m] = l


    %---------------------------------------------------
    %  Convergence of f at a point a towards a limit l
    %--------------------------------------------------

    convergence(f, a, l): bool = 
  	FORALL epsilon : EXISTS delta : 
  	    FORALL v: norm(v-a) < delta        
                   IMPLIES norm(f(v) - l) < epsilon

    cv_unique : LEMMA 
      convergence(f, a, l1) AND convergence(f, a, l2)
        IMPLIES l1 = l2

    cv_in_domain : LEMMA 
      convergence(f, a, l) 
        IMPLIES l = f(a)

    %-------------------------------------------
    %  convergence and operations on functions
    %-------------------------------------------

    cv_sum   : LEMMA 
      convergence(f1, a, l1) AND convergence(f2, a, l2)
        IMPLIES convergence(f1 + f2, a, l1 + l2)

    cv_neg   : LEMMA 
      convergence(f, a, l)
        IMPLIES convergence(-f, a, -l)

    cv_diff  : LEMMA 
      convergence(f1, a, l1) AND convergence(f2, a, l2)
        IMPLIES convergence(f1 - f2, a, l1 - l2)

    cv_const : LEMMA convergence(LAMBDA v: l, a, l)

    cv_scal  : LEMMA 
      convergence(f, a, l) 
        IMPLIES convergence(k*f, a, k*l)

    %-------------------------
    %  f is convergent at a    
    %-------------------------

    convergent?(f, a) : bool = EXISTS l : convergence(f, a, l)

    lim(f, (x0 : {a | convergent?(f, a)})) : Vector[m] =  
          choose(LAMBDA l : convergence(f, x0, l))

    lim_fun_lemma   : LEMMA FORALL f, (x0 : {a | convergent?(f, a)}) :
                            convergence(f, x0, lim(f, x0))

    lim_fun_def     : LEMMA FORALL f, l, (x0 : {a | convergent?(f, a)}) :
                               lim(f, x0) = l IFF convergence(f, x0, l)

    convergence_equiv    : LEMMA convergence(f, a, l) IFF 
                                    convergent?(f, a) AND lim(f, a) = l
         
    convergent_in_domain : LEMMA convergent?(f, x) IFF convergence(f, x, f(x))
         
    lim_in_domain        : LEMMA convergent?(f, x) IMPLIES lim(f, x) = f(x)
         

   %------------------------------------------
   %  Operations preserving convergnce at a 
   %------------------------------------------

    sum_fun_convergent  : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 + f2, a)

    neg_fun_convergent : LEMMA convergent?(f, a) IMPLIES convergent?(- f, a)
         
    diff_fun_convergent : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                                  IMPLIES convergent?(f1 - f2, a)

  %    prod_fun_convergent : LEMMA convergent?(f1, a) AND convergent?(f2, a)
  %                                  IMPLIES convergent?(f1 * f2, a)

    const_fun_convergent: LEMMA convergent?(const_fun(l), a)
         
    scal_fun_convergent : LEMMA convergent?(f, a) IMPLIES convergent?(k * f, a)
          
    %----------------------------
    %  Same things with lim(a)
    %----------------------------
    lim_sum_fun      : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 + f2, a) = lim(f1, a) + lim(f2, a)

    lim_neg_fun : LEMMA convergent?(f, a) 
                               IMPLIES lim(- f, a) = - lim(f, a)
         
    lim_diff_fun     : LEMMA convergent?(f1, a) AND convergent?(f2, a)
                               IMPLIES lim(f1 - f2, a) = lim(f1, a) - lim(f2, a)

  %    lim_prod_fun     : LEMMA convergent?(f1, a) AND convergent?(f2, a)
  %                               IMPLIES lim(f1 * f2, a) = lim(f1, a) * lim(f2, a)

    lim_const_fun    : LEMMA lim(const_fun(l), a) = l

     lim_scal_fun     : LEMMA convergent?(f, a) 
                                IMPLIES lim(k * f, a) = k * lim(f, a)
          
  END limit_vect

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

  % Subtype TCC generated (at line 73, column 15) for
      % LAMBDA l: convergence(f, x0, l)
      % expected type  p: (nonempty?[Vector[m]])
  lim_TCC1: OBLIGATION
    FORALL (f: [Vector[n] -> Vector[m]], (x0: {a | convergent?(f, a)})):
      nonempty?[Vector[m]](LAMBDA l: convergence(f, x0, l));

  % Subtype TCC generated (at line 112, column 50) for  a
      % expected type  {a | convergent?(LAMBDA (v): f1(v) + f2(v), a)}
  lim_sum_fun_TCC1: OBLIGATION
    FORALL (a: Vector[n], f1, f2: [Vector[n] -> Vector[m]]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(LAMBDA (v): (+[m])(f1(v), f2(v)), a);

  % Subtype TCC generated (at line 115, column 46) for  a
      % expected type  {a | convergent?(LAMBDA (v): -f(v), a)}
  lim_neg_fun_TCC1: OBLIGATION
    FORALL (a: Vector[n], f: [Vector[n] -> Vector[m]]):
      convergent?(f, a) IMPLIES convergent?(LAMBDA (v): -f(v), a);

  % Subtype TCC generated (at line 118, column 50) for  a
      % expected type  {a | convergent?(LAMBDA (v): f1(v) - f2(v), a)}
  lim_diff_fun_TCC1: OBLIGATION
    FORALL (a: Vector[n], f1, f2: [Vector[n] -> Vector[m]]):
      convergent?(f2, a) AND convergent?(f1, a) IMPLIES
       convergent?(LAMBDA (v): (-[m])(f1(v), f2(v)), a);

  % Subtype TCC generated (at line 123, column 45) for  a
      % expected type  {a | convergent?(const_fun(l), a)}
  lim_const_fun_TCC1: OBLIGATION
    FORALL (a: Vector[n], l: Vector[m]): convergent?(const_fun(l), a);

  % Subtype TCC generated (at line 126, column 49) for  a
      % expected type  {a | convergent?(LAMBDA (v): k * f(v), a)}
  lim_scal_fun_TCC1: OBLIGATION
    FORALL (a: Vector[n], f: [Vector[n] -> Vector[m]], k: real):
      convergent?(f, a) IMPLIES convergent?(LAMBDA (v): *[m](k, f(v)), a);


body:
  cont_vect[n,m:posnat] : THEORY
  %------------------------------------------------------------------------------
  %  Continuous functions [ Vector[n] -> Vector[m] ]   
  %
  %  Author: Cesar Munoz
  %          Ricky Butler     
  %          NASA Langley Research Center  8/12/2009
  %------------------------------------------------------------------------------
  BEGIN

    IMPORTING vectors@vectors

    IMPORTING limit_vect[n,m]

    f, f1, f2,g    : VAR [Vector[n] -> Vector[m]]
    u              : VAR Vector[m]
    x, x0          : VAR Vector[n]
    epsilon, delta : VAR posreal
   
    %--------------------
    %  Continuity at x0    
    %--------------------

    continuous_vv?(f, x0) : bool = 
  	FORALL epsilon : EXISTS delta : 
  	    FORALL x: norm(x-x0) < delta        
                   IMPLIES norm(f(x) - f(x0)) < epsilon

    continuity_def : LEMMA
          continuous_vv?(f, x0) IFF convergence(f, x0, f(x0))

    continuity_def2 : LEMMA
          continuous_vv?(f, x0) IFF convergent?(f, x0)


   %------------------------------------------
   %  Operations preserving continuity at x0 
   %------------------------------------------

    sum_continuous_vv  : LEMMA continuous_vv?(f1, x0) AND continuous_vv?(f2, x0)
                             IMPLIES continuous_vv?(f1 + f2, x0)

    diff_continuous_vv : LEMMA continuous_vv?(f1, x0) AND continuous_vv?(f2, x0)
                             IMPLIES continuous_vv?(f1 - f2, x0)

    const_continuous_vv: LEMMA continuous_vv?(const_fun(u), x0)

  %%  identity_continuous_vv: LEMMA continuous_vv?((LAMBDA(x):x),x0)

    neg_continuous_vv  : LEMMA continuous_vv?(f, x0) IMPLIES continuous_vv?(- f, x0)

   %---------------------------------
   %  Continuity of f in its domain
   %---------------------------------

    continuous_vv?(f): bool = FORALL x0: continuous_vv?(f, x0)


   %--- Properties ---%

    continuous_vv_fun: TYPE+ = { f | continuous_vv?(f) }

    nz_continuous_vv_fun: TYPE = { g | continuous_vv?(g) }

    h, h1, h2: VAR continuous_vv_fun
    h3: VAR nz_continuous_vv_fun

    sum_fun_continuous_vv : JUDGEMENT  +(h1, h2) HAS_TYPE continuous_vv_fun

    diff_fun_continuous_vv: JUDGEMENT  -(h1, h2) HAS_TYPE continuous_vv_fun

    const_fun_continuous_vv: JUDGEMENT const_fun(u) HAS_TYPE continuous_vv_fun

    neg_fun_continuous_vv : JUDGEMENT -(h) HAS_TYPE continuous_vv_fun


   % ------------ Alternate forms and names for convenience ---------------

    sum_cont_fun  : LEMMA continuous_vv?(f1) AND continuous_vv?(f2)
                             IMPLIES continuous_vv?(f1 + f2)

    diff_cont_fun : LEMMA continuous_vv?(f1) AND continuous_vv?(f2)
                             IMPLIES continuous_vv?(f1 - f2)

    const_cont_fun: LEMMA continuous_vv?(const_fun(u))

    neg_cont_fun  : LEMMA continuous_vv?(f) IMPLIES continuous_vv?(-f)

  %%  id_cont_fun   : LEMMA continuous_vv?((LAMBDA(x):x))

  END cont_vect

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

  % Existence TCC generated (at line 61, column 2) for
      % continuous_vv_fun: TYPE+ = {f | continuous_vv?(f)}
  continuous_vv_fun_TCC1: OBLIGATION
    EXISTS (x: {f | continuous_vv?(f)}): TRUE;

  % Judgement subtype TCC generated (at line 14, column 36) for
      % LAMBDA (v: Vector[n]): h1(v) + h2(v)
      % expected type  continuous_vv_fun
  sum_fun_continuous_vv: OBLIGATION
    FORALL (h1, h2):
      continuous_vv?(LAMBDA (v: Vector[n]): (+[m])(h1(v), h2(v)));

  % Judgement subtype TCC generated (at line 18, column 36) for
      % LAMBDA (v: Vector[n]): h1(v) - h2(v)
      % expected type  continuous_vv_fun
  diff_fun_continuous_vv: OBLIGATION
    FORALL (h1, h2):
      continuous_vv?(LAMBDA (v: Vector[n]): (-[m])(h1(v), h2(v)));

  % Judgement subtype TCC generated (at line 72, column 37) for  const_fun(u)
      % expected type  continuous_vv_fun
  const_fun_continuous_vv: OBLIGATION
    FORALL (u): continuous_vv?(const_fun[n, m](u));

  % Judgement subtype TCC generated (at line 16, column 30) for
      % LAMBDA (v: Vector[n]): -h(v)
      % expected type  continuous_vv_fun
  neg_fun_continuous_vv: OBLIGATION
    FORALL (h): continuous_vv?(LAMBDA (v: Vector[n]): -h(v));


