# TheoryBodies

body:
  min_walks[T: TYPE]: THEORY

  BEGIN

     IMPORTING graphs[T]

     IMPORTING walks[T], abstract_min

     v1,v2,x,y: VAR T
     G: VAR graph[T]

     gr_walk(v1,v2): TYPE = {G: graph[T] | vert(G)(v1) AND vert(G)(v2) AND
                                           (EXISTS (w: Seq(G)):
                                             walk_from?(G,w,v1,v2))}

     min_walk_from(x,y,(Gw:gr_walk(x,y))): Walk(Gw) =
                          min[Seq(Gw),(LAMBDA (w: Seq(Gw)): length(w)),
                                  (LAMBDA (w: Seq(Gw)): walk_from?(Gw,w,x,y))]

     is_min(G,(w: Seq(G)),x,y): bool = walk?(G,w) AND 
                         (FORALL (ww: Seq(G)): walk_from?(G,ww,x,y) IMPLIES 
                                                          length(w) <= length(ww))

     min_walk_def: LEMMA FORALL (Gw: gr_walk(x,y)): 
                            walk_from?(Gw,min_walk_from(x,y,Gw),x,y) AND
                            is_min(Gw, min_walk_from(x,y,Gw),x,y) 
     
     min_walk_in : LEMMA FORALL (Gw: gr_walk(x,y)): 
                            walk_from?(Gw,min_walk_from(x,y,Gw),x,y) 

     min_walk_is_min: LEMMA FORALL (Gw: gr_walk(x,y), ww: Seq(Gw)):
                                walk_from?(Gw,ww,x,y) IMPLIES 
                                          length(min_walk_from(x,y,Gw)) <= length(ww)


  END min_walks

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

  % Assuming TCC generated (at line 17, column 24) for
      % min
      %     [Seq(Gw), (LAMBDA (w: Seq(Gw)): length(w)),
      %      (LAMBDA (w: Seq(Gw)): walk_from?(Gw, w, x, y))]
      % generated from assumption abstract_min.T_ne
  min_walk_from_TCC1: OBLIGATION
    FORALL (x: T, y: T, (Gw: gr_walk(x, y))):
      EXISTS (t: Seq[T](Gw)): walk_from?[T](Gw, t, x, y);

  % Subtype TCC generated (at line 17, column 24) for
      % min
      %     [Seq(Gw), (LAMBDA (w: Seq(Gw)): length(w)),
      %      (LAMBDA (w: Seq(Gw)): walk_from?(Gw, w, x, y))]
      % expected type  Walk[T](Gw)
  min_walk_from_TCC2: OBLIGATION
    FORALL (x: T, y: T, (Gw: gr_walk(x, y))):
      walk?[T]
          (Gw,
           min
               [Seq[T](Gw), LAMBDA (w: Seq[T](Gw)): length(w),
                LAMBDA (w: Seq[T](Gw)): walk_from?[T](Gw, w, x, y)]);

  % Subtype TCC generated (at line 26, column 37) for  min_walk_from(x, y, Gw)
      % expected type  Seq[T](Gw)
  min_walk_def_TCC1: OBLIGATION
    FORALL (x, y: T, Gw: gr_walk(x, y)):
      walk_from?(Gw, min_walk_from(x, y, Gw), x, y) IMPLIES
       verts_in?[T](Gw, min_walk_from(x, y, Gw));


body:
  menger[T: TYPE]: THEORY


  BEGIN

     IMPORTING sep_sets[T], ind_paths[T]

     G: VAR graph[T]
     v,s,t: VAR T
     e: VAR doubleton[T]
     V: VAR finite_set[T]


     k,m: VAR nat
     easy_menger: LEMMA FORALL (ips:  set_of_paths(G,s,t)):
                           separable?(G,s,t) AND
                           ind_path_set?(G,s,t,ips) IMPLIES
                           card(ips) <= sep_num(G,s,t)

     IMPORTING k_menger[T] % FOR PROOF ONLY

     hard_menger: THEOREM  separable?(G,s,t) AND sep_num(G,s,t) = k 
                                AND vert(G)(s) AND vert(G)(t) 
                          IMPLIES
                              (EXISTS (ips: set_of_paths(G,s,t)):
                                     card(ips) = k AND ind_path_set?(G,s,t,ips))
    




  %   menger: THEOREM  separable?(G,s,t) AND vert(G)(s) AND vert(G)(t) 
  %                    IMPLIES
  %                        ( sep_num(G,s,t) = k 
  %                          IFF
  %                            (EXISTS (ips: set_of_paths(G,s,t)):
  %                                   card(ips) = k AND ind_path_set?(G,s,t,ips)))
    


  END menger


body:
  meng_scaff_defs[T: TYPE]: THEORY
  BEGIN

     IMPORTING paths[T], subgraphs[T], sep_sets[T],
               path_ops[T], subgraph_paths[T]

     G,HH: VAR graph[T]
     w1,w2,v,s,t,z: VAR T
     e: VAR doubleton[T]
     V: VAR finite_set[T]
     p: VAR prewalk

     IMPORTING ind_paths[T]

     path_comp(G,(x:T)): Subgraph(G) = subgraph(G,path_verts(G,x))

     IMPORTING graph_deg[T]

     H(G,(x,w1,w2:T)): Subgraph(G) = path_comp(del_vert(del_vert(G,w1),w2),x)
     

     incident(v,G,(x,w1,w2:T)): finite_set[doubleton[T]] 
                = {e: doubleton[T] | (EXISTS z: edges(G)(e) AND e = dbl(v,z) 
                                                AND vert(H(G,x,w1,w2))(z))}

     meng(G,(x,y: (vert(G))),(w1,w2: {t | vert(G)(t) AND t /= y})): graph[T] =
                     (# vert  := add(y,add(w1,add(w2,vert(H(G,x,w1,w2))))),
                        edges := add(dbl(w1,y), add(dbl(w2,y),
                                   union(edges(H(G,x,w1,w2)),
                                         union(incident(w1,G,x,w1,w2),
                                               incident(w2,G,x,w1,w2)))))
                     #)


     in?(G,s,t,w1,w2): bool = vert(G)(s) AND vert(G)(t) AND vert(G)(w1)
                                  AND vert(G)(w2) 
     
     disjoint?(s,t,w1,w2): bool = (s /= t AND w1 /= w2 AND w1 /= s AND w2 /= s 
                                       AND w1 /= t AND w2 /= t) 

     vert_H_s: LEMMA vert(G)(s) AND s /= w1 AND s /= w2
                       IMPLIES vert(H(G, s, w1, w2))(s)


     path_H_W        : LEMMA path?(H(G,s,w1,w2),p) IMPLIES
                                NOT verts_of(p)(w1) AND NOT verts_of(p)(w2)

  %  MOVED TO theory subgraph_paths
  %
  %  walk?_subgraph  : LEMMA subgraph?(HH,G) AND walk?(HH, p)
  %                               IMPLIES walk?(G, p)
  %
  %  path?_subgraph  : LEMMA subgraph?(HH,G) AND path?(HH, p)
  %                                  IMPLIES path?(G, p)

     path_comp_in    : LEMMA path?(H(G,s,w1,w2),p) IMPLIES path?(G,p)

     walk?_H         : LEMMA walk?(G, p) AND seq(p)(0) = s AND
                             NOT verts_of(p)(w1) AND NOT verts_of(p)(w2) 
                           IMPLIES walk?(H(G, s, w1, w2), p)

     vert_meng_sub   : LEMMA in?(G, s, t, w1, w2) AND disjoint?(s, t, w1, w2)
                             IMPLIES subset?(vert(meng(G, s, t, w1, w2)), vert(G))

     del_vert_comm   : LEMMA del_vert(del_vert(G,w2),w1) = 
                                      del_vert(del_vert(G,w1),w2)

     H_comm          : LEMMA H(G, t, w2, w1) = H(G, t, w1, w2)

     incident_comm   : LEMMA incident(v, G, t, w2, w1) = incident(v, G, t, w1, w2)

     meng_comm       : LEMMA vert(G)(s)  AND vert(G)(t) AND
                                vert(G)(w1) AND w1 /= s    AND
                                vert(G)(w2) AND w2 /= s 
                              IMPLIES meng(G, t, s, w1, w2) = meng(G, t, s, w2, w1)


  END meng_scaff_defs

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

  % Subtype TCC generated (at line 19, column 35) for
      % path_comp(del_vert(del_vert(G, w1), w2), x)
      % expected type  Subgraph[T](G)
  H_TCC1: OBLIGATION
    FORALL (G: graph[T], (x, w1, w2: T)):
      subgraph?[T](path_comp(del_vert[T](del_vert[T](G, w1), w2), x), G);

  % Subtype TCC generated (at line 23, column 16) for
      % {e: doubleton[T] |
      %    (EXISTS z:
      %       edges(G)(e) AND e = dbl(v, z) AND vert(H(G, x, w1, w2))(z))}
      % expected type  finite_set[doubleton[T]]
  incident_TCC1: OBLIGATION
    FORALL (v: T, G: graph[T], (x, w1, w2: T)):
      is_finite[doubleton[T]]
          ({e: doubleton[T] |
              EXISTS z:
                edges(G)(e) AND
                 e = dbl[T](v, z) AND vert(H(G, x, w1, w2))(z)});

  % Subtype TCC generated (at line 28, column 35) for  dbl(w1, y)
      % expected type  doubleton[T]
  meng_TCC1: OBLIGATION
    FORALL (G: graph[T], (x, y: (vert(G))),
            (w1, w2: {t | vert(G)(t) AND t /= y})):
      EXISTS (x: T), (y_1: T): x /= y_1 AND dbl[T](w1, y) = dbl[T](x, y_1);

  % Subtype TCC generated (at line 28, column 50) for  dbl(w2, y)
      % expected type  doubleton[T]
  meng_TCC2: OBLIGATION
    FORALL (G: graph[T], (x, y: (vert(G))),
            (w1, w2: {t | vert(G)(t) AND t /= y})):
      EXISTS (x: T), (y_1: T): x /= y_1 AND dbl[T](w2, y) = dbl[T](x, y_1);

  % Subtype TCC generated (at line 27, column 19) for
      % (# vert := add(y, add(w1, add(w2, vert(H(G, x, w1, w2))))),
      %    edges
      %      := add(dbl(w1, y),
      %             add(dbl(w2, y),
      %                 union(edges(H(G, x, w1, w2)),
      %                       union(incident(w1, G, x, w1, w2),
      %                             incident(w2, G, x, w1, w2))))) #)
      % expected type  graph[T]
  meng_TCC3: OBLIGATION
    FORALL (G: graph[T], (x, y: (vert(G))),
            (w1, w2: {t | vert(G)(t) AND t /= y})):
      FORALL (e: doubleton[T]):
        add[doubleton[T]]
            (dbl[T](w1, y),
             add[doubleton[T]]
                 (dbl[T](w2, y),
                  union[doubleton[T]]
                      (edges(H(G, x, w1, w2)),
                       union[doubleton[T]]
                           (incident(w1, G, x, w1, w2),
                            incident(w2, G, x, w1, w2)))))
            (e)
         IMPLIES
         (FORALL (x_1: T):
            e(x_1) IMPLIES
             add[T](y, add[T](w1, add[T](w2, vert(H(G, x, w1, w2)))))(x_1));

  % Subtype TCC generated (at line 58, column 50) for  0
      % expected type  below[p`length]
  walk?_H_TCC1: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T]): walk?(G, p) IMPLIES 0 < p`length;

  % Subtype TCC generated (at line 63, column 56) for  s
      % expected type  (vert(G))
  vert_meng_sub_TCC1: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
      disjoint?(s, t, w1, w2) AND in?(G, s, t, w1, w2) IMPLIES vert(G)(s);

  % Subtype TCC generated (at line 63, column 59) for  t
      % expected type  (vert(G))
  vert_meng_sub_TCC2: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
      disjoint?(s, t, w1, w2) AND in?(G, s, t, w1, w2) IMPLIES vert(G)(t);

  % Subtype TCC generated (at line 63, column 62) for  w1
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  vert_meng_sub_TCC3: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
      disjoint?(s, t, w1, w2) AND in?(G, s, t, w1, w2) IMPLIES
       vert(G)(w1) AND w1 /= t;

  % Subtype TCC generated (at line 63, column 66) for  w2
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  vert_meng_sub_TCC4: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
      disjoint?(s, t, w1, w2) AND in?(G, s, t, w1, w2) IMPLIES
       vert(G)(w2) AND w2 /= t;

  % Subtype TCC generated (at line 75, column 50) for  w1
      % expected type  {t | vert(G)(t) AND t /= s}
  meng_comm_TCC1: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           w2 /= s AND vert(G)(w2) AND w1 /= s AND vert(G)(w1) AND vert(G)(t)
       AND vert(G)(s)
       IMPLIES vert(G)(w1) AND w1 /= s;

  % Subtype TCC generated (at line 75, column 54) for  w2
      % expected type  {t | vert(G)(t) AND t /= s}
  meng_comm_TCC2: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           w2 /= s AND vert(G)(w2) AND w1 /= s AND vert(G)(w1) AND vert(G)(t)
       AND vert(G)(s)
       IMPLIES vert(G)(w2) AND w2 /= s;


body:
  meng_scaff[T: TYPE]: THEORY


  BEGIN

     IMPORTING meng_scaff_defs[T], sep_set_lems[T], min_lem

     G,MM: VAR graph[T]
     v,s,t,w1,w2: VAR T
     W: VAR finite_set[T]
     p: VAR prewalk
     i: VAR nat


    P: VAR pred[T]
    
    ps_ptype(P): TYPE = {ps: prewalk | EXISTS (i: below(length(ps))): P(seq(ps)(i))}

    first(P: pred[T],ps: ps_ptype(P)): below(length(ps)) = 
                    min({i: nat | i < length(ps) AND P(seq(ps)(i))})
    
    first_lem: LEMMA FORALL (ps: ps_ptype(P)): P(seq(ps)(first(P,ps)))
    
    first_not: LEMMA FORALL (ps: ps_ptype(P)): i < first(P,ps) IMPLIES
  					   NOT  P(seq(ps)(i))
    
      
    z: VAR T

    meng_to_G_sep: LEMMA walk_from?(G, p, s, t) AND 
                          in?(G, s, t, w1, w2) AND disjoint?(s, t, w1, w2) AND
                          separates(meng(G, s, t, w1, w2), singleton(z), s, t) AND
                          separable?(G, s, t) AND
                          separates(G, dbl(w1, w2), s, t) AND
                          NOT verts_of(p)(z)
                       IMPLIES sep_num(G, s, t) <= 1

    prep_14: LEMMA  vert(G)(s) AND vert(G)(t) AND
     	      	   vert(G)(w1) AND vert(G)(w2) AND 
                     disjoint?(s, t, w1, w2) AND
                     sep_num(meng(G, s, t, w1, w2),s,t) <= 1 AND
                     separates(meng(G, s, t, w1, w2), dbl(w1, w2), s, t) AND
     	      	   separable?(G, s, t) AND
     	      	   separates(G, dbl(w1, w2), s, t) AND 
                     sep_num(G, s, t) = 2 
                    IMPLIES sep_num(G,s,t) <= 1

     line14: LEMMA separable?(G, s, t) AND
                     in?(G, s, t, w1, w2) AND
                     sep_num(G, s, t) = 2 AND
                     separates(G, dbl(w1, w2), s, t) AND
                     disjoint?(s, t, w1, w2)
                     IMPLIES
                          sep_num(meng(G, s, t, w1, w2), s, t) = 2 


     line15ab: LEMMA  separable?(G,s,t) AND in?(G,s,t,w1,w2)
                      AND sep_num(G,s,t) = 2 
                      AND separates(G, dbl(w1, w2), s, t)
                IMPLIES
                   ((EXISTS (Psw1: prewalk): path_from?(G,Psw1,s,w1)) AND
                    (EXISTS (Psw2: prewalk): path_from?(G,Psw2,s,w2)))


     prep_16: LEMMA separates(G, dbl(w1, w2), s, t) AND
                       disjoint?(s, t, w1, w2) AND
                       (FORALL p: path_from?(G,p,t,w1) IMPLIES verts_of(p)(w2))
                       AND vert(G)(s) AND vert(G)(t)
                       IMPLIES  sep_num(G,s,t) <= 1

     line16: LEMMA NOT edge?(G)(w1, t) AND 
                          disjoint?(s,t,w1,w2) AND
                          separates(G, dbl(w1, w2), s, t) AND
                          sep_num(G,s,t) = 2 AND vert(G)(s) AND vert(G)(t)
                     IMPLIES EXISTS (yt: T): vert(H(G,t,w1,w2))(yt) AND yt /= t

     line19: LEMMA      separable?(G,s,t) AND in?(G,s,t,w1,w2)
                        AND disjoint?(s,t,w1,w2)
                        AND MM = meng(G, s, t, w1, w2)
                        AND separates(G, dbl(w1, w2), s, t)
                        AND path_from?(MM, p, s, t)
                            IMPLIES length(p) > 2 AND (  seq(p)(length(p)-2) = w1
                                                 OR seq(p)(length(p)-2) = w2)
   

     yt: VAR T

     line17_prep: LEMMA vert(G)(s) AND vert(G)(t) AND disjoint?(s,t,w1,w2) AND
                        vert(H(G, t, w1, w2))(yt) AND
                        separates(G, dbl(w1, w2), s, t) IMPLIES
                            NOT vert(H(G, s, w1, w2))(yt)


     line17: LEMMA  vert(H(G,t,w1,w2))(yt) AND
                    in?(G, s, t, w1, w2) AND
                    disjoint?(s, t, w1, w2) AND
                    yt /= t AND
                    separates(G, dbl(w1, w2), s, t) 
                         IMPLIES size(meng(G, s, t, w1, w2)) < size(G)

     pre20: LEMMA separable?(G, s, t) AND
                  in?(G, s, t, w1, w2) AND
                  sep_num(G, s, t) = 2 AND
                  separates(G, dbl(w1, w2), s, t) AND
                  disjoint?(s, t, w1, w2)
                  IMPLIES
             	   ( separable?(meng(G, s, t, w1, w2),s,t) AND
                       sep_num(meng(G, s, t, w1, w2), s, t) = 2 AND
                       vert(meng(G, s, t, w1, w2))(s) AND 
                       vert(meng(G, s, t, w1, w2))(t)                 ) 


  END meng_scaff

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

  % Subtype TCC generated (at line 20, column 22) for
      % {i: nat | i < length(ps) AND P(seq(ps)(i))}
      % expected type  S: (nonempty?[nat])
  first_TCC1: OBLIGATION
    FORALL (P: pred[T], ps: ps_ptype(P)):
      nonempty?[nat]({i: nat | i < length(ps) AND P(seq(ps)(i))});

  % Subtype TCC generated (at line 25, column 23) for  i
      % expected type  below[ps`length]
  first_not_TCC1: OBLIGATION
    FORALL (P: pred[T], i: nat, ps: ps_ptype(P)):
      i < first(P, ps) IMPLIES i < ps`length;

  % Subtype TCC generated (at line 32, column 42) for  s
      % expected type  (vert(G))
  meng_to_G_sep_TCC1: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, t, w1, w2: T):
      walk_from?(G, p, s, t) AND
       in?(G, s, t, w1, w2) AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(s);

  % Subtype TCC generated (at line 32, column 45) for  t
      % expected type  (vert(G))
  meng_to_G_sep_TCC2: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, t, w1, w2: T):
      walk_from?(G, p, s, t) AND
       in?(G, s, t, w1, w2) AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(t);

  % Subtype TCC generated (at line 32, column 48) for  w1
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  meng_to_G_sep_TCC3: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, t, w1, w2: T):
      walk_from?(G, p, s, t) AND
       in?(G, s, t, w1, w2) AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(w1) AND w1 /= t;

  % Subtype TCC generated (at line 32, column 52) for  w2
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  meng_to_G_sep_TCC4: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, t, w1, w2: T):
      walk_from?(G, p, s, t) AND
       in?(G, s, t, w1, w2) AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(w2) AND w2 /= t;

  % Subtype TCC generated (at line 41, column 41) for  w1
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  prep_14_TCC1: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           vert(G)(s) AND vert(G)(t) AND vert(G)(w1) AND vert(G)(w2)
       AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(w1) AND w1 /= t;

  % Subtype TCC generated (at line 41, column 45) for  w2
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  prep_14_TCC2: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           vert(G)(s) AND vert(G)(t) AND vert(G)(w1) AND vert(G)(w2)
       AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(w2) AND w2 /= t;

  % Subtype TCC generated (at line 54, column 40) for  s
      % expected type  (vert(G))
  line14_TCC1: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           disjoint?(s, t, w1, w2) AND separates(G, dbl(w1, w2), s, t)
       AND sep_num(G, s, t) = 2 AND in?(G, s, t, w1, w2)
       AND separable?(G, s, t)
       IMPLIES vert(G)(s);

  % Subtype TCC generated (at line 54, column 43) for  t
      % expected type  (vert(G))
  line14_TCC2: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           disjoint?(s, t, w1, w2) AND separates(G, dbl(w1, w2), s, t)
       AND sep_num(G, s, t) = 2 AND in?(G, s, t, w1, w2)
       AND separable?(G, s, t)
       IMPLIES vert(G)(t);

  % Subtype TCC generated (at line 54, column 46) for  w1
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  line14_TCC3: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           disjoint?(s, t, w1, w2) AND separates(G, dbl(w1, w2), s, t)
       AND sep_num(G, s, t) = 2 AND in?(G, s, t, w1, w2)
       AND separable?(G, s, t)
       IMPLIES vert(G)(w1) AND w1 /= t;

  % Subtype TCC generated (at line 54, column 50) for  w2
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  line14_TCC4: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           disjoint?(s, t, w1, w2) AND separates(G, dbl(w1, w2), s, t)
       AND sep_num(G, s, t) = 2 AND in?(G, s, t, w1, w2)
       AND separable?(G, s, t)
       IMPLIES vert(G)(w2) AND w2 /= t;

  % Subtype TCC generated (at line 79, column 39) for  s
      % expected type  (vert(G))
  line19_TCC1: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
      separable?(G, s, t) AND
       in?(G, s, t, w1, w2) AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(s);

  % Subtype TCC generated (at line 79, column 42) for  t
      % expected type  (vert(G))
  line19_TCC2: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
      separable?(G, s, t) AND
       in?(G, s, t, w1, w2) AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(t);

  % Subtype TCC generated (at line 79, column 45) for  w1
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  line19_TCC3: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
      separable?(G, s, t) AND
       in?(G, s, t, w1, w2) AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(w1) AND w1 /= t;

  % Subtype TCC generated (at line 79, column 49) for  w2
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  line19_TCC4: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
      separable?(G, s, t) AND
       in?(G, s, t, w1, w2) AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(w2) AND w2 /= t;

  % Subtype TCC generated (at line 82, column 62) for  length(p) - 2
      % expected type  below[p`length]
  line19_TCC5: OBLIGATION
    FORALL (G, MM: graph[T], p: prewalk[T], s, t, w1, w2: T):
           path_from?(MM, p, s, t) AND separates(G, dbl(w1, w2), s, t)
       AND MM = meng(G, s, t, w1, w2) AND disjoint?(s, t, w1, w2)
       AND in?(G, s, t, w1, w2) AND separable?(G, s, t) AND length(p) > 2
       IMPLIES length(p) - 2 >= 0 AND length(p) - 2 < p`length;

  % Subtype TCC generated (at line 99, column 44) for  s
      % expected type  (vert(G))
  line17_TCC1: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2, yt: T):
           separates(G, dbl(w1, w2), s, t) AND yt /= t
       AND disjoint?(s, t, w1, w2) AND in?(G, s, t, w1, w2)
       AND vert(H(G, t, w1, w2))(yt)
       IMPLIES vert(G)(s);

  % Subtype TCC generated (at line 99, column 47) for  t
      % expected type  (vert(G))
  line17_TCC2: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2, yt: T):
           separates(G, dbl(w1, w2), s, t) AND yt /= t
       AND disjoint?(s, t, w1, w2) AND in?(G, s, t, w1, w2)
       AND vert(H(G, t, w1, w2))(yt)
       IMPLIES vert(G)(t);

  % Subtype TCC generated (at line 99, column 50) for  w1
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  line17_TCC3: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2, yt: T):
           separates(G, dbl(w1, w2), s, t) AND yt /= t
       AND disjoint?(s, t, w1, w2) AND in?(G, s, t, w1, w2)
       AND vert(H(G, t, w1, w2))(yt)
       IMPLIES vert(G)(w1) AND w1 /= t;

  % Subtype TCC generated (at line 99, column 54) for  w2
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  line17_TCC4: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2, yt: T):
           separates(G, dbl(w1, w2), s, t) AND yt /= t
       AND disjoint?(s, t, w1, w2) AND in?(G, s, t, w1, w2)
       AND vert(H(G, t, w1, w2))(yt)
       IMPLIES vert(G)(w2) AND w2 /= t;


body:
  meng_scaff_prelude[T: TYPE]: THEORY


  BEGIN

     IMPORTING meng_scaff[T], sep_set_lems[T], meng_scaff_defs[T]

     G,MM: VAR graph[T]
     v,s,t,w1,w2: VAR T
     W: VAR finite_set[T]
     p,p1,p2: VAR prewalk
     i,j: VAR nat


     induction_step(G,s,t): bool = FORALL (GG: graph[T]): size(GG) < size(G)
                                 IMPLIES FORALL (s: T, t: T): 
                                            separable?(GG,s,t) AND
                                            sep_num(GG, s, t) = 2 AND
                                            vert(GG)(s) AND vert(GG)(t) 
                                     IMPLIES (EXISTS (p1,p2: prewalk): 
                                                    path_from?(GG,p1,s,t) AND 
                                                    path_from?(GG,p2,s,t) AND
                                                    independent?(p1,p2))
     

     line20: LEMMA separable?(G,s,t) AND in?(G,s,t,w1,w2)
                     AND sep_num(G,s,t) = 2 
                     AND separates(G, dbl(w1, w2), s, t)
                     AND disjoint?(s,t,w1,w2)
                     AND MM = meng(G,s,t,w1,w2)
                     AND induction_step(G,s,t) 
                     AND NOT (edge?(G)(w1,t) AND edge?(G)(w2,t))
                IMPLIES
                    (EXISTS (P1,P2: prewalk): 
                                path_from?(MM,P1,s,t) AND length(P1) > 2 AND
                                path_from?(MM,P2,s,t) AND length(P2) > 2 AND
                                seq(P1)(length(P1)-2) = w1 AND NOT verts_of(P1)(w2) AND
                                seq(P2)(length(P2)-2) = w2 AND NOT verts_of(P2)(w1) AND
                                independent?(P1,P2))      


     Long_walk_from(G,s,v): TYPE = {w: Walk_from(G,s,v) | length(w) > 1} 

     join2(G,s,t,v,(p1: Long_walk_from(G,s,v)),(p2: Walk_from(G,t,v))): 
                                   Walk_from(G,s,t) = p1^(0,length(p1)-2) o rev(p2)
     
     path_meng_t  : LEMMA path_from?(G, p, s, t) AND length(p) > 0 
                             IMPLIES (i < length(p) AND seq(p)(i) = t
                                        IMPLIES i = length(p) - 1)

     path_H_def   : LEMMA path?(H(G,s,w1,w2),p) AND j < length(p) IMPLIES 
                             walk?(del_verts[T](G, dbl[T](w1, w2)), p^(0,j))


     path_H_ind   : LEMMA length(p1) > 1 AND length(p2) > 1 AND
                          path?(H(G,s,w1,w2),trunc1(p1)) AND
                          path?(H(G,t,w1,w2),trunc1(p2)) AND
                          separates(G, dbl(w1, w2), s, t) AND
                          seq(p1)(0) = s AND seq(p2)(0) = t
                        IMPLIES independent?(p1,p2)


     path_comps_ind3: LEMMA length(p1) > 2 AND length(p2) > 2 AND
                               path?(H(G,s,w1,w2),trunc1(trunc1(p1))) AND
                               path?(H(G,t,w1,w2),trunc1(trunc1(p2))) AND
                               separates(G, dbl(w1, w2), s, t) AND
                               seq(p1)(0) = s AND seq(p2)(0) = t
                             IMPLIES independent?(trunc1(p1),trunc1(p2))


     path_H_trunc: LEMMA length(p) >= 2 AND
                      path?(H(G, s, w1, w2), trunc1(p)) AND
                      from?(p, s, w1) AND 
                      edge?(G)(p(length(p)-2),p(length(p)-1)) AND
                      vert(G)(s)  AND w1 /= s AND
                      vert(G)(t)  AND w2 /= s AND
                      vert(G)(w1) AND vert(G)(w2) 
                   IMPLIES
                      path_from?[T](G, p, s, w1) 

     meng_last: LEMMA length(p) > 2 AND
                      vert(G)(s)  AND w1 /= s AND w1 /= t AND
                      vert(G)(t)  AND w2 /= s AND w2 /= t AND
                      vert(G)(w1) AND vert(G)(w2) AND
                      path_from?(meng(G, s, t, w1, w2), p, s, t) 
                    IMPLIES edge?(G)(seq(p)(length(p) - 3), seq(p)(length(p) - 2))

     ind_verts_W: LEMMA path_from?(G,p1,s,t) AND
                        path_from?(G,p2,t,s) AND
                 	      length(p1) > 2 AND seq(p1)(length(p1) - 2) = w1 AND
                 	      length(p2) > 2 AND seq(p2)(length(p2) - 2) = w2 AND
                 	      independent?(p1,p2) AND
                        w1 /= s AND w1 /= t AND
                        w2 /= s AND w2 /= t 
                 IMPLIES NOT verts_of(p1)(w2) AND NOT verts_of(p2)(w1)

    ind_verts_w: LEMMA path_from?(G,p1,s,t) AND
                           path_from?(G,p2,s,t) AND
                    	      length(p1) > 2 AND seq(p1)(length(p1) - 2) = w1 AND
                    	      length(p2) > 2 AND seq(p2)(length(p2) - 2) = w2 AND
                    	      independent?(p1,p2) AND
                           w1 /= s AND w1 /= t AND
                           w2 /= s AND w2 /= t 
                    IMPLIES NOT verts_of(p1)(w2) AND NOT verts_of(p2)(w1)

     path_meng_in: LEMMA length(p) > 2 AND
                         vert(G)(s) AND w1 /= s AND w1 /= t AND
                         vert(G)(t) AND w2 /= s AND w2 /= t AND
                         vert(G)(w1) AND vert(G)(w2) AND
                         path?(meng(G, s, t, w1, w2), p) AND
                         from?(p,s,t) AND
                         ((seq(p)(length(p) - 2) = w1 AND NOT verts_of(p)(w2)) OR
                          (seq(p)(length(p) - 2) = w2 AND NOT verts_of(p)(w1))    )
                     IMPLIES
                        path?(H(G, s, w1, w2), trunc1(trunc1(p)))

     disjoint?(w1,w2: prewalk): bool = (FORALL (i,j: nat): 
                                       i < length(w1)  AND j < length(w2) IMPLIES
                                            seq(w1)(i) /= seq(w2)(j))
   
     join2_lem: LEMMA path_from?(G,p1,s,v) AND path_from?(G,p2,t,v) AND 
                      s /= v AND t /= v AND s /= t AND 
                      disjoint?(trunc1(p1),trunc1(p2))
                         IMPLIES path_from?(G,join2(G,s,t,v,p1,p2),s,t)

     path_from_to_walk_from: LEMMA path_from?(G,p,s,t) IMPLIES
                                       walk_from?(G,p,s,t)

     paths_H_disj: LEMMA path?(H(G, t, w1, w2), p2) AND
                              path?(H(G, s, w1, w2), p1) AND
                              separates(G, dbl(w1, w2), s, t) AND
                              seq(p1)(0) = s AND seq(p2)(0) = t AND s /= t
                         IMPLIES disjoint?(p1,p2)


     
     prelude: LEMMA separates(G, dbl(w1, w2), s, t) AND 
                       separable?(G,s,t) AND 
                       sep_num(G,s,t) = 2 AND 
                       induction_step(G,s,t) AND
                       in?(G,s,t,w1,w2) AND
                       disjoint?(s,t,w1,w2) AND
                       NOT (edge?(G)(w1,s) AND edge?(G)(w2,s)) AND
                       NOT (edge?(G)(w1,t) AND edge?(G)(w2,t)) 
                     IMPLIES
                           (EXISTS (p1,p2: prewalk): path_from?(G,p1,s,t) AND 
                                                    path_from?(G,p2,s,t) AND
                                                    independent?(p1,p2))


  END meng_scaff_prelude

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

  % Subtype TCC generated (at line 30, column 35) for  s
      % expected type  (vert(G))
  line20_TCC1: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           separable?(G, s, t) AND in?(G, s, t, w1, w2)
       AND sep_num(G, s, t) = 2 AND separates(G, dbl(w1, w2), s, t)
       AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(s);

  % Subtype TCC generated (at line 30, column 37) for  t
      % expected type  (vert(G))
  line20_TCC2: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           separable?(G, s, t) AND in?(G, s, t, w1, w2)
       AND sep_num(G, s, t) = 2 AND separates(G, dbl(w1, w2), s, t)
       AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(t);

  % Subtype TCC generated (at line 30, column 39) for  w1
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  line20_TCC3: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           separable?(G, s, t) AND in?(G, s, t, w1, w2)
       AND sep_num(G, s, t) = 2 AND separates(G, dbl(w1, w2), s, t)
       AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(w1) AND w1 /= t;

  % Subtype TCC generated (at line 30, column 42) for  w2
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  line20_TCC4: OBLIGATION
    FORALL (G: graph[T], s, t, w1, w2: T):
           separable?(G, s, t) AND in?(G, s, t, w1, w2)
       AND sep_num(G, s, t) = 2 AND separates(G, dbl(w1, w2), s, t)
       AND disjoint?(s, t, w1, w2)
       IMPLIES vert(G)(w2) AND w2 /= t;

  % Subtype TCC generated (at line 37, column 38) for  length(P1) - 2
      % expected type  below[P1`length]
  line20_TCC5: OBLIGATION
    FORALL (G, MM: graph[T], s, t, w1, w2: T):
           NOT (edge?(G)(w1, t) AND edge?(G)(w2, t))
       AND induction_step(G, s, t) AND MM = meng(G, s, t, w1, w2)
       AND disjoint?(s, t, w1, w2) AND separates(G, dbl(w1, w2), s, t)
       AND sep_num(G, s, t) = 2 AND in?(G, s, t, w1, w2)
       AND separable?(G, s, t)
       IMPLIES
       (FORALL (P1, P2: prewalk[T]):
          length(P2) > 2 AND
           path_from?(MM, P2, s, t) AND
            length(P1) > 2 AND path_from?(MM, P1, s, t)
           IMPLIES length(P1) - 2 >= 0 AND length(P1) - 2 < P1`length);

  % Subtype TCC generated (at line 38, column 38) for  length(P2) - 2
      % expected type  below[P2`length]
  line20_TCC6: OBLIGATION
    FORALL (G, MM: graph[T], s, t, w1, w2: T):
           NOT (edge?(G)(w1, t) AND edge?(G)(w2, t))
       AND induction_step(G, s, t) AND MM = meng(G, s, t, w1, w2)
       AND disjoint?(s, t, w1, w2) AND separates(G, dbl(w1, w2), s, t)
       AND sep_num(G, s, t) = 2 AND in?(G, s, t, w1, w2)
       AND separable?(G, s, t)
       IMPLIES
       (FORALL (P1, P2: prewalk[T]):
               NOT verts_of(P1)(w2) AND seq(P1)(length(P1) - 2) = w1
           AND length(P2) > 2 AND path_from?(MM, P2, s, t) AND length(P1) > 2
           AND path_from?(MM, P1, s, t)
           IMPLIES length(P2) - 2 >= 0 AND length(P2) - 2 < P2`length);

  % Subtype TCC generated (at line 45, column 58) for  length(p1) - 2
      % expected type  nat
  join2_TCC1: OBLIGATION
    FORALL (G: graph[T], s: T, t: T, v: T, (p1: Long_walk_from(G, s, v)),
            (p2: Walk_from[T](G, t, v))):
      length(p1) - 2 >= 0;

  % Subtype TCC generated (at line 45, column 52) for
      % p1 ^ (0, length(p1) - 2) o rev(p2)
      % expected type  Walk_from[T](G, s, t)
  join2_TCC2: OBLIGATION
    FORALL (G: graph[T], s: T, t: T, v: T, (p1: Long_walk_from(G, s, v)),
            (p2: Walk_from[T](G, t, v))):
      length(o[T](^[T](p1, (0, length(p1) - 2)), rev[T](p2))) > 0 AND
       walk_from?[T]
           (G, o[T](^[T](p1, (0, length(p1) - 2)), rev[T](p2)), s, t);

  % Subtype TCC generated (at line 52, column 66) for  p ^ (0, j)
      % expected type  prewalk[T]
  path_H_def_TCC1: OBLIGATION
    FORALL (G: graph[T], j: nat, p: prewalk[T], s, w1, w2: T):
      j < length(p) AND path?(H(G, s, w1, w2), p) IMPLIES
       length(^[T](p, (0, j))) > 0;

  % Subtype TCC generated (at line 56, column 50) for  p1
      % expected type  Longprewalk[T]
  path_H_ind_TCC1: OBLIGATION
    FORALL (p1, p2: prewalk[T]):
      length(p1) > 1 AND length(p2) > 1 IMPLIES length(p1) >= 2;

  % Subtype TCC generated (at line 57, column 50) for  p2
      % expected type  Longprewalk[T]
  path_H_ind_TCC2: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, w1, w2: T):
      length(p1) > 1 AND
       length(p2) > 1 AND path?(H(G, s, w1, w2), trunc1(p1))
       IMPLIES length(p2) >= 2;

  % Subtype TCC generated (at line 59, column 32) for  0
      % expected type  below[p1`length]
  path_H_ind_TCC3: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, w1, w2: T):
           length(p1) > 1 AND length(p2) > 1
       AND path?(H(G, s, w1, w2), trunc1(p1))
       AND path?(H(G, t, w1, w2), trunc1(p2))
       AND separates(G, dbl(w1, w2), s, t)
       IMPLIES 0 < p1`length;

  % Subtype TCC generated (at line 59, column 51) for  0
      % expected type  below[p2`length]
  path_H_ind_TCC4: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, w1, w2: T):
           length(p1) > 1 AND length(p2) > 1
       AND path?(H(G, s, w1, w2), trunc1(p1))
       AND path?(H(G, t, w1, w2), trunc1(p2))
       AND separates(G, dbl(w1, w2), s, t) AND seq(p1)(0) = s
       IMPLIES 0 < p2`length;

  % Subtype TCC generated (at line 64, column 62) for  p1
      % expected type  Longprewalk[T]
  path_comps_ind3_TCC1: OBLIGATION
    FORALL (p1, p2: prewalk[T]):
      length(p1) > 2 AND length(p2) > 2 IMPLIES length(p1) >= 2;

  % Subtype TCC generated (at line 64, column 55) for  trunc1(p1)
      % expected type  Longprewalk[T]
  path_comps_ind3_TCC2: OBLIGATION
    FORALL (p1, p2: prewalk[T]):
      length(p1) > 2 AND length(p2) > 2 IMPLIES length(trunc1[T](p1)) >= 2;

  % Subtype TCC generated (at line 65, column 62) for  p2
      % expected type  Longprewalk[T]
  path_comps_ind3_TCC3: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, w1, w2: T):
      length(p1) > 2 AND
       length(p2) > 2 AND path?(H(G, s, w1, w2), trunc1(trunc1(p1)))
       IMPLIES length(p2) >= 2;

  % Subtype TCC generated (at line 65, column 55) for  trunc1(p2)
      % expected type  Longprewalk[T]
  path_comps_ind3_TCC4: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, w1, w2: T):
      length(p1) > 2 AND
       length(p2) > 2 AND path?(H(G, s, w1, w2), trunc1(trunc1(p1)))
       IMPLIES length(trunc1[T](p2)) >= 2;

  % Subtype TCC generated (at line 67, column 37) for  0
      % expected type  below[p1`length]
  path_comps_ind3_TCC5: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, w1, w2: T):
           length(p1) > 2 AND length(p2) > 2
       AND path?(H(G, s, w1, w2), trunc1(trunc1(p1)))
       AND path?(H(G, t, w1, w2), trunc1(trunc1(p2)))
       AND separates(G, dbl(w1, w2), s, t)
       IMPLIES 0 < p1`length;

  % Subtype TCC generated (at line 67, column 56) for  0
      % expected type  below[p2`length]
  path_comps_ind3_TCC6: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, w1, w2: T):
           length(p1) > 2 AND length(p2) > 2
       AND path?(H(G, s, w1, w2), trunc1(trunc1(p1)))
       AND path?(H(G, t, w1, w2), trunc1(trunc1(p2)))
       AND separates(G, dbl(w1, w2), s, t) AND seq(p1)(0) = s
       IMPLIES 0 < p2`length;

  % Subtype TCC generated (at line 74, column 31) for  length(p) - 2
      % expected type  below[length(p)]
  path_H_trunc_TCC1: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, w1, w2: T):
      length(p) >= 2 AND
       path?(H(G, s, w1, w2), trunc1(p)) AND from?(p, s, w1)
       IMPLIES length(p) - 2 >= 0 AND length(p) - 2 < length(p);

  % Subtype TCC generated (at line 74, column 46) for  length(p) - 1
      % expected type  below[length(p)]
  path_H_trunc_TCC2: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, w1, w2: T):
      length(p) >= 2 AND
       path?(H(G, s, w1, w2), trunc1(p)) AND from?(p, s, w1)
       IMPLIES length(p) - 1 >= 0 AND length(p) - 1 < length(p);

  % Subtype TCC generated (at line 85, column 45) for  w1
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  meng_last_TCC1: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, t, w1, w2: T):
           length(p) > 2 AND vert(G)(s) AND w1 /= s AND w1 /= t AND vert(G)(t)
       AND w2 /= s AND w2 /= t AND vert(G)(w1) AND vert(G)(w2)
       IMPLIES vert(G)(w1) AND w1 /= t;

  % Subtype TCC generated (at line 85, column 49) for  w2
      % expected type  {t_1 | vert(G)(t_1) AND t_1 /= t}
  meng_last_TCC2: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, t, w1, w2: T):
           length(p) > 2 AND vert(G)(s) AND w1 /= s AND w1 /= t AND vert(G)(t)
       AND w2 /= s AND w2 /= t AND vert(G)(w1) AND vert(G)(w2)
       IMPLIES vert(G)(w2) AND w2 /= t;

  % Subtype TCC generated (at line 86, column 42) for  length(p) - 3
      % expected type  below[p`length]
  meng_last_TCC3: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, t, w1, w2: T):
           path_from?(meng(G, s, t, w1, w2), p, s, t) AND vert(G)(w2)
       AND vert(G)(w1) AND w2 /= t AND w2 /= s AND vert(G)(t) AND w1 /= t
       AND w1 /= s AND vert(G)(s) AND length(p) > 2
       IMPLIES length(p) - 3 >= 0 AND length(p) - 3 < p`length;

  % Subtype TCC generated (at line 86, column 65) for  length(p) - 2
      % expected type  below[p`length]
  meng_last_TCC4: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, t, w1, w2: T):
           path_from?(meng(G, s, t, w1, w2), p, s, t) AND vert(G)(w2)
       AND vert(G)(w1) AND w2 /= t AND w2 /= s AND vert(G)(t) AND w1 /= t
       AND w1 /= s AND vert(G)(s) AND length(p) > 2
       IMPLIES length(p) - 2 >= 0 AND length(p) - 2 < p`length;

  % Subtype TCC generated (at line 90, column 49) for  length(p1) - 2
      % expected type  below[p1`length]
  ind_verts_W_TCC1: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t: T):
      path_from?(G, p1, s, t) AND path_from?(G, p2, t, s) AND length(p1) > 2
       IMPLIES length(p1) - 2 >= 0 AND length(p1) - 2 < p1`length;

  % Subtype TCC generated (at line 91, column 49) for  length(p2) - 2
      % expected type  below[p2`length]
  ind_verts_W_TCC2: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, w1: T):
           path_from?(G, p1, s, t) AND path_from?(G, p2, t, s)
       AND length(p1) > 2 AND seq(p1)(length(p1) - 2) = w1 AND length(p2) > 2
       IMPLIES length(p2) - 2 >= 0 AND length(p2) - 2 < p2`length;

  % Subtype TCC generated (at line 99, column 52) for  length(p1) - 2
      % expected type  below[p1`length]
  ind_verts_w_TCC1: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t: T):
      path_from?(G, p1, s, t) AND path_from?(G, p2, s, t) AND length(p1) > 2
       IMPLIES length(p1) - 2 >= 0 AND length(p1) - 2 < p1`length;

  % Subtype TCC generated (at line 100, column 52) for  length(p2) - 2
      % expected type  below[p2`length]
  ind_verts_w_TCC2: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, w1: T):
           path_from?(G, p1, s, t) AND path_from?(G, p2, s, t)
       AND length(p1) > 2 AND seq(p1)(length(p1) - 2) = w1 AND length(p2) > 2
       IMPLIES length(p2) - 2 >= 0 AND length(p2) - 2 < p2`length;

  % Subtype TCC generated (at line 112, column 32) for  length(p) - 2
      % expected type  below[p`length]
  path_meng_in_TCC1: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, t, w1, w2: T):
           length(p) > 2 AND vert(G)(s) AND w1 /= s AND w1 /= t AND vert(G)(t)
       AND w2 /= s AND w2 /= t AND vert(G)(w1) AND vert(G)(w2)
       AND path?(meng(G, s, t, w1, w2), p) AND from?(p, s, t)
       IMPLIES length(p) - 2 >= 0 AND length(p) - 2 < p`length;

  % Subtype TCC generated (at line 115, column 59) for  p
      % expected type  Longprewalk[T]
  path_meng_in_TCC2: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, t, w1, w2: T):
           ((seq(p)(length(p) - 2) = w1 AND NOT verts_of(p)(w2)) OR
             (seq(p)(length(p) - 2) = w2 AND NOT verts_of(p)(w1)))
       AND from?(p, s, t) AND path?(meng(G, s, t, w1, w2), p) AND vert(G)(w2)
       AND vert(G)(w1) AND w2 /= t AND w2 /= s AND vert(G)(t) AND w1 /= t
       AND w1 /= s AND vert(G)(s) AND length(p) > 2
       IMPLIES length(p) >= 2;

  % Subtype TCC generated (at line 115, column 52) for  trunc1(p)
      % expected type  Longprewalk[T]
  path_meng_in_TCC3: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], s, t, w1, w2: T):
           ((seq(p)(length(p) - 2) = w1 AND NOT verts_of(p)(w2)) OR
             (seq(p)(length(p) - 2) = w2 AND NOT verts_of(p)(w1)))
       AND from?(p, s, t) AND path?(meng(G, s, t, w1, w2), p) AND vert(G)(w2)
       AND vert(G)(w1) AND w2 /= t AND w2 /= s AND vert(G)(t) AND w1 /= t
       AND w1 /= s AND vert(G)(s) AND length(p) > 2
       IMPLIES length(trunc1[T](p)) >= 2;

  % Subtype TCC generated (at line 123, column 37) for  p1
      % expected type  Longprewalk[T]
  join2_lem_TCC1: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, v: T):
           path_from?(G, p1, s, v) AND path_from?(G, p2, t, v) AND s /= v
       AND t /= v AND s /= t
       IMPLIES length(p1) >= 2;

  % Subtype TCC generated (at line 123, column 48) for  p2
      % expected type  Longprewalk[T]
  join2_lem_TCC2: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, v: T):
           path_from?(G, p1, s, v) AND path_from?(G, p2, t, v) AND s /= v
       AND t /= v AND s /= t
       IMPLIES length(p2) >= 2;

  % Subtype TCC generated (at line 124, column 58) for  p1
      % expected type  Long_walk_from(G, s, v)
  join2_lem_TCC3: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, v: T):
           disjoint?(trunc1(p1), trunc1(p2)) AND s /= t AND t /= v AND s /= v
       AND path_from?(G, p2, t, v) AND path_from?(G, p1, s, v)
       IMPLIES walk_from?[T](G, p1, s, v) AND length(p1) > 1;

  % Subtype TCC generated (at line 124, column 61) for  p2
      % expected type  Walk_from[T](G, t, v)
  join2_lem_TCC4: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, v: T):
           disjoint?(trunc1(p1), trunc1(p2)) AND s /= t AND t /= v AND s /= v
       AND path_from?(G, p2, t, v) AND path_from?(G, p1, s, v)
       IMPLIES walk_from?[T](G, p2, t, v);

  % Subtype TCC generated (at line 132, column 36) for  0
      % expected type  below[p1`length]
  paths_H_disj_TCC1: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, w1, w2: T):
      path?(H(G, t, w1, w2), p2) AND
       path?(H(G, s, w1, w2), p1) AND separates(G, dbl(w1, w2), s, t)
       IMPLIES 0 < p1`length;

  % Subtype TCC generated (at line 132, column 55) for  0
      % expected type  below[p2`length]
  paths_H_disj_TCC2: OBLIGATION
    FORALL (G: graph[T], p1, p2: prewalk[T], s, t, w1, w2: T):
      path?(H(G, t, w1, w2), p2) AND
       path?(H(G, s, w1, w2), p1) AND
        separates(G, dbl(w1, w2), s, t) AND seq(p1)(0) = s
       IMPLIES 0 < p2`length;


body:
  h_menger[T: TYPE]: THEORY


  BEGIN

     IMPORTING meng_scaff_prelude[T], graph_inductions[T], graph_ops[T], path_ops[T]

     G,MM: VAR graph[T]
     v,s,t,w1,w2,av,ajm,z,x: VAR T
     W: VAR finite_set[T]
     p,p1,p2: VAR prewalk
     e: VAR doubleton[T]

     path_not_thru: LEMMA separable?(G,s,t) AND 
                          sep_num(G,s,t) = 2 AND
                          vert(G)(s) AND vert(G)(t)
                      IMPLIES
                        (FORALL (z: T): z /= s AND z /= t IMPLIES
                          (EXISTS (pn: prewalk): path_from?(del_vert(G,z),pn,s,t)))


    adjacent_fact: LEMMA separates(G, dbl(w1, w2), s, t) AND 
                      separable?(G,s,t) AND 
                      sep_num(G,s,t) = 2 AND
                      in?(G,s,t,w1,w2) AND
                      disjoint?(s,t,w1,w2) AND
                      edge?(G)(w1,s) AND 
                      edge?(G)(w2,s) AND
                      (edge?(G)(w1,s) AND edge?(G)(w1,t))
                    IMPLIES
                            (EXISTS (p1,p2: prewalk): path_from?(G,p1,s,t) AND 
                                                     path_from?(G,p2,s,t) AND
                                                     independent?(p1,p2))


    sep_num_del: LEMMA separable?(G,s,t) AND vert(G)(s) AND vert(G)(t) 
                       AND v /= t AND v /= s IMPLIES
                       sep_num(del_vert(G, v), s, t) <= sep_num(G, s, t)



    separates_del: LEMMA separates(del_vert(G,ajm), singleton(z), s,t) AND
                           vert(G)(ajm) AND vert(G)(s) AND vert(G)(t) AND
                           ajm /= s AND ajm /= t
                         IMPLIES
                             separates(G, dbl(ajm,z), s,t)

    induction_step_comm: LEMMA induction_step(G,s,t) IMPLIES induction_step(G,t,s)

    separable?_del: LEMMA separable?(G,s,t) AND vert(G)(s) AND vert(G)(t) 
                          AND v /= s AND v /= t
                          IMPLIES separable?(del_vert(G, v), s, t) AND
                                  vert(del_vert(G, v))(s) AND 
                                  vert(del_vert(G, v))(t)
   
    seq_j: LEMMA (length(p) > 3 AND edge?(G)(seq(p)(length(p)-2),t) AND
                 NOT edge?(G)(seq(p)(0),t)) IMPLIES 
                   (EXISTS (j: nat): j > 0 AND j < length(p) AND
                                     NOT edge?(G)(seq(p)(j - 1), t)
                                     AND edge?(G)(seq(p)(j), t))
   
    short_path_case: LEMMA vert(G)(x) AND vert(G)(s) AND vert(G)(t) AND
                           edge?(G)(s, x) AND edge?(G)(x, t) AND
                           separable?(G, s, t) AND
                           sep_num(G, s, t) = 2
                       IMPLIES
                    (EXISTS (p1, p2: prewalk):
                      path_from?(G, p1, s, t)
                          AND path_from?(G, p2, s, t) AND independent?(p1, p2))
   
    finale: LEMMA  separable?(G,s,t) AND sep_num(G,s,t) = 2 AND
                   vert(G)(s) AND vert(G)(t) AND
                   induction_step(G,s,t)
                  IMPLIES
                        (EXISTS (p1,p2: prewalk): path_from?(G,p1,s,t) AND 
                                                 path_from?(G,p2,s,t) AND
                                                 independent?(p1,p2))

    h_menger: LEMMA  separable?(G,s,t) AND sep_num(G,s,t) = 2 AND
                        vert(G)(s) AND vert(G)(t) 
                  IMPLIES
                        (EXISTS (p1,p2: prewalk): path_from?(G,p1,s,t) AND 
                                                 path_from?(G,p2,s,t) AND
                                                 independent?(p1,p2))


    hard_menger: LEMMA  separable?(G,s,t) AND sep_num(G,s,t) = 2 AND
                        vert(G)(s) AND vert(G)(t) 
                  IMPLIES
                          (EXISTS (ips: set_of_paths(G,s,t)):
                                   card(ips) = 2 AND ind_path_set?(G,s,t,ips))

  END h_menger

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

  % Subtype TCC generated (at line 56, column 50) for  length(p) - 2
      % expected type  below[p`length]
  seq_j_TCC1: OBLIGATION
    FORALL (p: prewalk[T]):
      length(p) > 3 IMPLIES length(p) - 2 >= 0 AND length(p) - 2 < p`length;

  % Subtype TCC generated (at line 57, column 35) for  0
      % expected type  below[p`length]
  seq_j_TCC2: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], t: T):
      length(p) > 3 AND edge?(G)(seq(p)(length(p) - 2), t) IMPLIES
       0 < p`length;

  % Subtype TCC generated (at line 59, column 55) for  j - 1
      % expected type  below[p`length]
  seq_j_TCC3: OBLIGATION
    FORALL (G: graph[T], p: prewalk[T], t: T):
      NOT edge?(G)(seq(p)(0), t) AND
       edge?(G)(seq(p)(length(p) - 2), t) AND length(p) > 3
       IMPLIES
       (FORALL (j: nat):
          j < length(p) AND j > 0 IMPLIES j - 1 >= 0 AND j - 1 < p`length);


body:
  old_menger[T: TYPE]: THEORY


  BEGIN

     IMPORTING sep_sets[T], ind_paths[T]

     G: VAR graph[T]
     v,s,t: VAR T
     e: VAR doubleton[T]
     V: VAR finite_set[T]


     m: VAR nat
     easy_menger: LEMMA FORALL (ips:  set_of_paths(G,s,t)):
                           separable?(G,s,t) AND
                           ind_path_set?(G,s,t,ips) IMPLIES
                           card(ips) <= sep_num(G,s,t)

     IMPORTING h_menger[T] % FOR PROOF ONLY

     hard_menger: LEMMA  separable?(G,s,t) AND sep_num(G,s,t) = 2 AND
                         vert(G)(s) AND vert(G)(t) 
                     IMPLIES
                          (EXISTS (ips: set_of_paths(G,s,t)):
                                   card(ips) = 2 AND ind_path_set?(G,s,t,ips))



  % --------------------------- PLAY STUFF ------------------------------ %


     easy_meng_1: LEMMA FORALL (ips:  set_of_paths(G,s,t)):
                           separable?(G,s,t) AND
                           ind_path_set?(G,s,t,ips) IMPLIES
                           card(ips) <= sep_num(G,s,t)


  END old_menger


body:
  abstract_max[T: TYPE, N: nat, size: [T -> upto[N]], P: pred[T]]: THEORY
  %------------------------------------------------------------------------------
  %
  %  The need for a function that returns the largest object that
  %  satisfies a particular predicate arises in many contexts.  Thus it is
  %  useful to develop an "abstract" max theory that can be instantiated in
  %  multiple ways to provide different max functions.  Such a theory must
  %  be parameterized by
  %
  %    -------------------------------------------------------------------------
  %    | T: TYPE          | the base type over which max is defined            |
  %    | size:[T -> nat]  | the size function by which objects are compared    |
  %    | P: pred[T]       | the property that the max function must satisfy    |
  %    -------------------------------------------------------------------------
  %
  %  Author:
  %
  %      Ricky W. Butler   NASA Langley
  %
  %  Version 2.0           Last modified 10/21/97
  %
  %  Maintained by:
  %
  %     Rick Butler        NASA Langley Research Center   
  %                        R.W.Butler@larc.nasa.gov
  %
  %------------------------------------------------------------------------------
  BEGIN

     ASSUMING

     T_ne: ASSUMPTION EXISTS (t: T): P(t)

     ENDASSUMING

     IMPORTING max_upto

     TP: TYPE = {t: T | P(t)}


     n: VAR upto[N]

     S,SS: VAR T

     is_one(n): bool = (EXISTS (S: T): P(S) AND size(S) = n)

     prep0: LEMMA nonempty?({n: upto[N] | is_one(n)})

     max_f: upto[N] = max({n: upto[N] | is_one(n)})

     prep1: LEMMA nonempty?({S: T | size(S) = max_f AND P(S)})

     maximal?(S): bool = P(S) AND 
                         (FORALL (SS: T): P(SS) IMPLIES size(S) >= size(SS))

     max: {S: T | maximal?(S)} 


     max_def: LEMMA maximal?(max)

     max_in : LEMMA P(max) 

     max_is_max: LEMMA P(SS) IMPLIES size(max) >= size(SS) 


  END abstract_max

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

  % Subtype TCC generated (at line 49, column 24) for
      % {n: upto[N] | is_one(n)}
      % expected type  S: (nonempty?[upto[N]])
  max_f_TCC1: OBLIGATION nonempty?[upto[N]]({n: upto[N] | is_one(n)});

  % Existence TCC generated (at line 56, column 3) for
      % max: {S: T | maximal?(S)}
  max_TCC1: OBLIGATION EXISTS (x: {S: T | maximal?(S)}): TRUE;


body:
  cycle_deg[T: TYPE]: THEORY

  BEGIN

     IMPORTING cycles[T], trees[T], graph_conn_defs[T], graph_connected[T],
               graph_deg_sum[T], tree_circ[T], graph_complected[T],
               tree_paths[T], subgraph_paths[T]

     G,H: VAR graph[T]
     n: VAR nat
     x,y,s,t: VAR T 
     w,p,q: VAR prewalk

     reachable(G: graph[T],x:T): finite_set[T] = 
                        {y: T |  vert(G)(y) AND 
                              (EXISTS (w: Seq(G)): walk_from?(G,w,x,y))}

     reachable_subset: LEMMA subset?(reachable(G,x),vert(G))

     reachable_conn: LEMMA FORALL (x:(vert(G))):
  	 connected?(subgraph(G,reachable(G,x)))


      conn_compon: LEMMA FORALL (G: graph[T], x: (vert(G))): EXISTS H:
                        (subgraph?(H,G) AND 
  	                connected?(H) and vert(H)(x) and 
  	                  FORALL (y:(vert(H))): (deg(y,G)=deg(y,H)))  



      sub_cycle: LEMMA FORALL (G,H: graph[T], w: Seq(H)): subgraph?(H,G) 
                                  and cycle?(H,w) IMPLIES cycle?(G,w)


      uniq_paths?(G):bool = FORALL (s,t,p,q): path_from?(G,p,s,t) AND
                                 path_from?(G,q,s,t) IMPLIES   p=q

      uniq_del_vert: LEMMA FORALL (G:graph[T], v:(vert(G))): uniq_paths?(G) 
                                IMPLIES uniq_paths?(del_vert(G,v))

      del_edge_uniq: LEMMA FORALL (G:graph[T], e:(edges(G))): 
                          connected?(del_edge(G,e)) IMPLIES NOT uniq_paths?(G) 

      charact_tree: LEMMA connected?(G) AND uniq_paths?(G) IMPLIES tree?(G)


      exclus_cycl: THEOREM connected?(G) IMPLIES 
                           tree?(G) XOR (EXISTS (w:Seq(G)): cycle?(G,w))

      num_edge_tree: LEMMA connected?(G) and num_edges(G)<size(G) 
  	IMPLIES tree?(G)
  	

      iff_tree: LEMMA tree?(G) IFF connected?(G) AND uniq_paths?(G)
    
      tree_num_iff: LEMMA connected?(G) and num_edges(G)=size(G)-1 IFF tree?(G)


      deg_gt_1_cycle: LEMMA  (FORALL (v: T): vert(G)(v) IMPLIES deg(v,G) > 1)
                              IMPLIES (EXISTS (w: Seq(G)): cycle?(G,w)) OR 
                            empty?(G)
                                          

  END cycle_deg

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

  % Subtype TCC generated (at line 15, column 22) for
      % {y: T | vert(G)(y) AND (EXISTS (w: Seq(G)): walk_from?(G, w, x, y))}
      % expected type  finite_set[T]
  reachable_TCC1: OBLIGATION
    FORALL (G: graph[T], x: T):
      is_finite[T]
          ({y: T |
              vert(G)(y) AND
               (EXISTS (w: Seq[T](G)): walk_from?[T](G, w, x, y))});

  % Subtype TCC generated (at line 32, column 65) for  w
      % expected type  Seq[T](G)
  sub_cycle_TCC1: OBLIGATION
    FORALL (G, H: graph[T], w: Seq[T](H)):
      subgraph?(H, G) AND cycle?(H, w) IMPLIES verts_in?[T](G, w);


body:
  reduce_walks[T: TYPE]: THEORY

  BEGIN

     IMPORTING paths[T]

     G: VAR graph[T]

     Long_walk(G): TYPE = {w: Walk(G) | length(w) > 3}

     reduce(G: graph[T], w: Long_walk(G), 
            k: {n: nat | n > 0 AND n < length(w)-1}): Walk(G) =
                        IF w(k-1) = w(k+1) THEN
                            (# length := length(w) - 2,
                            seq := (LAMBDA (i: below(length(w)-2)):
                                       IF i < k THEN w(i)
                                       ELSE w(i+2)
                                       ENDIF) #) 
                        ELSE
                            w
                        ENDIF

     reduce_lem: LEMMA FORALL (w: Walk(G), 
                              k: {n: nat | n > 0 AND n < length(w)-1}):
         w(k-1) = w(k+1) AND length(w) > 3 IMPLIES
            reduce(G,w,k) = w^(0,k-1) o w^(k+2,length(w)-1)
              

  END reduce_walks

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

  % Subtype TCC generated (at line 13, column 27) for  k - 1
      % expected type  below[length(w)]
  reduce_TCC1: OBLIGATION
    FORALL (G: graph[T], w: Long_walk(G),
            k: {n: nat | n > 0 AND n < length(w) - 1}):
      k - 1 >= 0 AND k - 1 < length(w);

  % Subtype TCC generated (at line 13, column 36) for  k + 1
      % expected type  below[length(w)]
  reduce_TCC2: OBLIGATION
    FORALL (G: graph[T], w: Long_walk(G),
            k: {n: nat | n > 0 AND n < length(w) - 1}):
      k + 1 < length(w);

  % Subtype TCC generated (at line 14, column 39) for  length(w) - 2
      % expected type  nat
  reduce_TCC3: OBLIGATION
    FORALL (G: graph[T], w: Long_walk(G),
            k: {n: nat | n > 0 AND n < length(w) - 1}):
      finseq_appl[T](w)(k - 1) = finseq_appl[T](w)(k + 1) IMPLIES
       length(w) - 2 >= 0;

  % Subtype TCC generated (at line 16, column 53) for  i
      % expected type  below[length(w)]
  reduce_TCC4: OBLIGATION
    FORALL (G: graph[T], w: Long_walk(G),
            k: {n: nat | n > 0 AND n < length(w) - 1}):
      finseq_appl[T](w)(k - 1) = finseq_appl[T](w)(k + 1) IMPLIES
       (FORALL (i: below(length(w) - 2)): i < k IMPLIES i < length(w));

  % Subtype TCC generated (at line 17, column 44) for  i + 2
      % expected type  below[length(w)]
  reduce_TCC5: OBLIGATION
    FORALL (G: graph[T], w: Long_walk(G),
            k: {n: nat | n > 0 AND n < length(w) - 1}):
      finseq_appl[T](w)(k - 1) = finseq_appl[T](w)(k + 1) IMPLIES
       (FORALL (i: below(length(w) - 2)):
          NOT i < k IMPLIES i + 2 < length(w));

  % Subtype TCC generated (at line 14, column 26) for
      % (# length := length(w) - 2,
      %    seq
      %      := (LAMBDA (i: below(length(w) - 2)):
      %            IF i < k THEN finseq_appl[T](w)(i)
      %            ELSE finseq_appl[T](w)(i + 2)
      %            ENDIF) #)
      % expected type  Walk[T](G)
  reduce_TCC6: OBLIGATION
    FORALL (G: graph[T], w: Long_walk(G),
            k: {n: nat | n > 0 AND n < length(w) - 1}):
      finseq_appl[T](w)(k - 1) = finseq_appl[T](w)(k + 1) IMPLIES
       length(w) - 2 > 0 AND
        walk?[T]
            (G,
             (# length := length(w) - 2,
                seq
                  := (LAMBDA (i: below(length(w) - 2)):
                        IF i < k THEN finseq_appl[T](w)(i)
                        ELSE finseq_appl[T](w)(i + 2)
                        ENDIF) #));

  % Subtype TCC generated (at line 25, column 9) for  k - 1
      % expected type  below[length(w)]
  reduce_lem_TCC1: OBLIGATION
    FORALL (G: graph[T], w: Walk[T](G),
            k: {n: nat | n > 0 AND n < length(w) - 1}):
      k - 1 >= 0 AND k - 1 < length(w);

  % Subtype TCC generated (at line 25, column 18) for  k + 1
      % expected type  below[length(w)]
  reduce_lem_TCC2: OBLIGATION
    FORALL (G: graph[T], w: Walk[T](G),
            k: {n: nat | n > 0 AND n < length(w) - 1}):
      k + 1 < length(w);

  % Subtype TCC generated (at line 26, column 31) for  k - 1
      % expected type  nat
  reduce_lem_TCC3: OBLIGATION
    FORALL (G: graph[T], w: Walk[T](G),
            k: {n: nat | n > 0 AND n < length(w) - 1}):
      finseq_appl[T](w)(k - 1) = finseq_appl[T](w)(k + 1) AND length(w) > 3
       IMPLIES k - 1 >= 0;

  % Subtype TCC generated (at line 26, column 45) for  length(w) - 1
      % expected type  nat
  reduce_lem_TCC4: OBLIGATION
    FORALL (G: graph[T], w: Walk[T](G),
            k: {n: nat | n > 0 AND n < length(w) - 1}):
      finseq_appl[T](w)(k - 1) = finseq_appl[T](w)(k + 1) AND length(w) > 3
       IMPLIES length(w) - 1 >= 0;


body:
  min_walk_reduced[T: TYPE]: THEORY

  BEGIN

     IMPORTING min_walks[T], path_ops[T]

     reduced?(G: graph[T], w: Seq(G)): bool = 
            (FORALL (k: nat): k > 0 AND k < length(w) - 1 IMPLIES w(k-1) /= w(k+1))

     x,y: VAR T
     i: VAR nat
     min_walk_vert: LEMMA FORALL (Gw: gr_walk(x,y)): i < length(min_walk_from(x,y,Gw))
                                 IMPLIES vert(Gw)(min_walk_from(x,y,Gw)(i))

     min_walk_is_reduced: LEMMA FORALL (Gw: gr_walk(x,y)):
                                       reduced?(Gw,min_walk_from(x,y,Gw))

  END min_walk_reduced

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

  % Subtype TCC generated (at line 8, column 66) for  k - 1
      % expected type  below[length(w)]
  reduced?_TCC1: OBLIGATION
    FORALL (G: graph[T], w: Seq[T](G), k: nat):
      k > 0 AND k < length(w) - 1 IMPLIES k - 1 >= 0 AND k - 1 < length(w);

  % Subtype TCC generated (at line 8, column 76) for  k + 1
      % expected type  below[length(w)]
  reduced?_TCC2: OBLIGATION
    FORALL (G: graph[T], w: Seq[T](G), k: nat):
      k > 0 AND k < length(w) - 1 IMPLIES k + 1 < length(w);

  % Subtype TCC generated (at line 16, column 49) for  min_walk_from(x, y, Gw)
      % expected type  Seq[T](Gw)
  min_walk_is_reduced_TCC1: OBLIGATION
    FORALL (x, y: T, Gw: gr_walk[T](x, y)):
      verts_in?[T](Gw, min_walk_from[T](x, y, Gw));


body:
  ramsey_new[T: TYPE]: THEORY
  BEGIN
    IMPORTING graphs[T], subgraphs[T]
    i, j: VAR T

    n, p, q, ii: VAR nat   

  %  g: VAR graph[T]
    g: VAR graph[T]
    V: VAR finite_set[T]

    contains_clique(g, n): bool =
        (EXISTS (C: finite_set[T]):
          subset?(C,vert(g)) AND card(C) >= n AND
            (FORALL i,j: i/=j AND C(i) AND C(j) IMPLIES edge?(g)(i,j)))

    contains_indep(g, n): bool =
        (EXISTS (D: finite_set[T]):
          subset?(D, vert(g)) AND card(D) >= n AND
           (FORALL i, j: i/=j AND D(i) AND D(j) IMPLIES NOT edge?(g)(i, j)))

    subgraph_clique: LEMMA (FORALL (V: set[T]): 
                               contains_clique(subgraph(g, V), p)
                               IMPLIES contains_clique(g, p))

    subgraph_indep : LEMMA (FORALL (V: set[T]): 
                               contains_indep(subgraph(g, V), p)
                               IMPLIES contains_indep(g, p))

    G: VAR Graph[T]   % finite and nonempty

    r1(G): finite_set[T] = (LET v0 = choose(vert(G)) IN
             { n: T | vert(G)(n) AND n /= v0 AND edge?(G)(v0,n)})

    r2(G): finite_set[T] = (LET v0 = choose(vert(G)) IN
             { n: T | vert(G)(n) AND n /= v0 AND NOT edge?(G)(v0,n)})


    SG1(G): graph[T] = subgraph(G, r1(G))

    SG2(G): graph[T] = subgraph(G, r2(G))

    v0: VAR nat
    card_r1_r2: LEMMA card(r1(G)) + card(r2(G)) >= size(G) - 1

  %  ramsey(p, q): RECURSIVE posnat =
  %         (IF p=0
  %          THEN 1
  %          ELSIF q=0
  %             THEN 1
  %             ELSE (ramsey(p-1,q)+ramsey(p, q-1))
  %             ENDIF)
  %  MEASURE p+q

    ramsey(p, q): posnat 

    l1,l2: VAR nat

    ramsey_lem: LEMMA (FORALL l1,l2: l1+l2=ii IMPLIES
        (EXISTS (n: posnat):
            (FORALL (G: Graph[T]): size(G) >= n
                IMPLIES (contains_clique(G, l1) OR
                         contains_indep(G, l2)))))


    ramseys_theorem: THEOREM (EXISTS (n: posnat):
                                 (FORALL (G: Graph[T]): size(G) >= n
                                     IMPLIES (contains_clique(G, l1) OR
                                              contains_indep(G, l2))))



  END ramsey_new

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

  % Subtype TCC generated (at line 32, column 42) for  vert(G)
      % expected type  p: (nonempty?[T])
  r1_TCC1: OBLIGATION FORALL (G: Graph[T]): nonempty?[T](vert(G));

  % Subtype TCC generated (at line 33, column 11) for
      % {n: T | vert(G)(n) AND n /= v0 AND edge?(G)(v0, n)}
      % expected type  finite_set[T]
  r1_TCC2: OBLIGATION
    FORALL (G: Graph[T], v0: (vert(G))):
      v0 = choose(vert(G)) IMPLIES
       is_finite[T]({n: T | vert(G)(n) AND n /= v0 AND edge?[T](G)(v0, n)});

  % Subtype TCC generated (at line 36, column 11) for
      % {n: T | vert(G)(n) AND n /= v0 AND NOT edge?(G)(v0, n)}
      % expected type  finite_set[T]
  r2_TCC1: OBLIGATION
    FORALL (G: Graph[T], v0: (vert(G))):
      v0 = choose(vert(G)) IMPLIES
       is_finite[T]
           ({n: T | vert(G)(n) AND n /= v0 AND NOT edge?[T](G)(v0, n)});


body:
  graph_from_edges[T: TYPE]: THEORY
  %----------------------------------------------------------------------------
  %
  % Author:  Christian van der Stap
  %          Technical University of Eindhoven
  %          Netherlands
  %
  %          Jon Sjogren, AFOSR
  %
  %----------------------------------------------------------------------------
  BEGIN
     IMPORTING graphs

     ES: VAR finite_set[doubleton[T]]
     N, M: VAR nat   
     x,y: VAR T

     finite_lem: LEMMA is_finite(Union(ES))

     Union_to_pred: LEMMA FORALL x: Union(ES)(x) 
                            => EXISTS (d: doubleton[T]): ES(d) AND d(x)

     pred_to_Union: LEMMA FORALL x: (EXISTS (d: doubleton[T]): ES(d) AND d(x))
  	                  => Union(ES)(x)


     verts_of(ES): finite_set[T] = Union(ES)


     verts_from(ES): finite_set[T] = {t:T | EXISTS (d: doubleton[T]): 
                                          d(t) AND ES(d)}

     verts_from_of: LEMMA verts_of(ES) = verts_from(ES)

     G: VAR graph[T]
     v: VAR T
     isolated_vert?(G,v): bool = NOT member(v, verts_of(edges(G)))


     es_graph: TYPE = {G: graph[T] | FORALL (v: (vert(G))):
                                         NOT isolated_vert?(G,v)}

     graph_from_edgeset(ES): es_graph =
               (# vert := verts_of(ES),
                  edges := ES
               #)

     graph_from_edgeset_rew1: LEMMA edges(graph_from_edgeset(ES))= ES
     graph_from_edgeset_rew2: LEMMA vert(graph_from_edgeset(ES))= verts_of(ES)

     no_isolated_verts: LEMMA Let G = graph_from_edgeset(ES) IN 
                              vert(G)(v) IMPLIES
                                 NOT isolated_vert?(G,v)



  END graph_from_edges

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

  % Subtype TCC generated (at line 27, column 33) for
      % Union(extend[setof[T], doubleton[T], bool, FALSE](ES))
      % expected type  finite_set[T]
  verts_of_TCC1: OBLIGATION
    FORALL (ES: finite_set[doubleton[T]]):
      is_finite[T](Union[T](extend[setof[T], doubleton[T], bool, FALSE](ES)));

  % Subtype TCC generated (at line 30, column 35) for
      % {t: T | EXISTS (d: doubleton[T]): d(t) AND ES(d)}
      % expected type  finite_set[T]
  verts_from_TCC1: OBLIGATION
    FORALL (ES: finite_set[doubleton[T]]):
      is_finite[T]({t: T | EXISTS (d: doubleton[T]): d(t) AND ES(d)});

  % Subtype TCC generated (at line 44, column 13) for
      % (# vert := verts_of(ES), edges := ES #)
      % expected type  es_graph
  graph_from_edgeset_TCC1: OBLIGATION
    FORALL (ES: finite_set[doubleton[T]]):
      (FORALL (e: doubleton[T]):
         ES(e) IMPLIES (FORALL (x: T): e(x) IMPLIES verts_of(ES)(x)))
       AND
       (FORALL (v: (verts_of(ES))):
          NOT isolated_vert?((# vert := verts_of(ES), edges := ES #), v));


body:
  % Andre Luiz Galdino
  % Federal University of Goais, Brazil 
  % <galdino@unb.br>
  %
  % The following theorem of group theory are formalized:
  %
  % - Cauchy Theorem;
  % - Isomorphism Theorems;
  % - Burside Theorem;
  % - Sylow Theorems;
  % - New version of the Lagrange Theorem;
  % - A variation of the fundamental principle of counting;
  % - A variation of the formula for permutation with repetition;
  % - Group Action, stabilizer, orbit, normalizer, centralizer, index of a  
  %   subgroup in a group, and properties;
  % - Class Equation;
  % - p-groups and properties;
  % - Product of Subgroups;
  % - New version of the Zn Group, left (right) cosets, factor group and  
  %   properties.

  top[T: TYPE, *: [T,T -> T], one: T]: THEORY

  BEGIN
     ASSUMING IMPORTING algebra@group_def

         T_is_group: ASSUMPTION group?[T,*,one](fullset[T])

     ENDASSUMING

     IMPORTING sylow_theorems[T, *, one]

  END top

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

  % Assuming TCC generated (at line 31, column 13) for
      % sylow_theorems[T, *, one]
      % generated from assumption sylow_theorems.T_is_group
  IMP_sylow_theorems_TCC1: OBLIGATION group?[T, *, one](fullset[T]);


body:
  %%-------------------** Fundamental Counting Principle and Permutations with Repetition  **-------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%------------------------------------------------------------------------------------------------------


  cauchy_scaf[T:TYPE]: THEORY

  BEGIN


     IMPORTING structures@seq_extras[T],
               finite_sets@finite_sets_eq,
               finite_sets@finite_sets_card_eq

         S: VAR finite_set[finseq]
         M: VAR finite_set[T]
         a: VAR T
         n: VAR nat
         p: VAR posnat

    
   add_element(S)(a): set[finseq] = {seq: finseq | EXISTS (s: (S)): seq = add_first(a, s)}

   add_set(S)(M): setofsets[finseq] = {C: set[finseq] | EXISTS (a: (M)): C = add_element(S)(a)}

   set_seq(M)(n): set[finseq] = {seq: finseq | length(seq) = n AND 
                                               FORALL (i: below[n]): member(seq(i), M)}


   emptyset_gives_emptyset: LEMMA empty?(S) IMPLIES empty?(add_element(S)(a))

   emptyset_gives_emptyset1: LEMMA empty?(M) IMPLIES empty?(add_set(S)(M))

   set_seq_singleton: LEMMA set_seq(M)(0) = singleton(empty_seq)

   set_seq_empty: LEMMA  empty?(M) IMPLIES empty?(set_seq(M)(p))

   add_element_add_set: LEMMA NOT member(a, M) IMPLIES 
                          LET B = add_set(S)(M),
                              A = add_element(S)(a) IN
                          Union(add_set(S)(add(a, M)))= union(Union(B), A)

   card_add_element_aux: LEMMA 
                           LET A = add_element(S)(a) IN
                           EXISTS (g:[(A)->(S)]): bijective?(g)


   card_add_element: LEMMA 
                           LET A = add_element(S)(a) IN
                           card(A) = card(S)
   
   disjoint_add_set: LEMMA 
                       LET B = add_set(S)(M),
                           A = add_element(S)(a) IN
                         NOT member(a, M) IMPLIES disjoint?(Union(B),A)

   add_set_is_add_ele: LEMMA 
                         LET B = add_set(S)(M),
                             A = add_element(S)(a) IN
                         M = singleton(a) IMPLIES Union(B) = A

   add_set_is_finite_aux: LEMMA
                           nonempty?(S) IMPLIES
                              LET B = add_set(S)(M) IN
                              EXISTS (g:[(M)->(B)]): bijective?(g)

   add_set_is_finite: LEMMA
                       LET B = add_set(S)(M) IN
                       is_finite(B)

  %%%%% Fundamental Counting Principle %%%%%

   card_add_set: LEMMA 
                    LET B = add_set(S)(M) IN
                    card(Union(B)) = card(S)*card(M)


   set_seq_is_finite: LEMMA 
                        LET C = set_seq(M)(n) IN
                        is_finite(C)

   set_seq_is_add_set: LEMMA 
                          LET C = set_seq(M)(p),
                              D = set_seq(M)(p-1) IN
                          C = Union(add_set(D)(M))

  %%%%% Permutations with Repetition %%%%%

   card_set_seq: LEMMA 
                      LET C = set_seq(M)(n) IN
                      card(C) = card(M)^n

  END cauchy_scaf

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

  % Subtype TCC generated (at line 33, column 78) for  i
      % expected type  below[length(seq)]
  set_seq_TCC1: OBLIGATION
    FORALL (n: nat, seq: finseq[T]):
      length(seq) = n IMPLIES (FORALL (i: below[n]): i < length(seq));

  % Subtype TCC generated (at line 56, column 30) for  A
      % expected type  S: finite_set[finseq[T]]
  card_add_element_TCC1: OBLIGATION
    FORALL (S: finite_set[finseq], a: T, A: set[finseq[T]]):
      A = add_element(S)(a) IMPLIES is_finite[finseq[T]](A);

  % Subtype TCC generated (at line 81, column 23) for  Union(B)
      % expected type  S: finite_set[finseq[T]]
  card_add_set_TCC1: OBLIGATION
    FORALL (M: finite_set[T], S: finite_set[finseq],
            B: setofsets[finseq[T]]):
      B = add_set(S)(M) IMPLIES is_finite[finseq[T]](Union[finseq[T]](B));

  % Subtype TCC generated (at line 90, column 43) for  p - 1
      % expected type  nat
  set_seq_is_add_set_TCC1: OBLIGATION
    FORALL (M: finite_set[T], p: posnat, C: set[finseq[T]]):
      C = set_seq(M)(p) IMPLIES p - 1 >= 0;

  % Subtype TCC generated (at line 91, column 42) for  D
      % expected type  finite_set[finseq]
  set_seq_is_add_set_TCC2: OBLIGATION
    FORALL (M: finite_set[T], p: posnat, C: set[finseq[T]]):
      C = set_seq(M)(p) IMPLIES
       (FORALL (D: set[finseq[T]]):
          D = set_seq(M)(p - 1) IMPLIES is_finite[finseq[T]](D));

  % Subtype TCC generated (at line 97, column 25) for  C
      % expected type  S: finite_set[finseq[T]]
  card_set_seq_TCC1: OBLIGATION
    FORALL (M: finite_set[T], n: nat, C: set[finseq[T]]):
      C = set_seq(M)(n) IMPLIES is_finite[finseq[T]](C);

  % Subtype TCC generated (at line 97, column 38) for  n
      % expected type  {i: int | card(M) /= 0 OR i >= 0}
  card_set_seq_TCC2: OBLIGATION
    FORALL (M: finite_set[T], n: nat, C: set[finseq[T]]):
      C = set_seq(M)(n) IMPLIES card[T](M) /= 0 OR n >= 0;


body:
  %%-------------------** Zn Group **-------------------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%----------------------------------------------------------


  zp_group[n:posnat]: THEORY

  BEGIN


    IMPORTING algebra@group
    

     Zn: set[below(n)] = {m: nat | m < n};

    ++(a,b: below(n)): below(n) = rem(n)(a+b)

     Zn_group: LEMMA group?[below(n), ++, 0](Zn)

     Zn_finite: LEMMA is_finite(Zn)

     Zn_card: LEMMA card(Zn) = n


  END zp_group

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

  % Subtype TCC generated (at line 24, column 40) for  0
      % expected type  below(n)
  Zn_group_TCC1: OBLIGATION 0 < n;

  % Existence TCC generated (at line 24, column 19) for
      % group?[below(n), ++, 0]
  Zn_group_TCC2: OBLIGATION EXISTS (x: below(n)): TRUE;

  % Subtype TCC generated (at line 28, column 23) for  Zn
      % expected type  S: finite_set[below(n)]
  Zn_card_TCC1: OBLIGATION is_finite[below(n)](Zn);


body:
  %%-------------------** Right, left cosets and some properties **-------------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%----------------------------------------------------------------------------------

  right_left_cosets[T:Type,*:[T,T->T],one:T]: THEORY


  BEGIN

     ASSUMING IMPORTING algebra@group_def[T,*,one]

         fullset_is_group: ASSUMPTION group?(fullset[T])

     ENDASSUMING

     IMPORTING algebra@lagrange[T,*,one], 
               algebra@factor_groups,
               finite_sets@finite_sets_eq[T,T],
               finite_sets@finite_sets_card_eq

     G,H, N: VAR group
       a, b: VAR T
   

   
     left_cosets(G:group, H:subgroup(G)): setofsets[T] = {s: set[T] | EXISTS (a: (G)): s = a*H}

     right_cosets(G:group, H:subgroup(G)): setofsets[T] = {s: set[T] | EXISTS (a: (G)): s = H*a}


  %%%%%%%%%

     nonempty_left_coset: LEMMA  subgroup?(H,G) AND member(a,G) IMPLIES
                                                   nonempty?(left_coset(G,H)(a))

   
     left_coset_finite: LEMMA 
         FORALL (G:finite_group): subgroup?(H,G) AND member(a,G) IMPLIES
                                 is_finite(left_coset(G,H)(a))


     left_coset_correspondence: LEMMA 
          FORALL (A:set[T]): subgroup?(H,G) AND member(a,G) AND A = left_coset(G,H)(a)
            IMPLIES
               EXISTS (f:[(H)->(A)]): bijective?(f)

     left_coset_correspondence_inv: LEMMA 
         subgroup?(H,G) AND member(a,G)
            IMPLIES
               EXISTS (f:[(H)->(a*H*inv(a))]): bijective?(f) 


     finite_left_coset_correspondence: LEMMA 
          FORALL (G:finite_group): subgroup?(H,G) AND member(a,G) AND member(b,G) 
            IMPLIES
                 card(left_coset(G,H)(a)) = card(left_coset(G,H)(b))


     set_left_cosets_full: LEMMA FORALL (H: subgroup(G)): Union(left_cosets(G,H)) = G


     left_cosets_disjoint: LEMMA FORALL (H: subgroup(G), A,B: left_cosets(G, H)):
                                       A = B OR disjoint?(A,B)

     left_cosets_partition: LEMMA FORALL (G:finite_group, H: subgroup(G)):
                                      finite_partition?[T](left_cosets(G, H))


     set_right_cosets_full_1: LEMMA FORALL (H: subgroup(G)): Union(right_cosets(G,H)) = G


     right_left_correspondence: LEMMA  
       subgroup?(H,G) IMPLIES
             EXISTS (f:[(right_cosets(G, H)) -> (left_cosets(G,H))]): bijective?(f)


     finite_right_left_correspondence: LEMMA  
          FORALL (G:finite_group): subgroup?(H,G) 
           IMPLIES
            card[set[T]](right_cosets(G,H)) = card[set[T]](left_cosets(G,H))


  %% index of H in G is the number of left (right) cosets of H in G %%

     index(G:finite_group, H:subgroup(G)): nat = card[set[T]](left_cosets(G, H))

     index_gt1: LEMMA FORALL (G:finite_group, H:subgroup(G)): index(G,H) >= 1

  ;%% define G/N as set of all left cosets of N in G

     /(G: group[T,*,one], N: normal_subgroup(G)): group[left_cosets(G,N),mult(G,N),N] = left_cosets(G, N)


  ;%% order of G/N

     card_factor: LEMMA finite_group?(G) AND normal_subgroup?(N, G)
                                IMPLIES card[set[T]](G/N) = index(G,N)


  END right_left_cosets

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

  % Assuming TCC generated (at line 22, column 13) for
      % algebra@lagrange[T, *, one]
      % generated from assumption lagrange.fullset_is_group
  IMP_lagrange_TCC1: OBLIGATION group?[T, *, one](fullset[T]);

  % Subtype TCC generated (at line 40, column 75) for  a
      % expected type  (G)
  nonempty_left_coset_TCC1: OBLIGATION
    FORALL (G, H: group[T, *, one], a: T):
      member(a, G) AND subgroup?(H, G) IMPLIES G(a);

  % Subtype TCC generated (at line 45, column 57) for  a
      % expected type  (G)
  left_coset_finite_TCC1: OBLIGATION
    FORALL (H: group[T, *, one], a: T, G: finite_group[T, *, one]):
      subgroup?(H, G) AND member(a, G) IMPLIES G(a);

  % Subtype TCC generated (at line 62, column 20) for  left_coset(G, H)(a)
      % expected type  S: finite_set[T]
  finite_left_coset_correspondence_TCC1: OBLIGATION
    FORALL (H: group[T, *, one], a, b: T, G: finite_group[T, *, one]):
      subgroup?(H, G) AND member(a, G) AND member(b, G) IMPLIES
       is_finite[T](left_coset[T, *, one](G, H)(a));

  % Subtype TCC generated (at line 62, column 63) for  b
      % expected type  (G)
  finite_left_coset_correspondence_TCC2: OBLIGATION
    FORALL (H: group[T, *, one], a, b: T, G: finite_group[T, *, one]):
      subgroup?(H, G) AND member(a, G) AND member(b, G) IMPLIES G(b);

  % Subtype TCC generated (at line 62, column 47) for  left_coset(G, H)(b)
      % expected type  S: finite_set[T]
  finite_left_coset_correspondence_TCC3: OBLIGATION
    FORALL (H: group[T, *, one], a, b: T, G: finite_group[T, *, one]):
      subgroup?(H, G) AND member(a, G) AND member(b, G) IMPLIES
       is_finite[T](left_coset[T, *, one](G, H)(b));

  % Subtype TCC generated (at line 86, column 23) for  right_cosets(G, H)
      % expected type  S: finite_set[set[T]]
  finite_right_left_correspondence_TCC1: OBLIGATION
    FORALL (H: group[T, *, one], G: finite_group[T, *, one]):
      subgroup?(H, G) IMPLIES is_finite[set[T]](right_cosets(G, H));

  % Subtype TCC generated (at line 86, column 57) for  left_cosets(G, H)
      % expected type  S: finite_set[set[T]]
  finite_right_left_correspondence_TCC2: OBLIGATION
    FORALL (H: group[T, *, one], G: finite_group[T, *, one]):
      subgroup?(H, G) IMPLIES is_finite[set[T]](left_cosets(G, H));

  % Subtype TCC generated (at line 91, column 60) for  left_cosets(G, H)
      % expected type  S: finite_set[set[T]]
  index_TCC1: OBLIGATION
    FORALL (G: finite_group[T, *, one], H: subgroup[T, *, one](G)):
      is_finite[set[T]](left_cosets(G, H));

  % Subtype TCC generated (at line 97, column 48) for
      % group[left_cosets(G, N), mult(G, N), N]
      % expected type  left_cosets[T, *, one](G, N)
  divide_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], N: normal_subgroup(G)):
      EXISTS (a: (G)): N = *[T, *, one](a, N);

  % Assuming TCC generated (at line 97, column 48) for
      % group[left_cosets(G, N), mult(G, N), N]
      % generated from assumption group.fullset_is_group
  divide_TCC2: OBLIGATION
    FORALL (G: group[T, *, one], N: normal_subgroup(G)):
      group?[left_cosets(G, N), mult(G, N), N](fullset[left_cosets(G, N)]);

  % Existence TCC generated (at line 97, column 48) for
      % group[left_cosets(G, N), mult(G, N), N]
  divide_TCC3: OBLIGATION
    FORALL (G: group[T, *, one], N: normal_subgroup(G)):
      EXISTS (x: left_cosets[T, *, one](G, N)): TRUE;

  % Subtype TCC generated (at line 97, column 101) for  N
      % expected type  subgroup[T, *, one](G)
  divide_TCC4: OBLIGATION
    FORALL (G: group[T, *, one], N: normal_subgroup[T, *, one](G)):
      subgroup?[T, *, one](N, G);

  % Subtype TCC generated (at line 97, column 86) for
      % restrict[setof[T], left_cosets[T, *, one](G, N), boolean]
      %     (left_cosets(G, N))
      % expected type  group[left_cosets(G, N), mult(G, N), N]
  divide_TCC5: OBLIGATION
    FORALL (G: group[T, *, one], N: normal_subgroup[T, *, one](G)):
      group?[left_cosets[T, *, one](G, N), mult[T, *, one](G, N), N]
          (restrict[setof[T], left_cosets[T, *, one](G, N), boolean]
               (left_cosets(G, N)));

  % Subtype TCC generated (at line 103, column 51) for
      % extend[set[T], left_cosets[T, *, one](G, N), bool, FALSE](G / N)
      % expected type  S: finite_set[set[T]]
  card_factor_TCC1: OBLIGATION
    FORALL (G, N: group[T, *, one]):
      normal_subgroup?(N, G) AND finite_group?(G) IMPLIES
       is_finite[set[T]]
           (extend[set[T], left_cosets[T, *, one](G, N), bool, FALSE](G / N));

  % Subtype TCC generated (at line 103, column 66) for  N
      % expected type  subgroup[T, *, one](G)
  card_factor_TCC2: OBLIGATION
    FORALL (G, N: group[T, *, one]):
      normal_subgroup?(N, G) AND finite_group?(G) IMPLIES
       subgroup?[T, *, one](N, G);


body:
  %%-------------------** Properties of divides and gcd **----------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%----------------------------------------------------------------


  general_properties: THEORY

  BEGIN


    IMPORTING ints@gcd,
              ints@gcd_fractions,
              numbers@unique_factorization,
              numbers@product_perm_lems,
              numbers@eq_mod,
              structures@fseqs[posnat],
              structures@fseqs_ops_def

        x, y, z, m: VAR int
        i, p, q, k: VAR posnat
              j, n: VAR nat
                fs: VAR fseq

    
  %%%%% Definitions %%%%%

     seq_power(p,i): fseq = (# length := i,
                                  seq := (LAMBDA (j: nat): IF j < i THEN p ELSE default ENDIF) #)

     only_power_p(fs, p):  bool = FORALL (j: below(fs`length)): EXISTS (i: nat): fs`seq(j) = p^i


  %%%%% Properties %%%%%

     divides_element: LEMMA
       divides(x, y + z) AND divides(x, y) IMPLIES  divides(x, z)

     divides_rel_primes: LEMMA divides(x,k*y) AND gcd(x,k) = 1 IMPLIES divides(x,y)

     divides_product: LEMMA FORALL (j: below(fs`length)): divides(fs`seq(j), product(fs))

     product_power: LEMMA p^i = product(seq_power(p,i))

     product_only_power: LEMMA only_power_p(fs, p) IMPLIES 
                                EXISTS (n: nat): product(fs) = p^n

     divides_power: LEMMA  divides(p, p^i) 
                                      
     divides_prime_power: LEMMA prime?(p) AND divides(q, p^j) 
                                        IMPLIES (EXISTS (i: nat): i <= j AND q = p^i)


     gcd_1: LEMMA gcd(m,1) = 1

     gcd_1_nd: LEMMA prime?(p) AND gcd(m,p) = 1 IMPLIES (NOT divides(p,m))

     gcd_1_ndp: LEMMA prime?(p) AND gcd(m,p) = 1 AND m = x*y IMPLIES (NOT divides(p,x) AND NOT divides(p,y))
     
     gcd_1_gcd_1: LEMMA prime?(p) AND gcd(m,p) = 1 AND m = x*y IMPLIES gcd(x,p) = 1 AND gcd(y,p) = 1


  END general_properties

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

  % Subtype TCC generated (at line 34, column 40) for
      % (LAMBDA (j: nat): IF j < i THEN p ELSE default ENDIF)
      % expected type  barray[posnat](i)
  seq_power_TCC1: OBLIGATION
    FORALL (p: posnat, i: posnat):
      FORALL (i_1: nat):
        i_1 >= i IMPLIES
         IF i_1 < i THEN p ELSE default[posnat] ENDIF = default[posnat];

  % Subtype TCC generated (at line 36, column 93) for  i
      % expected type  {i: int | p /= 0 OR i >= 0}
  only_power_p_TCC1: OBLIGATION
    FORALL (fs: fseq[posnat], p: posnat, j: below(fs`length), i: nat):
      p /= 0 OR i >= 0;

  % Subtype TCC generated (at line 44, column 54) for  k
      % expected type  {jj: int | x = 0 => jj /= 0}
  divides_rel_primes_TCC1: OBLIGATION
    FORALL (k: posnat, x, y: int): divides(x, k * y) IMPLIES x = 0 => k /= 0;

  % Subtype TCC generated (at line 48, column 26) for  i
      % expected type  {i: int | p /= 0 OR i >= 0}
  product_power_TCC1: OBLIGATION FORALL (i, p: posnat): p /= 0 OR i >= 0;

  % Subtype TCC generated (at line 51, column 63) for  n
      % expected type  {i: int | p /= 0 OR i >= 0}
  product_only_power_TCC1: OBLIGATION
    FORALL (fs: fseq[posnat], p: posnat):
      only_power_p(fs, p) IMPLIES (FORALL (n: nat): p /= 0 OR n >= 0);

  % Subtype TCC generated (at line 55, column 57) for  j
      % expected type  {i: int | p /= 0 OR i >= 0}
  divides_prime_power_TCC1: OBLIGATION
    FORALL (j: nat, p: posnat): prime?(p) IMPLIES p /= 0 OR j >= 0;

  % Subtype TCC generated (at line 56, column 81) for  i
      % expected type  {i: int | p /= 0 OR i >= 0}
  divides_prime_power_TCC2: OBLIGATION
    FORALL (j: nat, p, q: posnat):
      divides(q, p ^ j) AND prime?(p) IMPLIES
       (FORALL (i: nat): i <= j IMPLIES p /= 0 OR i >= 0);

  % Subtype TCC generated (at line 59, column 22) for  1
      % expected type  {jj: int | m = 0 => jj /= 0}
  gcd_1_TCC1: OBLIGATION FORALL (m: int): m = 0 => 1 /= 0;

  % Subtype TCC generated (at line 61, column 39) for  p
      % expected type  {jj: int | m = 0 => jj /= 0}
  gcd_1_nd_TCC1: OBLIGATION
    FORALL (m: int, p: posnat): prime?(p) IMPLIES m = 0 => p /= 0;

  % Subtype TCC generated (at line 65, column 75) for  p
      % expected type  {jj: int | x = 0 => jj /= 0}
  gcd_1_gcd_1_TCC1: OBLIGATION
    FORALL (m: int, p: posnat, x, y: int):
      m = x * y AND gcd(m, p) = 1 AND prime?(p) IMPLIES x = 0 => p /= 0;

  % Subtype TCC generated (at line 65, column 92) for  p
      % expected type  {jj: int | y = 0 => jj /= 0}
  gcd_1_gcd_1_TCC2: OBLIGATION
    FORALL (m: int, p: posnat, x, y: int):
      m = x * y AND gcd(m, p) = 1 AND prime?(p) AND gcd(x, p) = 1 IMPLIES
       y = 0 => p /= 0;


body:
  %%-------------------** Some properties of groups and subgroups  **-------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%------------------------------------------------------------------------------


  groups_scaf[T: TYPE, *: [T,T -> T], one: T]: THEORY

  BEGIN

     ASSUMING IMPORTING algebra@group_def[T,*,one]

         fullset_is_group: ASSUMPTION group?(fullset[T])

     ENDASSUMING

    IMPORTING algebra@group,
              algebra@factor_groups,
              algebra@finite_groups[T,*,one],
              general_properties,
              right_left_cosets

        G, H, N, K: VAR group
           a, b, c: VAR T
              p, k: VAR posnat
                 m: VAR int
                 i: VAR nat

  %%%%% Definitions %%%%%

    subgroup_contain(G: group, N: subgroup(G)): TYPE = {H: group | subgroup?(H,G) AND subset?(N, H)}



  %%%%% Properties of groups and subgroups %%%%%

     divby_r: LEMMA a = b * c  IFF a * inv[T,*,one](c)  = b

     subgroup_transitive: LEMMA subgroup?(H,G) AND  subgroup?(K,H)
                                  IMPLIES subgroup?(K,G)

     normal_subgroup_tran: LEMMA subgroup?(H,G) AND subgroup?(N,H) AND
                            normal_subgroup?(N,G)
                                  IMPLIES normal_subgroup?(N,H)

     subgroup_intersection: LEMMA  subgroup?(H,G) AND subgroup?(K,G) 
                                  IMPLIES subgroup?(intersection(H,K),G)

     conjugate_is_subgroup: LEMMA FORALL (a: (G), H:subgroup(G)): subgroup?(a*H*inv(a),G)

     center_is_normal: LEMMA  normal_subgroup?(center(G),G)

     abelian_eq_center: LEMMA abelian_group?(G) IFF G = center(G)


     order_gt_1: LEMMA FORALL (G:finite_group): 
                        prime?(p) AND divides(p, order(G)) IMPLIES order(G) > 1
    
     order_gt_p: LEMMA FORALL (G:finite_group): 
                        prime?(p) AND divides(p, order(G)) IMPLIES order(G) >= p

     exists_diff_one: LEMMA FORALL (G:finite_group):
                                   order(G) > 1 IMPLIES EXISTS (x: (G)): x /= one

     one_iff_divides: LEMMA FORALL (G:finite_group, a:(G)): 
                               a^m = one IFF divides(period(G,a), m)

     order_power: LEMMA FORALL (G:finite_group, a:(G)): 
                                 LET n = period(G,a) IN
                                 period(G,a^k) = n / gcd(k,n)


     coset_power_nat: LEMMA FORALL (x:(G), H:normal_subgroup(G)): 
                               ^[left_cosets(G,H),mult(G,H),H](x*H, i) = (x^i)*H

     coset_power_int: LEMMA FORALL (x:(G), H:normal_subgroup(G)): 
                               ^[left_cosets(G,H),mult(G,H),H](x*H, m) = (x^m)*H
  END groups_scaf

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

  % Assuming TCC generated (at line 24, column 12) for
      % algebra@finite_groups[T, *, one]
      % generated from assumption finite_groups.fullset_is_group
  IMP_finite_groups_TCC1: OBLIGATION group?[T, *, one](fullset[T]);

  % Subtype TCC generated (at line 56, column 45) for  center(G)
      % expected type  group[T, *, one]
  center_is_normal_TCC1: OBLIGATION
    FORALL (G: group[T, *, one]): group?[T, *, one](center[T, *, one](G));

  % Subtype TCC generated (at line 75, column 40) for  a ^ k
      % expected type  (G)
  order_power_TCC1: OBLIGATION
    FORALL (k: posnat, G: finite_group[T, *, one], a: (G), n: posnat):
      n = period(G, a) IMPLIES G(^[T, *, one](a, k));

  % Subtype TCC generated (at line 75, column 57) for  n
      % expected type  {jj: int | k = 0 => jj /= 0}
  order_power_TCC2: OBLIGATION
    FORALL (k: posnat, G: finite_group[T, *, one], a: (G), n: posnat):
      n = period(G, a) IMPLIES k = 0 => n /= 0;

  % Subtype TCC generated (at line 79, column 61) for  x * H
      % expected type  left_cosets[T, *, one](G, H)
  coset_power_nat_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], x: (G), H: normal_subgroup[T, *, one](G)):
      EXISTS (a: (G)): *[T, *, one](x, H) = *[T, *, one](a, H);

  % Subtype TCC generated (at line 79, column 58) for  H
      % expected type  left_cosets[T, *, one](G, H)
  coset_power_nat_TCC2: OBLIGATION
    FORALL (G: group[T, *, one], x: (G), H: normal_subgroup[T, *, one](G)):
      EXISTS (a: (G)): H = *[T, *, one](a, H);

  % Assuming TCC generated (at line 45, column 7) for
      % algebra@group[left_cosets(G, H), mult(G, H), H]
      % generated from assumption group.fullset_is_group
  coset_power_nat_TCC3: OBLIGATION
    FORALL (G: group[T, *, one], x: (G), H: normal_subgroup[T, *, one](G)):
      group?[left_cosets[T, *, one](G, H), mult(G, H), H]
          (fullset[left_cosets[T, *, one](G, H)]);

  % Existence TCC generated (at line 79, column 29) for
      % ^[left_cosets(G, H), mult(G, H), H]
  coset_power_nat_TCC4: OBLIGATION
    FORALL (G: group[T, *, one], x: (G), H: normal_subgroup[T, *, one](G)):
      EXISTS (x1: left_cosets[T, *, one](G, H)): TRUE;


body:
  %%----------------------------------------------------------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%----------------------------------------------------------------


  class_equation_scaf[D, T:TYPE]: THEORY

  BEGIN


     IMPORTING algebra@lagrange_scaf[T], 
               sigma_set@sigma_set[finite_set[T]] 
   

        FP:  VAR finite_partition
         A: VAR finite_set[D]
         B: VAR finite_set[T]
  m, n, x : VAR int



  card_rest_aux: LEMMA nonempty?(FP) IMPLIES 
                         card(Union(FP)) = card(choose(FP)) + card(Union(rest(FP)))
   

  card_partition: LEMMA (nonempty?(FP) AND FORALL (A: (FP)): card(A) /= 0) IMPLIES 
                               card(Union(FP)) = sigma_set.sigma(FP, card)


  divide_sigma: LEMMA (nonempty?(FP) AND 
                            FORALL (A: (FP)): card(A) /= 0 AND divides(n, card(A))) IMPLIES 
                               divides(n,sigma_set.sigma(FP, card))

  END class_equation_scaf

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

  % Subtype TCC generated (at line 29, column 28) for  Union(FP)
      % expected type  S: finite_set[T]
  card_rest_aux_TCC1: OBLIGATION
    FORALL (FP: finite_partition[T]):
      nonempty?(FP) IMPLIES is_finite[T](Union[T](FP));

  % Subtype TCC generated (at line 29, column 46) for  choose(FP)
      % expected type  S: finite_set[T]
  card_rest_aux_TCC2: OBLIGATION
    FORALL (FP: finite_partition[T]):
      nonempty?(FP) IMPLIES is_finite[T](choose[setof[T]](FP));

  % Subtype TCC generated (at line 29, column 65) for  Union(rest(FP))
      % expected type  S: finite_set[T]
  card_rest_aux_TCC3: OBLIGATION
    FORALL (FP: finite_partition[T]):
      nonempty?(FP) IMPLIES is_finite[T](Union[T](rest[setof[T]](FP)));

  % Subtype TCC generated (at line 32, column 64) for  A
      % expected type  S: finite_set[T]
  card_partition_TCC1: OBLIGATION
    FORALL (FP: finite_partition[T]):
      nonempty?(FP) IMPLIES (FORALL (A: (FP)): is_finite[T](A));

  % Subtype TCC generated (at line 33, column 67) for  card
      % expected type  (convergent?(restrict[setof[T], finite_set[T], boolean]
                     %                  (FP)))
  card_partition_TCC2: OBLIGATION
    FORALL (FP: finite_partition[T]):
      (FORALL (A: (FP)): card(A) /= 0) AND nonempty?(FP) IMPLIES
       convergent?[finite_set[T]]
           (restrict[setof[T], finite_set[T], boolean](FP))(card[T]);

  % Subtype TCC generated (at line 38, column 59) for  card
      % expected type  (convergent?(restrict[setof[T], finite_set[T], boolean]
                     %                  (FP)))
  divide_sigma_TCC1: OBLIGATION
    FORALL (FP: finite_partition[T], n: int):
      (FORALL (A: (FP)): card(A) /= 0 AND divides(n, card(A))) AND
       nonempty?(FP)
       IMPLIES
       convergent?[finite_set[T]]
           (restrict[setof[T], finite_set[T], boolean](FP))(card[T]);

  % Subtype TCC generated (at line 38, column 39) for
      % sigma_set.sigma(restrict[setof[T], finite_set[T], boolean](FP), card)
      % expected type  int
  divide_sigma_TCC2: OBLIGATION
    FORALL (FP: finite_partition[T], n: int):
      (FORALL (A: (FP)): card(A) /= 0 AND divides(n, card(A))) AND
       nonempty?(FP)
       IMPLIES
       rational_pred(sigma_set[finite_set[T]].sigma
                         (restrict[setof[T], finite_set[T], boolean](FP),
                          card[T]))
        AND
        integer_pred(sigma_set[finite_set[T]].sigma
                         (restrict[setof[T], finite_set[T], boolean](FP),
                          card[T]));


body:
  %%-------------------** Lagrange Theorem  **----------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%----------------------------------------------------------


  lagrange_index[T:Type+,*:[T,T->T],one:T]: THEORY


  BEGIN

     ASSUMING IMPORTING algebra@group_def[T,*,one]

         fullset_is_group: ASSUMPTION group?(fullset[T])

     ENDASSUMING

     IMPORTING algebra@lagrange,
               right_left_cosets[T,*,one],
               algebra@normal_subgroups[T,*,one]

     G,H,N: VAR finite_group


    Lagrange_index: THEOREM subgroup?(H,G) IMPLIES order(G) = index(G, H) * order(H)

    index_divides: COROLLARY subgroup?(H,G) IMPLIES divides(index(G, H), order(G))

    order_factor: LEMMA normal_subgroup?(N, G) IMPLIES card[set[T]](G/N) = order(G)/order(N)


  END lagrange_index

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

  % Assuming TCC generated (at line 24, column 13) for
      % right_left_cosets[T, *, one]
      % generated from assumption right_left_cosets.fullset_is_group
  IMP_right_left_cosets_TCC1: OBLIGATION group?[T, *, one](fullset[T]);

  % Subtype TCC generated (at line 34, column 66) for
      % extend[set[T], left_cosets[T, *, one](G, N), bool, FALSE](G / N)
      % expected type  S: finite_set[set[T]]
  order_factor_TCC1: OBLIGATION
    FORALL (G, N: finite_group[T, *, one]):
      normal_subgroup?(N, G) IMPLIES
       is_finite[set[T]]
           (extend[set[T], left_cosets[T, *, one](G, N), bool, FALSE]
                (/[T, *, one](G, N)));


body:
  %%-------------------** Group Action and Class Equation **-------------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%---------------------------------------------------------------------------


  group_action[T: TYPE, *: [T,T -> T], one: T, T1: TYPE]: THEORY

  BEGIN
    
       ASSUMING IMPORTING algebra@group_def[T,*,one]

         fullset_is_group: ASSUMPTION group?(fullset[T])

     ENDASSUMING


     IMPORTING algebra@group[T,*,one],
               algebra@factor_groups[T,*,one],
               lagrange_index[T,*,one],
               class_equation_scaf[set[T1],T1],
               groups_scaf


      G, H, K: VAR group[T,*,one]
         X, Y: VAR set[T1]
            p: VAR posnat
            n: VAR nat
       F(G,X): TYPE = [(G), (X) -> (X)]


  %%%%% Definitions %%%%

     group_action?(G, X)(f:F(G,X)): bool = FORALL (g1, g2:(G), x: (X)):   
                               f(one, x) = x AND f(g1 * g2, x) = f(g1, f(g2, x))

     stabilizer(G,X)(f: F(G,X), x: (X)): {S: set[T] | subset?(S,G)} = {g:(G) | f(g,x) = x}


     orbit(G,X)(f: F(G,X), x: (X)): {Y: set[T1] | subset?(Y,X)} = {y:(X) | EXISTS (g:(G)): y = f(g, x)}


     orbits(G,X)(f: F(G,X)): setofsets[T1] = {Y: set[T1] | EXISTS (x:(X)): Y = orbit(G,X)(f,x)}

     
     Fix(G,X)(f: F(G,X)): {Y: set[T1] | subset?(Y,X)} = {x:(X) | FORALL (g:(G)): f(g, x) = x}


     orbits_nFix(G,X)(f: F(G,X)): setofsets[T1] = {Y: (orbits(G,X)(f)) | 
                                       EXISTS (x: {x:(X) | NOT member(x, Fix(G,X)(f))}): Y = orbit(G,X)(f,x)}

  %%%%% Properties and results %%%%

     stabilizer_is_subgroup: LEMMA FORALL (x:(X), f:F(G,X)): 
                                group_action?(G, X)(f) IMPLIES subgroup?(stabilizer(G,X)(f, x), G)


     singleton_iff_Fix: LEMMA FORALL (x:(X), f:F(G,X)): 
                           group_action?(G, X)(f)
                              IMPLIES
                                (orbit(G,X)(f,x) = singleton(x) IFF member(x, Fix(G,X)(f)))

     empty_iff_eq_Fix: LEMMA FORALL (f:F(G,X)): 
                                group_action?(G, X)(f)
                                   IMPLIES
                                      (empty?(orbits_nFix(G,X)(f)) IFF X = Fix(G,X)(f))

     orbits_nFix_disj_Fix: LEMMA FORALL (f:F(G,X)): 
                              group_action?(G, X)(f) 
                                 IMPLIES disjoint?(Fix(G,X)(f),Union(orbits_nFix(G,X)(f)))


     orbits_is_union: LEMMA FORALL (f:F(G,X)): 
                         group_action?(G, X)(f) 
                            IMPLIES Union(orbits(G,X)(f)) = union(Fix(G,X)(f), Union(orbits_nFix(G,X)(f)))

     orbit_nonempty: LEMMA FORALL (x:(X), f:F(G,X)): 
                        group_action?(G, X)(f) IMPLIES nonempty?(orbit(G,X)(f,x))

     orbits_nonempty: LEMMA FORALL (f:F(G,X)): nonempty?(X) AND group_action?(G, X)(f) 
                               IMPLIES nonempty?(orbits(G,X)(f))

     set_orbits_is: LEMMA FORALL (f:F(G,X)): group_action?(G, X)(f) 
                            IMPLIES Union(orbits(G,X)(f)) = X

     orbit_is_finite: LEMMA FORALL (x:(X), f:F(G,X)):
                              is_finite(X) AND group_action?(G, X)(f)
                                 IMPLIES
                                    is_finite(orbit(G,X)(f,x))

     orbits_disjoint: LEMMA FORALL (f:F(G,X), A,B: (orbits(G,X)(f))):
                               group_action?(G, X)(f)
                                  IMPLIES 
                                     A = B OR disjoint?(A,B)

     orbits_partition: LEMMA  FORALL (f:F(G,X)): 
                                is_finite(X) AND group_action?(G, X)(f) 
                                  IMPLIES
                                     finite_partition?(orbits(G,X)(f))

     orbits_nFix_partition: LEMMA FORALL (f:F(G,X)): 
                                     is_finite(X) AND group_action?(G, X)(f) 
                                        IMPLIES
                                           finite_partition?(orbits_nFix(G,X)(f))

     orbits_eq_index_aux: LEMMA 
        FORALL (x:(X), f:F(G,X)): group_action?(G, X)(f) 
          IMPLIES
            EXISTS (f:[(left_cosets(G,stabilizer(G,X)(f, x))) -> (orbit(G,X)(f,x))]): bijective?(f)

     orbits_eq_index: LEMMA FORALL (G:finite_group, x:(X), f:F(G,X)):
                           is_finite(X) AND group_action?(G, X)(f)
                              IMPLIES
                                index(G, stabilizer(G,X)(f, x)) = card(orbit(G,X)(f,x))


  %%%%% Class Equation %%%%%%%%%%%%%%%%%%%%%%%%

  %                 ----
  %  sigma(X, f) =  \     f(x)
  %                 /
  %                 ----
  %              member(x,X)


     counting_formula: LEMMA FORALL (f:F(G,X)):
                               finite_group?(G) AND is_finite(X) AND 
                               nonempty?(X)     AND group_action?(G, X)(f)
                                  IMPLIES
                                    card(X) = sigma_set.sigma(orbits(G,X)(f), card)

     class_equation: LEMMA FORALL (f:F(G,X)):
                              finite_group?(G) AND is_finite(X) AND 
                              nonempty?(X)     AND group_action?(G, X)(f)
                                 IMPLIES 
                                    card(X) = card(Fix(G,X)(f)) + sigma_set.sigma(orbits_nFix(G,X)(f), card)

     Fix_congruence: LEMMA FORALL (f:F(G,X)):
                              finite_group?(G) AND order(G) = p^n AND 
                              is_finite(X)     AND nonempty?(X)   AND 
                              prime?(p)        AND group_action?(G, X)(f)
                                IMPLIES 
                                   divides(p, card(X) - card(Fix(G,X)(f)))


   
  END group_action

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

  % Assuming TCC generated (at line 23, column 13) for
      % algebra@group[T, *, one]
      % generated from assumption group.fullset_is_group
  IMP_group_TCC1: OBLIGATION group?[T, *, one](fullset[T]);

  % Subtype TCC generated (at line 40, column 31) for  one
      % expected type  (G)
  group_action?_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], X: set[T1], f: F(G, X), g1, g2: (G),
            x: (X)):
      G(one);

  % Subtype TCC generated (at line 40, column 49) for  g1 * g2
      % expected type  (G)
  group_action?_TCC2: OBLIGATION
    FORALL (G: group[T, *, one], X: set[T1], f: F(G, X), g1, g2: (G),
            x: (X)):
      f(one, x) = x IMPLIES G(g1 * g2);

  % Subtype TCC generated (at line 42, column 68) for
      % extend[T, (G), bool, FALSE]({g: (G) | f(g, x) = x})
      % expected type  {S: set[T] | subset?(S, G)}
  stabilizer_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], X: set[T1], f: F(G, X), x: (X)):
      subset?[T](extend[T, (G), bool, FALSE]({g: (G) | f(g, x) = x}), G);

  % Subtype TCC generated (at line 45, column 64) for
      % extend[T1, (X), bool, FALSE]({y: (X) | EXISTS (g: (G)): y = f(g, x)})
      % expected type  {Y: set[T1] | subset?(Y, X)}
  orbit_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], X: set[T1], f: F(G, X), x: (X)):
      subset?[T1]
          (extend[T1, (X), bool, FALSE]
               ({y: (X) | EXISTS (g: (G)): y = f(g, x)}),
           X);

  % Subtype TCC generated (at line 51, column 54) for
      % extend[T1, (X), bool, FALSE]({x: (X) | FORALL (g: (G)): f(g, x) = x})
      % expected type  {Y: set[T1] | subset?(Y, X)}
  Fix_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], X: set[T1], f: F(G, X)):
      subset?[T1]
          (extend[T1, (X), bool, FALSE]
               ({x: (X) | FORALL (g: (G)): f(g, x) = x}),
           X);

  % Subtype TCC generated (at line 114, column 36) for  stabilizer(G, X)(f, x)
      % expected type  subgroup[T, *, one](G)
  orbits_eq_index_aux_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], X: set[T1], x: (X), f: F(G, X)):
      group_action?(G, X)(f) IMPLIES
       (FORALL (f1:
                  [(left_cosets[T, *, one](G, stabilizer(G, X)(f, x))) ->
                     (orbit(G, X)(f, x))]):
          group?[T, *, one](stabilizer(G, X)(f, x)) AND
           subgroup?[T, *, one](stabilizer(G, X)(f, x), G));

  % Subtype TCC generated (at line 119, column 39) for  stabilizer(G, X)(f, x)
      % expected type  subgroup[T, *, one](G)
  orbits_eq_index_TCC1: OBLIGATION
    FORALL (X: set[T1], G: finite_group[T, *, one], x: (X), f: F(G, X)):
      is_finite(X) AND group_action?(G, X)(f) IMPLIES
       group?[T, *, one](stabilizer(G, X)(f, x)) AND
        subgroup?[T, *, one](stabilizer(G, X)(f, x), G);

  % Subtype TCC generated (at line 119, column 69) for  orbit(G, X)(f, x)
      % expected type  S: finite_set[T1]
  orbits_eq_index_TCC2: OBLIGATION
    FORALL (X: set[T1], G: finite_group[T, *, one], x: (X), f: F(G, X)):
      is_finite(X) AND group_action?(G, X)(f) IMPLIES
       is_finite[T1](orbit(G, X)(f, x));

  % Subtype TCC generated (at line 135, column 76) for  card
      % expected type  (convergent?(restrict
                     %                  [setof[T1], finite_set[T1], boolean]
                     %                  (orbits(G, X)(f))))
  counting_formula_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], X: set[T1], f: F(G, X)):
      finite_group?(G) AND
       is_finite(X) AND nonempty?(X) AND group_action?(G, X)(f)
       IMPLIES
       convergent?[finite_set[T1]]
           (restrict[setof[T1], finite_set[T1], boolean](orbits(G, X)(f)))
           (card[T1]);

  % Subtype TCC generated (at line 141, column 49) for  Fix(G, X)(f)
      % expected type  S: finite_set[T1]
  class_equation_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], X: set[T1], f: F(G, X)):
      finite_group?(G) AND
       is_finite(X) AND nonempty?(X) AND group_action?(G, X)(f)
       IMPLIES is_finite[T1](Fix(G, X)(f));

  % Subtype TCC generated (at line 141, column 101) for  card
      % expected type  (convergent?(restrict
                     %                  [setof[T1], finite_set[T1], boolean]
                     %                  (orbits_nFix(G, X)(f))))
  class_equation_TCC2: OBLIGATION
    FORALL (G: group[T, *, one], X: set[T1], f: F(G, X)):
      finite_group?(G) AND
       is_finite(X) AND nonempty?(X) AND group_action?(G, X)(f)
       IMPLIES
       convergent?[finite_set[T1]]
           (restrict[setof[T1], finite_set[T1], boolean]
                (orbits_nFix(G, X)(f)))
           (card[T1]);

  % Subtype TCC generated (at line 144, column 55) for  G
      % expected type  finite_monad[T, *, one]
  Fix_congruence_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], X: set[T1], f: F(G, X)):
      finite_group?(G) IMPLIES finite_monad?[T, *, one](G);

  % Subtype TCC generated (at line 144, column 62) for  n
      % expected type  {i: int | p /= 0 OR i >= 0}
  Fix_congruence_TCC2: OBLIGATION
    FORALL (G: group[T, *, one], X: set[T1], n: nat, p: posnat, f: F(G, X)):
      finite_group?(G) IMPLIES p /= 0 OR n >= 0;


body:
  %%-------------------** Cauchy Theorem **-------------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%----------------------------------------------------------


  cauchy[T: TYPE, *: [T,T -> T], one: T]: THEORY

  BEGIN

     ASSUMING IMPORTING algebra@group_def[T,*,one]
                        
         fullset_is_group: ASSUMPTION group?(fullset[T])

     ENDASSUMING

     IMPORTING  ints@primes,
                algebra@finite_groups,
                algebra@finite_cyclic_groups[T,*,one],
                group_action,
                zp_group,
                cauchy_scaf[T]



                G: VAR finite_group
                p: VAR posnat
     fs, fs1, fs2: VAR finseq
                n: VAR nat
                a: VAR T

     fseq_product(fs): RECURSIVE T =  IF length(fs) = 0 THEN one
                                      ELSE fs`seq(0)*fseq_product(rest(fs))
                                      ENDIF
                                      MEASURE length(fs)

     S(G)(n): set[finseq] = {fs: finseq | length(fs) = n AND 
                                          (FORALL (i: below[n]): member(fs`seq(i), G)) AND 
                                          fseq_product(fs) = one}

     same_element(a, fs):bool = FORALL (i: below[length(fs)]): fs`seq(i) = a


     SE(G)(n): set[finseq] = {fs: (S(G)(n)) | EXISTS (a: (G)): same_element(a, fs)}
     


   %%%%% Properties %%%


     fseq_product_in: LEMMA (FORALL (i: below[length(fs)]): member(fs`seq(i), G))
                                IMPLIES member(fseq_product(fs), G)

     fseq_product_o: LEMMA (FORALL (i: below[length(fs1)]): member(fs1`seq(i), G)) AND
                                (FORALL (j: below[length(fs2)]): member(fs2`seq(j), G))
                                       IMPLIES
                                          fseq_product(fs1 o fs2) = fseq_product(fs1) * fseq_product(fs2)


     fseq_product_one: LEMMA (FORALL (i: below[length(fs)]): member(fs`seq(i), G))
                                    IMPLIES  inv(fseq_product(fs)) * fseq_product(fs) = one

     fseq_product_power: LEMMA FORALL (g: (G)): same_element(g, fs) IMPLIES fseq_product(fs) = g^length(fs)

     one_in_SE: LEMMA length(fs) = n AND same_element(one, fs) IMPLIES member(fs, SE(G)(n))

     order_SE: LEMMA FORALL (g: (G)): prime?(p) AND g /= one AND 
                                           same_element(g, fs) AND member(fs, SE(G)(p))
                                              IMPLIES period(G,g) = p

     S_bij_set_seq: LEMMA LET A = set_seq(G)(p - 1),
                                  B = S(G)(p)         IN
                              EXISTS (g:[(A)->(B)]): bijective?(g)

     S_is_finite:LEMMA is_finite(S(G)(n))

     S_card: LEMMA card(S(G)(p)) = card(G)^(p - 1)



  %%%%% Group action %%%


     F(p, G)(k: (Zn[p]), fs: (S(G)(p))): finseq = (# length := p,
                                                        seq := (LAMBDA (i: below[p]):fs`seq(rem(p)(i + k))) #)


     F_1(fs)(k: below[length(fs)]): finseq = (# length := length(fs) - k,
                                                   seq := (LAMBDA (i: below[length(fs) - k]): 
                                                              fs`seq(rem(length(fs))(i + k))) #)

     F_2(fs)(k: below[length(fs)]): finseq = (# length := k,
                                                  seq := (LAMBDA (i: below[k]): fs`seq(i)) #)



     F_o_F12: LEMMA FORALL (k: (Zn[p]), fs: (S(G)(p))): F(p,G)(k, fs) = F_1(fs)(k) o F_2(fs)(k)

     
     fs_o_F21: LEMMA FORALL (k: (Zn[p]), fs: (S(G)(p))): fs = F_2(fs)(k) o F_1(fs)(k)


     F_in_S: LEMMA FORALL (k: (Zn[p]), fs: (S(G)(p))): member(F(p,G)(k, fs), S(G)(p))


     F_is_action: LEMMA group_action?[below(p),++,0,finseq](Zn[p],S(G)(p))(F(p,G))




  %%%%% Fixed point subset %%%

     Fixed_subset: LEMMA  LET H = Zn[p],
                              X = S(G)(p),
                              f = F(p, G) IN
                          Fix[below(p),++,0,finseq](H,X)(f) = SE(G)(p)


  %%%%% Cauchy Theorem %%%

     cauchy: THEOREM prime?(p) AND divides(p, order(G)) IMPLIES EXISTS (x: (G)):  period(G,x) = p

     cauchy_cor: COROLLARY prime?(p) AND divides(p, order(G)) IMPLIES EXISTS (H: subgroup(G)): order(H) = p


  END cauchy

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

  % Assuming TCC generated (at line 24, column 14) for
      % algebra@finite_cyclic_groups[T, *, one]
      % generated from assumption finite_cyclic_groups.fullset_is_group
  IMP_finite_cyclic_groups_TCC1: OBLIGATION group?[T, *, one](fullset[T]);

  % Subtype TCC generated (at line 38, column 48) for  0
      % expected type  below[fs`length]
  fseq_product_TCC1: OBLIGATION
    FORALL (fs: finseq[T]): NOT length(fs) = 0 IMPLIES 0 < fs`length;

  % Termination TCC generated (at line 38, column 51) for
      % fseq_product(rest(fs))
  fseq_product_TCC2: OBLIGATION
    FORALL (fs: finseq[T]):
      NOT length(fs) = 0 IMPLIES length(rest[T](fs)) < length(fs);

  % Subtype TCC generated (at line 43, column 77) for  i
      % expected type  below[fs`length]
  S_TCC1: OBLIGATION
    FORALL (n: nat, fs: finseq[T]):
      length(fs) = n IMPLIES (FORALL (i: below[n]): i < fs`length);

  % Subtype TCC generated (at line 76, column 43) for  p - 1
      % expected type  nat
  S_bij_set_seq_TCC1: OBLIGATION FORALL (p: posnat): p - 1 >= 0;

  % Subtype TCC generated (at line 76, column 40) for  G
      % expected type  finite_set[T]
  S_bij_set_seq_TCC2: OBLIGATION
    FORALL (G: finite_group[T, *, one]): is_finite[T](G);

  % Subtype TCC generated (at line 82, column 22) for  S(G)(p)
      % expected type  S: finite_set[finseq[T]]
  S_card_TCC1: OBLIGATION
    FORALL (G: finite_group[T, *, one], p: posnat):
      is_finite[finseq[T]](S(G)(p));

  % Subtype TCC generated (at line 90, column 90) for  rem(p)(i + k)
      % expected type  below[fs`length]
  F_TCC1: OBLIGATION
    FORALL (p: posnat, G: finite_group[T, *, one], k: (Zn[p]), fs: (S(G)(p)),
            i: below[p]):
      rem(p)(i + k) < fs`length;

  % Subtype TCC generated (at line 93, column 56) for  length(fs) - k
      % expected type  nat
  F_1_TCC1: OBLIGATION
    FORALL (fs: finseq[T], k: below[length(fs)]): length(fs) - k >= 0;

  % Subtype TCC generated (at line 95, column 71) for  length(fs)
      % expected type  b: posnat
  F_1_TCC2: OBLIGATION
    FORALL (fs: finseq[T], k: below[length(fs)], i: below[length(fs) - k]):
      length(fs) > 0;

  % Subtype TCC generated (at line 98, column 85) for  i
      % expected type  below[fs`length]
  F_2_TCC1: OBLIGATION
    FORALL (fs: finseq[T], k: below[length(fs)], i: below[k]): i < fs`length;

  % Subtype TCC generated (at line 102, column 78) for  k
      % expected type  below[length(fs)]
  F_o_F12_TCC1: OBLIGATION
    FORALL (G: finite_group[T, *, one], p: posnat, k: (Zn[p]),
            fs: (S(G)(p))):
      k < length(fs);

  % Subtype TCC generated (at line 111, column 73) for  F(p, G)
      % expected type  F[below(p), ++, 0, finseq](Zn[p], S(G)(p))
  F_is_action_TCC1: OBLIGATION
    FORALL (G: finite_group[T, *, one], p: posnat, x1: [(Zn[p]), (S(G)(p))]):
      S(G)(p)(F(p, G)(x1));

  % Subtype TCC generated (at line 111, column 58) for  Zn[p]
      % expected type  group[below(p), ++, 0]
  F_is_action_TCC2: OBLIGATION
    FORALL (p: posnat): group?[below(p), ++[p], 0](Zn[p]);

  % Subtype TCC generated (at line 111, column 48) for  0
      % expected type  below(p)
  F_is_action_TCC3: OBLIGATION FORALL (p: posnat): 0 < p;

  % Assuming TCC generated (at line 18, column 7) for
      % group_action[below(p), ++, 0, finseq]
      % generated from assumption group_action.fullset_is_group
  F_is_action_TCC4: OBLIGATION
    FORALL (p: posnat): group?[below(p), ++, 0](fullset[below(p)]);

  % Subtype TCC generated (at line 121, column 55) for  f
      % expected type  F[below(p), ++, 0, finseq](H, X)
  Fixed_subset_TCC1: OBLIGATION
    FORALL (G: finite_group[T, *, one], p: posnat, H: set[below(p)]):
      H = Zn[p] IMPLIES
       (FORALL (X: set[finseq[T]]):
          X = S(G)(p) IMPLIES
           (FORALL (f: [[(Zn[p]), (S(G)(p))] -> finseq[T]]):
              f = F(p, G) IMPLIES
               ((FORALL (x: below(p)): Zn[p](x) IFF H(x)) AND
                 (FORALL (x: finseq[T]): S(G)(p)(x) IFF X(x)))
                AND (FORALL (x1: [(Zn[p]), (S(G)(p))]): X(f(x1)))));

  % Subtype TCC generated (at line 121, column 50) for  H
      % expected type  group[below(p), ++, 0]
  Fixed_subset_TCC2: OBLIGATION
    FORALL (G: finite_group[T, *, one], p: posnat, H: set[below(p)]):
      H = Zn[p] IMPLIES
       (FORALL (X: set[finseq[T]]):
          X = S(G)(p) IMPLIES
           (FORALL (f: [[(Zn[p]), (S(G)(p))] -> finseq[T]]):
              f = F(p, G) IMPLIES group?[below(p), ++[p], 0](H)));

  % Subtype TCC generated (at line 128, column 99) for  H
      % expected type  finite_monad[T, *, one]
  cauchy_cor_TCC1: OBLIGATION
    FORALL (G: finite_group[T, *, one], p: posnat):
      divides(p, order(G)) AND prime?(p) IMPLIES
       (FORALL (H: subgroup[T, *, one](G)): finite_monad?[T, *, one](H));


body:
  %%-------------------** Normalizer, Centralizer and Class Equation **-------------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%--------------------------------------------------------------------------------------


  normalizer_centralizer[T: TYPE, *: [T,T -> T], one: T]: THEORY

  BEGIN

     ASSUMING IMPORTING algebra@group_def[T,*,one]

         fullset_is_group: ASSUMPTION group?(fullset[T])

     ENDASSUMING

    IMPORTING algebra@normal_subgroups[T,*,one],
              group_action[T,*,one,T]


        G, H: VAR group
        a, x: VAR T


  %%%%% Definitions %%%%%

     normalizer(G:group, H:subgroup(G)): {S: set[T] | subset?(S,G)} = { x: (G) | inv(x) * H * x = H}

     centralizer(G)(a): {S: set[T] | subset?(S,G)} = { x: (G) | x * a = a * x}

     a_by_c(G:group, H:subgroup(G))(h:(H), x:(G)): (G) = h * x * inv(h)


     CL(G)(x): {X: set[T] | subset?(X,G)} = { y: (G) | EXISTS (g: (G)): y = g * x * inv(g)}

     
     CLs(G): setofsets[T] = {X: set[T] | EXISTS (x: (G)): X = CL(G)(x)}


     CLs_nc(G): setofsets[T] = {X: (CLs(G)) | EXISTS (x: {x:(G) | 
                                                    NOT member(x, center(G))}): X = CL(G)(x)}


  %%%%% Properties and results %%%%%

     normalizer_is_subgroup: LEMMA subgroup?(H,G) IMPLIES subgroup?(normalizer(G,H), G)

     subset_of_normalizer: LEMMA subgroup?(H,G) IMPLIES subset?(H, normalizer(G,H))

     normal_in_normalizer: LEMMA subgroup?(H,G) IMPLIES 
                                        normal_subgroup?(H, normalizer(G,H)) 

     centralizer_is_subgroup: LEMMA subgroup?(centralizer(G)(a), G)

     singleton_iff_center: LEMMA FORALL (x:(G)): CL(G)(x) = singleton(x) IFF member(x, center(G))

     a_by_c_is_action: LEMMA subgroup?(H,G) IMPLIES group_action?(H,G)(a_by_c(G,H))

     Fix_is_center: LEMMA Fix(G,G)(a_by_c(G,G)) = center(G)

     stabilizer_is_centralizer: LEMMA FORALL (x:(G)): stabilizer(G,G)(a_by_c(G,G), x) = centralizer(G)(x)

     orbit_is_CL: LEMMA FORALL (x:(G)): orbit(G,G)(a_by_c(G,G), x) = CL(G)(x)

     orbits_is_CLs: LEMMA orbits(G,G)(a_by_c(G,G)) = CLs(G)

     orbits_nFix_is_CLs_nc: LEMMA orbits_nFix(G,G)(a_by_c(G,G)) = CLs_nc(G)

     CLs_eq_index: LEMMA FORALL (G:finite_group, x:(G)): index(G, centralizer(G)(x)) = card(CL(G)(x))


  %%%%% Class Equation %%%%%%%%%%%%%%%%%%%%%%%%

  %                 ----
  %  sigma(X, f) =  \     f(x)
  %                 /
  %                 ----
  %              member(x,X)

    

    class_equation_2: LEMMA  FORALL (G:finite_group): 
                                order(G) = card(center(G)) + sigma_set.sigma(CLs_nc(G), card)

  END  normalizer_centralizer

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

  % Assuming TCC generated (at line 22, column 12) for
      % algebra@normal_subgroups[T, *, one]
      % generated from assumption normal_subgroups.fullset_is_group
  IMP_normal_subgroups_TCC1: OBLIGATION group?[T, *, one](fullset[T]);

  % Subtype TCC generated (at line 32, column 68) for
      % extend[T, (G), bool, FALSE]({x: (G) | inv(x) * H * x = H})
      % expected type  {S: set[T] | subset?(S, G)}
  normalizer_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], H: subgroup[T, *, one](G)):
      subset?[T]
          (extend[T, (G), bool, FALSE]
               ({x: (G) |
                   *[T, *, one](*[T, *, one](inv[T, *, one](x), H), x) = H}),
           G);

  % Subtype TCC generated (at line 34, column 51) for
      % extend[T, (G), bool, FALSE]({x: (G) | x * a = a * x})
      % expected type  {S: set[T] | subset?(S, G)}
  centralizer_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], a: T):
      subset?[T](extend[T, (G), bool, FALSE]({x: (G) | x * a = a * x}), G);

  % Subtype TCC generated (at line 36, column 55) for  h * x * inv(h)
      % expected type  (G)
  a_by_c_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], H: subgroup[T, *, one](G), h: (H), x: (G)):
      G(h * x * inv[T, *, one](h));

  % Subtype TCC generated (at line 39, column 42) for
      % extend[T, (G), bool, FALSE]
      %     ({y: (G) | EXISTS (g: (G)): y = g * x * inv(g)})
      % expected type  {X: set[T] | subset?(X, G)}
  CL_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], x: T):
      subset?[T]
          (extend[T, (G), bool, FALSE]
               ({y: (G) | EXISTS (g: (G)): y = g * x * inv[T, *, one](g)}),
           G);

  % Subtype TCC generated (at line 56, column 58) for  normalizer(G, H)
      % expected type  group[T, *, one]
  normal_in_normalizer_TCC1: OBLIGATION
    FORALL (G, H: group[T, *, one]):
      subgroup?(H, G) IMPLIES group?[T, *, one](normalizer(G, H));

  % Subtype TCC generated (at line 64, column 42) for  G
      % expected type  subgroup[T, *, one](G)
  Fix_is_center_TCC1: OBLIGATION
    FORALL (G: group[T, *, one]): subgroup?[T, *, one](G, G);

  % Subtype TCC generated (at line 74, column 64) for  centralizer(G)(x)
      % expected type  subgroup[T, *, one](G)
  CLs_eq_index_TCC1: OBLIGATION
    FORALL (G: finite_group[T, *, one], x: (G)):
      group?[T, *, one](centralizer(G)(x)) AND
       subgroup?[T, *, one](centralizer(G)(x), G);

  % Subtype TCC generated (at line 74, column 90) for  CL(G)(x)
      % expected type  S: finite_set[T]
  CLs_eq_index_TCC2: OBLIGATION
    FORALL (G: finite_group[T, *, one], x: (G)): is_finite[T](CL(G)(x));

  % Subtype TCC generated (at line 88, column 46) for  center(G)
      % expected type  S: finite_set[T]
  class_equation_2_TCC1: OBLIGATION
    FORALL (G: finite_group[T, *, one]): is_finite[T](center[T, *, one](G));

  % Subtype TCC generated (at line 88, column 86) for  card
      % expected type  (convergent?(restrict[setof[T], finite_set[T], boolean]
                     %                  (CLs_nc(G))))
  class_equation_2_TCC2: OBLIGATION
    FORALL (G: finite_group[T, *, one]):
      convergent?[finite_set[T]]
          (restrict[setof[T], finite_set[T], boolean](CLs_nc(G)))(card[T]);


body:
  %%-------------------** p-Groups and Burside Theorem **-------------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%------------------------------------------------------------------------


  p_groups[T:Type, *:[T,T->T], one:T]: THEORY

  BEGIN
    
       ASSUMING IMPORTING algebra@group_def[T,*,one]

         fullset_is_group: ASSUMPTION group?(fullset[T])

     ENDASSUMING


     IMPORTING algebra@finite_cyclic_groups,
               algebra@finite_groups[T,*,one],
               normalizer_centralizer[T,*,one],
               cauchy[T, *, one]

      G, H, K: VAR group[T,*,one]
            p: VAR posnat
            n: VAR nat


  %%%%% Definitions %%%%%

     p_group?(G:finite_group, p: {p:posnat | prime?(p)} ): bool = FORALL (a:(G)): 
                                                                (EXISTS (n: nat): period(G,a) = p^n)


     alt(G:group,H: subgroup(G),K: subgroup(G))(h:(H), A: (left_cosets(G,K))): set[T] = h*A


  ; %%%%% Properties and results %%%%%


     alt_is_action: LEMMA FORALL (H, K: subgroup(G)):
                             group_action?(H, left_cosets(G,K))(alt(G,H,K))


     Fix_iff_subset: LEMMA FORALL (H, K: subgroup(G), g: (G)): 
                              member(g*K,  Fix(H,left_cosets(G,K))(alt(G,H,K))) IFF subset?(H, g*K*inv(g))

   
     Fix_iff_subset_cor: LEMMA FORALL (G:finite_group, H, K: subgroup(G), g: (G)): 
                                  member(g*H,  Fix(H,left_cosets(G,H))(alt(G,H,H))) IFF H = g*H*inv(g)

     subgroup_is_p_group: LEMMA FORALL (G:finite_group,H: subgroup(G)): 
                                   prime?(p) AND p_group?(G,p) IMPLIES p_group?(H,p)

     p_group_iff_power: LEMMA FORALL (G:finite_group): 
                                    prime?(p) IMPLIES (p_group?(G,p) IFF (EXISTS (m:nat): order(G) = p^m))

     p_divides_index: LEMMA FORALL (G:finite_group, H:subgroup(G)): 
                              prime?(p) AND p_group?(G,p) AND H /= G IMPLIES divides(p, index(G,H))

     factor_cyclic: LEMMA cyclic?(G/center(G)) IMPLIES abelian_group?(G)

     normalizer_index: LEMMA FORALL (G:finite_group, H:subgroup(G)): 
                                   prime?(p) AND p_group?(H,p) AND divides(p, index(G,H))
                                     IMPLIES divides(p, index(normalizer(G,H), H))
   
     subgroup_proper: LEMMA  FORALL (G:finite_group, H:subgroup(G)): 
                                   prime?(p) AND p_group?(G,p) AND H /= G
                                     IMPLIES H /= normalizer(G,H)

  %%%%% Burside Theorem %%%%%

    burside_theorem: THEOREM FORALL (G:finite_group): 
                                    order(G) > 1 AND prime?(p) AND p_group?(G,p)
                                       IMPLIES order(center(G)) >= p
     
    p_square_is_abelian: LEMMA FORALL (G:finite_group): prime?(p) AND order(G) = p^2 
                                 IMPLIES abelian_group?(G)

   

  END p_groups

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

  % Assuming TCC generated (at line 24, column 13) for
      % algebra@finite_groups[T, *, one]
      % generated from assumption finite_groups.fullset_is_group
  IMP_finite_groups_TCC1: OBLIGATION group?[T, *, one](fullset[T]);

  % Subtype TCC generated (at line 36, column 96) for  n
      % expected type  {i: int | p /= 0 OR i >= 0}
  p_group?_TCC1: OBLIGATION
    FORALL (G: finite_group[T, *, one], p: {p: posnat | prime?(p)}, a: (G),
            n: nat):
      p /= 0 OR n >= 0;

  % Subtype TCC generated (at line 46, column 62) for  alt(G, H, K)
      % expected type  F[T, *, one, setof[T]](H, left_cosets(G, K))
  alt_is_action_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], H, K: subgroup[T, *, one](G)):
      FORALL (x1: [(H), (left_cosets[T, *, one](G, K))]):
        left_cosets[T, *, one](G, K)(alt(G, H, K)(x1));

  % Subtype TCC generated (at line 54, column 69) for  alt(G, H, H)
      % expected type  F[T, *, one, setof[T]](H, left_cosets(G, H))
  Fix_iff_subset_cor_TCC1: OBLIGATION
    FORALL (G: finite_group[T, *, one], H, K: subgroup[T, *, one](G),
            g: (G)):
      FORALL (x1: [(H), (left_cosets[T, *, one](G, H))]):
        left_cosets[T, *, one](G, H)(alt(G, H, H)(x1));

  % Subtype TCC generated (at line 57, column 78) for  H
      % expected type  finite_group[T, *, one]
  subgroup_is_p_group_TCC1: OBLIGATION
    FORALL (p: posnat, G: finite_group[T, *, one],
            H: subgroup[T, *, one](G)):
      prime?(p) AND p_group?(G, p) IMPLIES finite_group?[T, *, one](H);

  % Subtype TCC generated (at line 60, column 101) for  m
      % expected type  {i: int | p /= 0 OR i >= 0}
  p_group_iff_power_TCC1: OBLIGATION
    FORALL (p: posnat): prime?(p) IMPLIES (FORALL (m: nat): p /= 0 OR m >= 0);

  % Subtype TCC generated (at line 65, column 34) for  center(G)
      % expected type  normal_subgroup[T, *, one](G)
  factor_cyclic_TCC1: OBLIGATION
    FORALL (G: group[T, *, one]):
      group?[T, *, one](center[T, *, one](G)) AND
       normal_subgroup?[T, *, one](center[T, *, one](G), G);

  % Subtype TCC generated (at line 65, column 34) for  center(G)
      % expected type  left_cosets[T, *, one](G, center(G))
  factor_cyclic_TCC2: OBLIGATION
    FORALL (G: group[T, *, one]):
      EXISTS (a: (G)):
        center[T, *, one](G) = *[T, *, one](a, center[T, *, one](G));

  % Assuming TCC generated (at line 24, column 13) for
      % algebra@group
      %     [left_cosets[T, *, one](G, center(G)), mult(G, center(G)),
      %      center(G)]
      % generated from assumption group.fullset_is_group
  factor_cyclic_TCC3: OBLIGATION
    FORALL (G: group[T, *, one]):
      group?
          [left_cosets[T, *, one](G, center(G)), mult(G, center(G)),
           center(G)]
          (fullset[left_cosets[T, *, one](G, center(G))]);

  % Subtype TCC generated (at line 68, column 56) for  H
      % expected type  finite_group[T, *, one]
  normalizer_index_TCC1: OBLIGATION
    FORALL (p: posnat, G: finite_group[T, *, one],
            H: subgroup[T, *, one](G)):
      prime?(p) IMPLIES finite_group?[T, *, one](H);

  % Subtype TCC generated (at line 69, column 60) for  normalizer(G, H)
      % expected type  finite_group[T, *, one]
  normalizer_index_TCC2: OBLIGATION
    FORALL (p: posnat, G: finite_group[T, *, one],
            H: subgroup[T, *, one](G)):
      prime?(p) AND p_group?(H, p) AND divides(p, index(G, H)) IMPLIES
       finite_group?[T, *, one](normalizer[T, *, one](G, H));

  % Subtype TCC generated (at line 69, column 77) for  H
      % expected type  subgroup[T, *, one](normalizer(G, H))
  normalizer_index_TCC3: OBLIGATION
    FORALL (p: posnat, G: finite_group[T, *, one],
            H: subgroup[T, *, one](G)):
      prime?(p) AND p_group?(H, p) AND divides(p, index(G, H)) IMPLIES
       subgroup?[T, *, one](H, normalizer[T, *, one](G, H));

  % Subtype TCC generated (at line 79, column 51) for  center(G)
      % expected type  finite_monad[T, *, one]
  burside_theorem_TCC1: OBLIGATION
    FORALL (p: posnat, G: finite_group[T, *, one]):
      order(G) > 1 AND prime?(p) AND p_group?(G, p) IMPLIES
       finite_monad?[T, *, one](center[T, *, one](G));

  % Subtype TCC generated (at line 81, column 81) for  2
      % expected type  {i: int | p /= 0 OR i >= 0}
  p_square_is_abelian_TCC1: OBLIGATION
    FORALL (p: posnat): prime?(p) IMPLIES p /= 0 OR 2 >= 0;


body:
  %%-------------------** Product of Subgroups **-------------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%----------------------------------------------------------------


  products_subgroups[T: TYPE, *: [T,T -> T], one: T]: THEORY

  BEGIN
    
       ASSUMING IMPORTING algebra@group_def[T,*,one]

         fullset_is_group: ASSUMPTION group?(fullset[T])

     ENDASSUMING


     IMPORTING  algebra@normal_subgroups[T,*,one], groups_scaf

         G: VAR group[T,*,one]
     H,K,N: VAR set[T]


  %%% Definitions %%%%%%

  prod(H,K): set[T] = {t:T | EXISTS (h:(H), k:(K)): t = h*k}


  HK_subgroup: LEMMA FORALL (H, N: subgroup(G)): normal_subgroup?(N,G) 
                        IMPLIES subgroup?(prod(H,N),G)


  HK_subgroup_permute: LEMMA FORALL (H, K: subgroup(G)): 
                                   subgroup?(prod(H,K),G) IFF prod(H,K) = prod(K,H) ;


  H_K_are_subgroups: LEMMA FORALL (H, K: subgroup(G)):
                     group?(prod(H,K)) IMPLIES 
                          subgroup?(H, prod(H,K)) AND 
                          subgroup?(K, prod(H,K))


  END products_subgroups

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

  % Assuming TCC generated (at line 23, column 14) for
      % algebra@normal_subgroups[T, *, one]
      % generated from assumption normal_subgroups.fullset_is_group
  IMP_normal_subgroups_TCC1: OBLIGATION group?[T, *, one](fullset[T]);


body:
  %%-------------------** First Isomorphism Theorem **-------------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%---------------------------------------------------------------------


  homomorphism_lemmas[T1: TYPE, *: [T1,T1 -> T1], one1: T1,
                      T2: TYPE, o: [T2,T2 -> T2], one2: T2]: THEORY

  BEGIN
    
     ASSUMING IMPORTING algebra@group_def

         T1_is_group: ASSUMPTION group?[T1,*,one1](fullset[T1])
         T2_is_group: ASSUMPTION group?[T2,o,one2](fullset[T2])

     ENDASSUMING


     IMPORTING  products_subgroups,
                algebra@homomorphisms, 
                algebra@factor_groups

       G:  VAR group[T1,*,one1]
      GP: VAR group[T2,o,one2]
   x,y,z: VAR T1


  natural_homo: LEMMA FORALL (K: normal_subgroup(G)):  
                EXISTS (pi: [(G) -> (G/K)]): 
                   pi = (LAMBDA (x:(G)): *[T1, *, one1](x, K)) AND
                   homomorphism?(G,G/K,pi)                     AND 
                   surjective?(pi)                             AND  
                   K = kernel(G,G/K)(pi) 


  homo_inv:  LEMMA FORALL (phi: homomorphism(G,GP), x: (G)): 
                                         phi(inv[T1, *, one1](x)) = inv[T2, o, one2](phi(x)) 


  kernel_normal: LEMMA FORALL (phi: homomorphism(G,GP)):
                                     LET K = kernel(G,GP)(phi) IN
                                         normal_subgroup?(K, G)


  homo_image: LEMMA FORALL (phi: homomorphism(G,GP),H: subgroup(G)): 
                          subgroup?[T2, o, one2](image(phi, H), GP)


  homo_image_normal: LEMMA FORALL (phi: homomorphism(G,GP),H: normal_subgroup(G)): 
                         surjective?(phi) IMPLIES  normal_subgroup?[T2, o, one2](image(phi, H), GP)


  homo_inv_image:  LEMMA FORALL (phi: homomorphism(G,GP),K: subgroup(GP)): 
                          subgroup?[T1, *, one1](inverse_image(phi, K), G)


  homo_inv_image_normal:  LEMMA FORALL (phi: homomorphism(G,GP),K: normal_subgroup(GP)): 
                          normal_subgroup?[T1, *, one1](inverse_image(phi, K), G)


  kernel_in_inv_image: LEMMA FORALL (phi: homomorphism(G,GP),S: subgroup(GP)): 
                                 LET K = kernel(G,GP)(phi) IN
                                 subset?(K, inverse_image(phi, S))


  homo_inv_image_image: LEMMA FORALL (phi: homomorphism(G,GP),H: subgroup(G)):
                                     LET K = kernel(G,GP)(phi) IN
                                     inverse_image(phi, image(phi, H)) = prod[T1,*,one1](H,K)


  homo_inv_image_image_cor: LEMMA FORALL (phi: homomorphism(G,GP),H: subgroup(G)):
                                     LET K = kernel(G,GP)(phi) IN
                                     inverse_image(phi, image(phi, H)) = H IFF subgroup?[T1, *, one1](K,H)



  first_isomorphism_th: LEMMA FORALL (phi: homomorphism(G,GP)): 
                           LET K = kernel(G,GP)(phi) IN
                           isomorphic?[left_cosets(G,K),mult(G,K),K, T2, o, one2](G/K, image(phi, G))

  END homomorphism_lemmas

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

  % Assuming TCC generated (at line 29, column 13) for  group[T1, *, one1]
      % generated from assumption group.fullset_is_group
  G_TCC1: OBLIGATION group?[T1, *, one1](fullset[T1]);

  % Assuming TCC generated (at line 30, column 12) for  group[T2, o, one2]
      % generated from assumption group.fullset_is_group
  GP_TCC1: OBLIGATION group?[T2, o, one2](fullset[T2]);

  % Subtype TCC generated (at line 37, column 35) for  K
      % expected type  left_cosets[T1, *, one1](G, K)
  natural_homo_TCC1: OBLIGATION
    FORALL (G: group[T1, *, one1], K: normal_subgroup[T1, *, one1](G),
            pi: [(G) -> (/[T1, *, one1](G, K))]):
      (pi = (LAMBDA (x: (G)): (*[T1, *, one1](x, K)))) IMPLIES
       (EXISTS (a: (G)): K = *[T1, *, one1](a, K));

  % Assuming TCC generated (at line 26, column 14) for
      % algebra@homomorphisms
      %     [T1, *, one1, left_cosets[T1, *, one1](G, K),
      %      mult[T1, *, one1](G, K), K]
      % generated from assumption homomorphisms.T2_is_group
  natural_homo_TCC2: OBLIGATION
    FORALL (G: group[T1, *, one1], K: normal_subgroup[T1, *, one1](G),
            pi: [(G) -> (/[T1, *, one1](G, K))]):
      (pi = (LAMBDA (x: (G)): (*[T1, *, one1](x, K)))) IMPLIES
       group?[left_cosets[T1, *, one1](G, K), mult[T1, *, one1](G, K), K]
           (fullset[left_cosets[T1, *, one1](G, K)]);

  % Subtype TCC generated (at line 17, column 23) for  inv[T1, *, one1](x)
      % expected type  (G)
  homo_inv_TCC1: OBLIGATION
    FORALL (G: group[T1, *, one1], GP: group[T2, o, one2],
            phi: homomorphism[T1, *, one1, T2, o, one2](G, GP), x: (G)):
      G(inv[T1, *, one1](x));

  % Subtype TCC generated (at line 56, column 79) for
      % extend[T2, (GP), bool, FALSE]
      %     (image(phi, restrict[T1, (G), boolean](H)))
      % expected type  group[T2, o, one2]
  homo_image_normal_TCC1: OBLIGATION
    FORALL (G: group[T1, *, one1], GP: group[T2, o, one2],
            phi: homomorphism[T1, *, one1, T2, o, one2](G, GP),
            H: normal_subgroup[T1, *, one1](G)):
      surjective?(phi) IMPLIES
       group?[T2, o, one2]
           (extend[T2, (GP), bool, FALSE]
                (image[(G), (GP)](phi, restrict[T1, (G), boolean](H))));

  % Subtype TCC generated (at line 64, column 54) for
      % extend[T1, (G), bool, FALSE](inverse_image(phi, K))
      % expected type  group[T1, *, one1]
  homo_inv_image_normal_TCC1: OBLIGATION
    FORALL (G: group[T1, *, one1], GP: group[T2, o, one2],
            phi: homomorphism[T1, *, one1, T2, o, one2](G, GP),
            K: normal_subgroup[T2, o, one2](GP)):
      group?[T1, *, one1]
          (extend[T1, (G), bool, FALSE](inverse_image[(G), T2](phi, K)));

  % Subtype TCC generated (at line 85, column 82) for  K
      % expected type  normal_subgroup[T1, *, one1](G)
  first_isomorphism_th_TCC1: OBLIGATION
    FORALL (G: group[T1, *, one1], GP: group[T2, o, one2],
            phi: homomorphism[T1, *, one1, T2, o, one2](G, GP),
            K: subgroup[T1, *, one1](G)):
      K = kernel(G, GP)(phi) IMPLIES normal_subgroup?[T1, *, one1](K, G);

  % Subtype TCC generated (at line 85, column 85) for
      % extend[T2, (GP), bool, FALSE]
      %     (image(phi, restrict[T1, (G), boolean](G)))
      % expected type  group[T2, o, one2]
  first_isomorphism_th_TCC2: OBLIGATION
    FORALL (G: group[T1, *, one1], GP: group[T2, o, one2],
            phi: homomorphism[T1, *, one1, T2, o, one2](G, GP),
            K: subgroup[T1, *, one1](G)):
      K = kernel(G, GP)(phi) IMPLIES
       group?[T2, o, one2]
           (extend[T2, (GP), bool, FALSE]
                (image[(G), (GP)](phi, restrict[T1, (G), boolean](G))));

  % Subtype TCC generated (at line 85, column 64) for  K
      % expected type  left_cosets[T1, *, one1](G, K)
  first_isomorphism_th_TCC3: OBLIGATION
    FORALL (G: group[T1, *, one1], GP: group[T2, o, one2],
            phi: homomorphism[T1, *, one1, T2, o, one2](G, GP),
            K: subgroup[T1, *, one1](G)):
      K = kernel(G, GP)(phi) IMPLIES
       (EXISTS (a: (G)): K = *[T1, *, one1](a, K));

  % Assuming TCC generated (at line 18, column 7) for
      % algebra@homomorphisms[left_cosets(G, K), mult(G, K), K, T2, o, one2]
      % generated from assumption homomorphisms.T1_is_group
  first_isomorphism_th_TCC4: OBLIGATION
    FORALL (G: group[T1, *, one1], GP: group[T2, o, one2],
            phi: homomorphism[T1, *, one1, T2, o, one2](G, GP),
            K: subgroup[T1, *, one1](G)):
      K = kernel(G, GP)(phi) IMPLIES
       group?[left_cosets[T1, *, one1](G, K), mult[T1, *, one1](G, K), K]
           (fullset[left_cosets[T1, *, one1](G, K)]);


body:
  %%-------------------** Isomorphism Theorems **-------------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%----------------------------------------------------------------


  isomorphism_theorems[T1: TYPE,
                      *: [T1,T1 -> T1],
                   one1: T1,
                     T2: TYPE,
                      o: [T2,T2 -> T2],
                   one2: T2]: THEORY

  BEGIN
    
     ASSUMING IMPORTING algebra@group_def

         T1_is_group: ASSUMPTION group?[T1,*,one1](fullset[T1])
         T2_is_group: ASSUMPTION group?[T2,o,one2](fullset[T2])

     ENDASSUMING


     IMPORTING homomorphism_lemmas

     G:  VAR group[T1,*,one1]
     GP: VAR group[T2,o,one2]
      S: VAR setofsets[T1]

  quotient_subgroup: LEMMA 
        FORALL (M, N:normal_subgroup(G)): 
          subgroup?(N,M)
            IMPLIES subgroup?[left_cosets(G,N),mult(G,N),N](M/N, G/N)


  second_isomorphism_th_aux: LEMMA 
    FORALL (H: subgroup(G), N: normal_subgroup(G)):
      LET NH = prod[T1,*,one1](N,H) IN
        EXISTS (varphi: [(H) -> (NH/N)]): 
                homomorphism?(H,NH/N,varphi)                AND 
                surjective?(varphi)                        AND 
                kernel(H, NH/N)(varphi) = intersection(N,H)   


  second_isomorphism_th: THEOREM 
    FORALL (H: subgroup(G), N: normal_subgroup(G)):
      LET NH = prod[T1,*,one1](N,H) IN
        normal_subgroup?[T1,*,one1](intersection(N,H),H) AND 
                    isomorphic?(H/intersection(N,H), NH/N)
  	
  	
  third_isomorphism_th_aux: LEMMA 
     FORALL (M, N:  normal_subgroup(G)): 
      subgroup?(N,M)
        IMPLIES
          EXISTS (psi: [(G/N) -> (G/M)]): 
                   homomorphism?(G/N,G/M,psi)    AND 
                   surjective?(psi)              AND 
                   kernel(G/N, G/M)(psi) = M/N   

  	       
  third_isomorphism_th: THEOREM 
     FORALL (M, N:  normal_subgroup(G)): 
      subgroup?(N,M)
        IMPLIES
          normal_subgroup?[left_cosets(G,N),mult(G,N),N](M/N, G/N)    AND
          isomorphic?((G/N)/(M/N), G/M)



  %%%%% Fourth Isomorphism Theorem %%%%%

  correspondence_theorem: THEOREM 
          FORALL (f: homomorphism(G,GP)):
             surjective?(f)
                IMPLIES
                  EXISTS (phi: [subgroup_contain(G,kernel(G,GP)(f))  -> subgroup(GP)]):
                     phi = (LAMBDA (N: subgroup_contain(G, kernel(G, GP)(f))): image(f, N))	AND
                     bijective?(phi)                                                              AND 
                     (FORALL (N: subgroup_contain(G,kernel(G,GP)(f))):  
                         (subgroup?[T1,*,one1](N,G) IFF subgroup?[T2,o,one2](phi(N), GP))          AND
                         (normal_subgroup?[T1,*,one1](N,G) IFF normal_subgroup?[T2,o,one2](phi(N), GP)))



  END isomorphism_theorems

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

  % Assuming TCC generated (at line 31, column 11) for  group[T1, *, one1]
      % generated from assumption group.fullset_is_group
  G_TCC1: OBLIGATION group?[T1, *, one1](fullset[T1]);

  % Assuming TCC generated (at line 32, column 11) for  group[T2, o, one2]
      % generated from assumption group.fullset_is_group
  GP_TCC1: OBLIGATION group?[T2, o, one2](fullset[T2]);

  % Subtype TCC generated (at line 38, column 60) for  N
      % expected type  normal_subgroup[T1, *, one1](M)
  quotient_subgroup_TCC1: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      subgroup?(N, M) IMPLIES normal_subgroup?[T1, *, one1](N, M);

  % Subtype TCC generated (at line 38, column 58) for  M / N
      % expected type  set[left_cosets(G, N)]
  quotient_subgroup_TCC2: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      subgroup?(N, M) IMPLIES
       (FORALL (x: set[T1]):
          (/[T1, *, one1](M, N))(x) IMPLIES
           ((EXISTS (a: (M)): x = *[T1, *, one1](a, N)) IFF
             (EXISTS (a: (G)): x = *[T1, *, one1](a, N))));

  % Subtype TCC generated (at line 38, column 55) for  N
      % expected type  left_cosets[T1, *, one1](G, N)
  quotient_subgroup_TCC3: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      subgroup?(N, M) IMPLIES (EXISTS (a: (G)): N = *[T1, *, one1](a, N));

  % Existence TCC generated (at line 38, column 18) for
      % subgroup?[left_cosets(G, N), mult(G, N), N]
  quotient_subgroup_TCC4: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      subgroup?(N, M) IMPLIES
       (EXISTS (x: left_cosets[T1, *, one1](G, N)): TRUE);

  % Subtype TCC generated (at line 45, column 30) for  NH
      % expected type  group[T1, *, one1]
  second_isomorphism_th_aux_TCC1: OBLIGATION
    FORALL (G: group[T1, *, one1], H: subgroup[T1, *, one1](G),
            N: normal_subgroup[T1, *, one1](G), NH: set[T1]):
      NH = prod[T1, *, one1](N, H) IMPLIES
       (FORALL (varphi: [(H) -> (/[T1, *, one1](NH, N))]):
          group?[T1, *, one1](NH));

  % Subtype TCC generated (at line 45, column 33) for  N
      % expected type  normal_subgroup[T1, *, one1](NH)
  second_isomorphism_th_aux_TCC2: OBLIGATION
    FORALL (G: group[T1, *, one1], H: subgroup[T1, *, one1](G),
            N: normal_subgroup[T1, *, one1](G), NH: set[T1]):
      NH = prod[T1, *, one1](N, H) IMPLIES
       (FORALL (varphi: [(H) -> (/[T1, *, one1](NH, N))]):
          normal_subgroup?[T1, *, one1](N, NH));

  % Subtype TCC generated (at line 45, column 33) for  N
      % expected type  left_cosets[T1, *, one1](NH, N)
  second_isomorphism_th_aux_TCC3: OBLIGATION
    FORALL (G: group[T1, *, one1], H: subgroup[T1, *, one1](G),
            N: normal_subgroup[T1, *, one1](G), NH: set[T1]):
      NH = prod[T1, *, one1](N, H) IMPLIES
       (FORALL (varphi: [(H) -> (/[T1, *, one1](NH, N))]):
          EXISTS (a: (NH)): N = *[T1, *, one1](a, N));

  % Assuming TCC generated (at line 26, column 14) for
      % algebra@homomorphisms
      %     [T1, *, one1, left_cosets[T1, *, one1](NH, N),
      %      mult[T1, *, one1](NH, N), N]
      % generated from assumption homomorphisms.T2_is_group
  second_isomorphism_th_aux_TCC4: OBLIGATION
    FORALL (G: group[T1, *, one1], H: subgroup[T1, *, one1](G),
            N: normal_subgroup[T1, *, one1](G), NH: set[T1]):
      NH = prod[T1, *, one1](N, H) IMPLIES
       (FORALL (varphi: [(H) -> (/[T1, *, one1](NH, N))]):
          group?[left_cosets[T1, *, one1](NH, N), mult[T1, *, one1](NH, N), N]
              (fullset[left_cosets[T1, *, one1](NH, N)]));

  % Subtype TCC generated (at line 53, column 34) for  intersection(N, H)
      % expected type  group[T1, *, one1]
  second_isomorphism_th_TCC1: OBLIGATION
    FORALL (G: group[T1, *, one1], H: subgroup[T1, *, one1](G),
            N: normal_subgroup[T1, *, one1](G), NH: set[T1]):
      NH = prod[T1, *, one1](N, H) IMPLIES
       group?[T1, *, one1](intersection[T1](N, H));

  % Subtype TCC generated (at line 54, column 51) for  NH
      % expected type  group[T1, *, one1]
  second_isomorphism_th_TCC2: OBLIGATION
    FORALL (G: group[T1, *, one1], H: subgroup[T1, *, one1](G),
            N: normal_subgroup[T1, *, one1](G), NH: set[T1]):
      normal_subgroup?[T1, *, one1](intersection(N, H), H) AND
       NH = prod[T1, *, one1](N, H)
       IMPLIES group?[T1, *, one1](NH);

  % Subtype TCC generated (at line 54, column 54) for  N
      % expected type  normal_subgroup[T1, *, one1](NH)
  second_isomorphism_th_TCC3: OBLIGATION
    FORALL (G: group[T1, *, one1], H: subgroup[T1, *, one1](G),
            N: normal_subgroup[T1, *, one1](G), NH: set[T1]):
      normal_subgroup?[T1, *, one1](intersection(N, H), H) AND
       NH = prod[T1, *, one1](N, H)
       IMPLIES normal_subgroup?[T1, *, one1](N, NH);

  % Subtype TCC generated (at line 54, column 32) for  intersection(N, H)
      % expected type  left_cosets[T1, *, one1](H, intersection(N, H))
  second_isomorphism_th_TCC4: OBLIGATION
    FORALL (G: group[T1, *, one1], H: subgroup[T1, *, one1](G),
            N: normal_subgroup[T1, *, one1](G), NH: set[T1]):
      normal_subgroup?[T1, *, one1](intersection(N, H), H) AND
       NH = prod[T1, *, one1](N, H)
       IMPLIES
       (EXISTS (a: (H)):
          intersection[T1](N, H) = *[T1, *, one1](a, intersection[T1](N, H)));

  % Subtype TCC generated (at line 54, column 54) for  N
      % expected type  left_cosets[T1, *, one1](NH, N)
  second_isomorphism_th_TCC5: OBLIGATION
    FORALL (G: group[T1, *, one1], H: subgroup[T1, *, one1](G),
            N: normal_subgroup[T1, *, one1](G), NH: set[T1]):
      normal_subgroup?[T1, *, one1](intersection(N, H), H) AND
       NH = prod[T1, *, one1](N, H)
       IMPLIES (EXISTS (a: (NH)): N = *[T1, *, one1](a, N));

  % Assuming TCC generated (at line 26, column 14) for
      % algebra@homomorphisms
      %     [left_cosets[T1, *, one1](H, intersection(N, H)),
      %      mult[T1, *, one1](H, intersection(N, H)), intersection(N, H),
      %      left_cosets[T1, *, one1](NH, N), mult[T1, *, one1](NH, N), N]
      % generated from assumption homomorphisms.T1_is_group
  second_isomorphism_th_TCC6: OBLIGATION
    FORALL (G: group[T1, *, one1], H: subgroup[T1, *, one1](G),
            N: normal_subgroup[T1, *, one1](G), NH: set[T1]):
      normal_subgroup?[T1, *, one1](intersection(N, H), H) AND
       NH = prod[T1, *, one1](N, H)
       IMPLIES
       group?
           [left_cosets[T1, *, one1](H, intersection(N, H)),
            mult[T1, *, one1](H, intersection[T1](N, H)),
            intersection[T1](N, H)]
           (fullset[left_cosets[T1, *, one1](H, intersection(N, H))]);

  % Assuming TCC generated (at line 26, column 14) for
      % algebra@homomorphisms
      %     [left_cosets[T1, *, one1](H, intersection(N, H)),
      %      mult[T1, *, one1](H, intersection(N, H)), intersection(N, H),
      %      left_cosets[T1, *, one1](NH, N), mult[T1, *, one1](NH, N), N]
      % generated from assumption homomorphisms.T2_is_group
  second_isomorphism_th_TCC7: OBLIGATION
    FORALL (G: group[T1, *, one1], H: subgroup[T1, *, one1](G),
            N: normal_subgroup[T1, *, one1](G), NH: set[T1]):
      normal_subgroup?[T1, *, one1](intersection(N, H), H) AND
       NH = prod[T1, *, one1](N, H)
       IMPLIES
       group?[left_cosets[T1, *, one1](NH, N), mult[T1, *, one1](NH, N), N]
           (fullset[left_cosets[T1, *, one1](NH, N)]);

  % Subtype TCC generated (at line 62, column 37) for  M
      % expected type  left_cosets[T1, *, one1](G, M)
  third_isomorphism_th_aux_TCC1: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      subgroup?(N, M) IMPLIES
       (FORALL (psi: [(/[T1, *, one1](G, N)) -> (/[T1, *, one1](G, M))]):
          EXISTS (a: (G)): M = *[T1, *, one1](a, M));

  % Assuming TCC generated (at line 26, column 14) for
      % algebra@homomorphisms
      %     [left_cosets[T1, *, one1](G, N), mult[T1, *, one1](G, N), N,
      %      left_cosets[T1, *, one1](G, M), mult[T1, *, one1](G, M), M]
      % generated from assumption homomorphisms.T1_is_group
  third_isomorphism_th_aux_TCC2: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      subgroup?(N, M) IMPLIES
       (FORALL (psi: [(/[T1, *, one1](G, N)) -> (/[T1, *, one1](G, M))]):
          group?[left_cosets[T1, *, one1](G, N), mult[T1, *, one1](G, N), N]
              (fullset[left_cosets[T1, *, one1](G, N)]));

  % Assuming TCC generated (at line 26, column 14) for
      % algebra@homomorphisms
      %     [left_cosets[T1, *, one1](G, N), mult[T1, *, one1](G, N), N,
      %      left_cosets[T1, *, one1](G, M), mult[T1, *, one1](G, M), M]
      % generated from assumption homomorphisms.T2_is_group
  third_isomorphism_th_aux_TCC3: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      subgroup?(N, M) IMPLIES
       (FORALL (psi: [(/[T1, *, one1](G, N)) -> (/[T1, *, one1](G, M))]):
          group?[left_cosets[T1, *, one1](G, M), mult[T1, *, one1](G, M), M]
              (fullset[left_cosets[T1, *, one1](G, M)]));

  % Subtype TCC generated (at line 71, column 55) for  M / N
      % expected type  group[left_cosets(G, N), mult(G, N), N]
  third_isomorphism_th_TCC1: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      subgroup?(N, M) IMPLIES
       (FORALL (x: set[T1]):
          (/[T1, *, one1](M, N))(x) IMPLIES
           ((EXISTS (a: (M)): x = *[T1, *, one1](a, N)) IFF
             (EXISTS (a: (G)): x = *[T1, *, one1](a, N))))
        AND
        group?[left_cosets[T1, *, one1](G, N), mult[T1, *, one1](G, N), N]
            (/[T1, *, one1](M, N));

  % Assuming TCC generated (at line 6, column 7) for
      % algebra@normal_subgroups[left_cosets(G, N), mult(G, N), N]
      % generated from assumption normal_subgroups.fullset_is_group
  third_isomorphism_th_TCC2: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      subgroup?(N, M) IMPLIES
       group?[left_cosets[T1, *, one1](G, N), mult(G, N), N]
           (fullset[left_cosets[T1, *, one1](G, N)]);

  % Subtype TCC generated (at line 72, column 27) for  (M / N)
      % expected type  left_cosets
                     %     [left_cosets[T1, *, one1](G, N),
                     %      mult[T1, *, one1](G, N), N]((G / N), (M / N))
  third_isomorphism_th_TCC3: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      normal_subgroup?[left_cosets[T1, *, one1](G, N), mult(G, N), N]
          (M / N, G / N)
       AND subgroup?(N, M)
       IMPLIES
       (FORALL (x: set[T1]):
          (/[T1, *, one1](M, N))(x) IMPLIES
           ((EXISTS (a: (M)): x = *[T1, *, one1](a, N)) IFF
             (EXISTS (a: (G)): x = *[T1, *, one1](a, N))))
        AND
        (EXISTS (a: (/[T1, *, one1](G, N))):
           (/[T1, *, one1](M, N)) =
            *[left_cosets[T1, *, one1](G, N), mult[T1, *, one1](G, N), N]
                (a, (/[T1, *, one1](M, N))));

  % Subtype TCC generated (at line 72, column 35) for  M
      % expected type  left_cosets[T1, *, one1](G, M)
  third_isomorphism_th_TCC4: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      normal_subgroup?[left_cosets[T1, *, one1](G, N), mult(G, N), N]
          (M / N, G / N)
       AND subgroup?(N, M)
       IMPLIES (EXISTS (a: (G)): M = *[T1, *, one1](a, M));

  % Assuming TCC generated (at line 26, column 14) for
      % algebra@homomorphisms
      %     [left_cosets
      %          [left_cosets[T1, *, one1](G, N), mult[T1, *, one1](G, N),
      %           N]((G / N), (M / N)),
      %      mult[left_cosets[T1, *, one1](G, N), mult[T1, *, one1](G, N), N]
      %          ((G / N), (M / N)),
      %      (M / N), left_cosets[T1, *, one1](G, M),
      %      mult[T1, *, one1](G, M), M]
      % generated from assumption homomorphisms.T1_is_group
  third_isomorphism_th_TCC5: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      normal_subgroup?[left_cosets[T1, *, one1](G, N), mult(G, N), N]
          (M / N, G / N)
       AND subgroup?(N, M)
       IMPLIES
       group?
           [left_cosets
                [left_cosets[T1, *, one1](G, N), mult[T1, *, one1](G, N),
                 N]((G / N), (M / N)),
            mult[left_cosets[T1, *, one1](G, N), mult[T1, *, one1](G, N), N]
                ((/[T1, *, one1](G, N)), (/[T1, *, one1](M, N))),
            (/[T1, *, one1](M, N))]
           (fullset
                [left_cosets
                     [left_cosets[T1, *, one1](G, N),
                      mult[T1, *, one1](G, N), N]((G / N), (M / N))]);

  % Assuming TCC generated (at line 26, column 14) for
      % algebra@homomorphisms
      %     [left_cosets
      %          [left_cosets[T1, *, one1](G, N), mult[T1, *, one1](G, N),
      %           N]((G / N), (M / N)),
      %      mult[left_cosets[T1, *, one1](G, N), mult[T1, *, one1](G, N), N]
      %          ((G / N), (M / N)),
      %      (M / N), left_cosets[T1, *, one1](G, M),
      %      mult[T1, *, one1](G, M), M]
      % generated from assumption homomorphisms.T2_is_group
  third_isomorphism_th_TCC6: OBLIGATION
    FORALL (G: group[T1, *, one1], M, N: normal_subgroup[T1, *, one1](G)):
      normal_subgroup?[left_cosets[T1, *, one1](G, N), mult(G, N), N]
          (M / N, G / N)
       AND subgroup?(N, M)
       IMPLIES
       group?[left_cosets[T1, *, one1](G, M), mult[T1, *, one1](G, M), M]
           (fullset[left_cosets[T1, *, one1](G, M)]);


body:
  %%-------------------** Sylow Theorems **-------------------
  %%                                                                          
  %% Author          : André Luiz Galdino 
  %%                   Universidade Federal de Goiás - Brasil
  %%                    
  %% Last Modified On: November 28, 2011
  %%                                                                          
  %%----------------------------------------------------------


  sylow_theorems[T: TYPE, *: [T,T -> T], one: T]: THEORY

  BEGIN
    
     ASSUMING IMPORTING algebra@group_def

         T_is_group: ASSUMPTION group?[T,*,one](fullset[T])

     ENDASSUMING


     IMPORTING algebra@finite_groups[T,*,one],
               isomorphism_theorems, 
               p_groups

               G: VAR group[T,*,one]
               X: VAR setofsets[T]
      p, n, m, i: VAR posnat


  %%%%% Definitions %%%%%

     p_subgroup_sylow?(G:finite_group, p:{p: posnat | prime?(p)})(P:subgroup(G)): bool = 
        p_group?[T,*,one](P,p) AND 
       (FORALL (H: subgroup(G)): p_group?[T,*,one](H,p) AND subgroup?(P,H) IMPLIES P = H)


     p_subgroup_sylow(G:finite_group, p:{p: posnat | prime?(p)}): setofsets[T] = 
                                                                  {P: subgroup(G) | p_subgroup_sylow?(G,p)(P)}


     is_conjugate(G:finite_group,H:subgroup(G))(S:subgroup(G)): bool = EXISTS (a: (G)): S = a*H*inv(a)

   
     action_by_c(G:finite_group, X)(a:(G), P:(X)): set[T] = a*P*inv(a)


  %%%%% Quotient subgroups %%%%%

     subgroup_is_factor: LEMMA FORALL (N: normal_subgroup(G), S: subgroup(G/N)): 
                                        EXISTS (H: subgroup(G)): subgroup?(N,H) AND S = H/N



  %%%%% First Sylow Theorem %%%%%

     First_Sylow_Theorem: THEOREM 
              FORALL (G:finite_group): prime?(p) AND order(G) = p^(n)*m AND gcd(p,m) = 1 AND i <= n
                 IMPLIES
                       (EXISTS (H: subgroup(G)): order(H) = p^i)
                                        AND
                       (FORALL (S: subgroup(G)): order(S) = p^(i - 1) 
                          IMPLIES 
                             EXISTS (K: subgroup(G)): order(K) = p^i AND normal_subgroup?(S,K))


     p_group_is_subgroup: COROLLARY 
                 FORALL (G:finite_group, H: subgroup(G)): 
                   prime?(p) AND gcd(p,m) = 1 AND i <= n AND order(G) = p^(n)*m  AND order(H) = p^(n - i)
                    IMPLIES
                       EXISTS (K: subgroup(G)): order(K) = p^(n) AND subgroup?(H,K)


     p_subgroup_sylow_order: COROLLARY FORALL (G:finite_group, P:subgroup(G)): 
                                          prime?(p) AND order(G) = p^(n)*m AND gcd(p,m) = 1 
                                              IMPLIES
                                                  (p_subgroup_sylow?(G,p)(P) IFF order(P) = p^(n))

     conjugate_is_p_subgroup_sylow: COROLLARY  FORALL (G:finite_group, P:subgroup(G)): 
                                          prime?(p) AND order(G) = p^(n)*m AND gcd(p,m) = 1 AND
                                          p_subgroup_sylow?(G,p)(P)
                                              IMPLIES 
                                                  FORALL (a:(G)): p_subgroup_sylow?(G,p)(a*P*inv(a))

     unique_is_normal: COROLLARY  FORALL (G:finite_group, P:subgroup(G)): 
                                          prime?(p) AND order(G) = p^(n)*m AND gcd(p,m) = 1 AND
                                          p_subgroup_sylow(G,p) = singleton(P)
                                              IMPLIES 
                                                  normal_subgroup?(P,G)


  %%%%% Second Sylow Theorem %%%%%


     Second_Sylow_Theorem: THEOREM 
              FORALL (G:finite_group, P, K:subgroup(G)): 
                 prime?(p) AND order(G) = p^(n)*m AND gcd(p,m) = 1 AND 
                 p_subgroup_sylow?(G,p)(P) AND p_group?[T,*,one](K,p)
                    IMPLIES
                       EXISTS (a:(G)): subgroup?(K,a*P*inv(a))
                                        AND
                       (p_subgroup_sylow?(G,p)(K) IMPLIES is_conjugate(G,P)(K))



  %%%%% Third Sylow Theorem %%%%%



     Third_Sylow_Theorem: THEOREM 
              FORALL (G:finite_group, P:subgroup(G)): 
                 prime?(p) AND order(G) = p^(n)*m AND gcd(p,m) = 1 AND 
                 p_subgroup_sylow?(G,p)(P)
                     IMPLIES
                       LET np = card(p_subgroup_sylow(G,p)) IN
                       np = index(G, normalizer(G,P)) AND divides(np,m) AND divides(p, np -1)


  END sylow_theorems

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

  % Assuming TCC generated (at line 23, column 13) for
      % algebra@finite_groups[T, *, one]
      % generated from assumption finite_groups.fullset_is_group
  IMP_finite_groups_TCC1: OBLIGATION group?[T, *, one](fullset[T]);

  % Subtype TCC generated (at line 35, column 24) for  P
      % expected type  finite_group[T, *, one]
  p_subgroup_sylow?_TCC1: OBLIGATION
    FORALL (G: finite_group[T, *, one], p: {p: posnat | prime?(p)},
            P: subgroup[T, *, one](G)):
      finite_group?[T, *, one](P);

  % Subtype TCC generated (at line 36, column 49) for  H
      % expected type  finite_group[T, *, one]
  p_subgroup_sylow?_TCC2: OBLIGATION
    FORALL (G: finite_group[T, *, one], p: {p: posnat | prime?(p)},
            P: subgroup[T, *, one](G)):
      p_group?[T, *, one](P, p) IMPLIES
       (FORALL (H: subgroup[T, *, one](G)): finite_group?[T, *, one](H));

  % Subtype TCC generated (at line 51, column 74) for  N
      % expected type  left_cosets[T, *, one](G, N)
  subgroup_is_factor_TCC1: OBLIGATION
    FORALL (G: group[T, *, one], N: normal_subgroup[T, *, one](G)):
      EXISTS (a: (G)): N = *[T, *, one](a, N);

  % Assuming TCC generated (at line 24, column 13) for
      % algebra@group[left_cosets[T, *, one](G, N), mult[T, *, one](G, N), N]
      % generated from assumption group.fullset_is_group
  subgroup_is_factor_TCC2: OBLIGATION
    FORALL (G: group[T, *, one], N: normal_subgroup[T, *, one](G)):
      group?[left_cosets[T, *, one](G, N), mult[T, *, one](G, N), N]
          (fullset[left_cosets[T, *, one](G, N)]);

  % Subtype TCC generated (at line 52, column 88) for  N
      % expected type  normal_subgroup[T, *, one](H)
  subgroup_is_factor_TCC3: OBLIGATION
    FORALL (G: group[T, *, one], N: normal_subgroup[T, *, one](G),
            S:
              subgroup
                  [left_cosets[T, *, one](G, N), mult[T, *, one](G, N),
                   N](/[T, *, one](G, N)),
            H: subgroup[T, *, one](G)):
      subgroup?(N, H) IMPLIES normal_subgroup?[T, *, one](N, H);

  % Subtype TCC generated (at line 52, column 86) for  H / N
      % expected type  set[left_cosets[T, *, one](G, N)]
  subgroup_is_factor_TCC4: OBLIGATION
    FORALL (G: group[T, *, one], N: normal_subgroup[T, *, one](G),
            S:
              subgroup
                  [left_cosets[T, *, one](G, N), mult[T, *, one](G, N),
                   N](/[T, *, one](G, N)),
            H: subgroup[T, *, one](G)):
      subgroup?(N, H) IMPLIES
       (FORALL (x: set[T]):
          (/[T, *, one](H, N))(x) IMPLIES
           ((EXISTS (a: (H)): x = *[T, *, one](a, N)) IFF
             (EXISTS (a: (G)): x = *[T, *, one](a, N))));

  % Subtype TCC generated (at line 59, column 65) for  (n)
      % expected type  {i: int | p /= 0 OR i >= 0}
  First_Sylow_Theorem_TCC1: OBLIGATION
    FORALL (n, p: posnat): prime?(p) IMPLIES p /= 0 OR n >= 0;

  % Subtype TCC generated (at line 59, column 80) for  m
      % expected type  {jj: int | p = 0 => jj /= 0}
  First_Sylow_Theorem_TCC2: OBLIGATION
    FORALL (m, n, p: posnat, G: finite_group[T, *, one]):
      order(G) = p ^ n * m AND prime?(p) IMPLIES p = 0 => m /= 0;

  % Subtype TCC generated (at line 61, column 53) for  H
      % expected type  finite_monad[T, *, one]
  First_Sylow_Theorem_TCC3: OBLIGATION
    FORALL (i, m, n, p: posnat, G: finite_group[T, *, one]):
      prime?(p) AND order(G) = p ^ n * m AND gcd(p, m) = 1 AND i <= n IMPLIES
       (FORALL (H: subgroup[T, *, one](G)): finite_monad?[T, *, one](H));

  % Subtype TCC generated (at line 61, column 60) for  i
      % expected type  {i: int | p /= 0 OR i >= 0}
  First_Sylow_Theorem_TCC4: OBLIGATION
    FORALL (i, m, n, p: posnat, G: finite_group[T, *, one]):
      prime?(p) AND order(G) = p ^ n * m AND gcd(p, m) = 1 AND i <= n IMPLIES
       (FORALL (H: subgroup[T, *, one](G)): p /= 0 OR i >= 0);

  % Subtype TCC generated (at line 63, column 61) for  (i - 1)
      % expected type  {i: int | p /= 0 OR i >= 0}
  First_Sylow_Theorem_TCC5: OBLIGATION
    FORALL (i, m, n, p: posnat, G: finite_group[T, *, one]):
           EXISTS (H: subgroup(G)): order(H) = p ^ i AND prime?(p)
       AND order(G) = p ^ n * m AND gcd(p, m) = 1 AND i <= n
       IMPLIES (FORALL (S: subgroup[T, *, one](G)): p /= 0 OR (i - 1) >= 0);

  % Subtype TCC generated (at line 65, column 58) for  K
      % expected type  finite_monad[T, *, one]
  First_Sylow_Theorem_TCC6: OBLIGATION
    FORALL (i, m, n, p: posnat, G: finite_group[T, *, one]):
           EXISTS (H: subgroup(G)): order(H) = p ^ i AND prime?(p)
       AND order(G) = p ^ n * m AND gcd(p, m) = 1 AND i <= n
       IMPLIES
       (FORALL (S: subgroup[T, *, one](G)):
          order(S) = p ^ (i - 1) IMPLIES
           (FORALL (K: subgroup[T, *, one](G)): finite_monad?[T, *, one](K)));

  % Subtype TCC generated (at line 70, column 37) for  m
      % expected type  {jj: int | p = 0 => jj /= 0}
  p_group_is_subgroup_TCC1: OBLIGATION
    FORALL (m, p: posnat, G: finite_group[T, *, one],
            H: subgroup[T, *, one](G)):
      prime?(p) IMPLIES p = 0 => m /= 0;

  % Subtype TCC generated (at line 70, column 97) for  (n - i)
      % expected type  {i: int | p /= 0 OR i >= 0}
  p_group_is_subgroup_TCC2: OBLIGATION
    FORALL (i, m, n, p: posnat, G: finite_group[T, *, one],
            H: subgroup[T, *, one](G)):
      order(G) = p ^ n * m AND i <= n AND gcd(p, m) = 1 AND prime?(p) IMPLIES
       p /= 0 OR (n - i) >= 0;

  % Subtype TCC generated (at line 72, column 52) for  K
      % expected type  finite_monad[T, *, one]
  p_group_is_subgroup_TCC3: OBLIGATION
    FORALL (i, m, n, p: posnat, G: finite_group[T, *, one],
            H: subgroup[T, *, one](G)):
           prime?(p) AND gcd(p, m) = 1 AND i <= n AND order(G) = p ^ n * m
       AND order(H) = p ^ (n - i)
       IMPLIES
       (FORALL (K: subgroup[T, *, one](G)): finite_monad?[T, *, one](K));

  % Subtype TCC generated (at line 78, column 85) for  P
      % expected type  finite_monad[T, *, one]
  p_subgroup_sylow_order_TCC1: OBLIGATION
    FORALL (m, n, p: posnat, G: finite_group[T, *, one],
            P: subgroup[T, *, one](G)):
      prime?(p) AND order(G) = p ^ n * m AND gcd(p, m) = 1 IMPLIES
       finite_monad?[T, *, one](P);

  % Subtype TCC generated (at line 84, column 87) for  a * P * inv(a)
      % expected type  subgroup[T, *, one](G)
  conjugate_is_p_subgroup_sylow_TCC1: OBLIGATION
    FORALL (m, n, p: posnat, G: finite_group[T, *, one],
            P: subgroup[T, *, one](G)):
      prime?(p) AND
       order(G) = p ^ n * m AND gcd(p, m) = 1 AND p_subgroup_sylow?(G, p)(P)
       IMPLIES
       (FORALL (a: (G)):
          group?[T, *, one]
              (*[T, *, one](*[T, *, one](a, P), inv[T, *, one](a)))
           AND
           subgroup?[T, *, one]
               (*[T, *, one](*[T, *, one](a, P), inv[T, *, one](a)), G));

  % Subtype TCC generated (at line 99, column 63) for  K
      % expected type  finite_group[T, *, one]
  Second_Sylow_Theorem_TCC1: OBLIGATION
    FORALL (m, n, p: posnat, G: finite_group[T, *, one],
            P, K: subgroup[T, *, one](G)):
      p_subgroup_sylow?(G, p)(P) AND
       gcd(p, m) = 1 AND order(G) = p ^ n * m AND prime?(p)
       IMPLIES finite_group?[T, *, one](K);

  % Subtype TCC generated (at line 101, column 49) for  a * P * inv(a)
      % expected type  (group?)
  Second_Sylow_Theorem_TCC2: OBLIGATION
    FORALL (m, n, p: posnat, G: finite_group[T, *, one],
            P, K: subgroup[T, *, one](G)):
           prime?(p) AND order(G) = p ^ n * m AND gcd(p, m) = 1
       AND p_subgroup_sylow?(G, p)(P) AND p_group?[T, *, one](K, p)
       IMPLIES
       (FORALL (a: (G)):
          group?[T, *, one]
              (*[T, *, one](*[T, *, one](a, P), inv[T, *, one](a))));

  % Subtype TCC generated (at line 116, column 35) for  p_subgroup_sylow(G, p)
      % expected type  S: finite_set[setof[T]]
  Third_Sylow_Theorem_TCC1: OBLIGATION
    FORALL (m, n, p: posnat, G: finite_group[T, *, one],
            P: subgroup[T, *, one](G)):
      prime?(p) AND
       order(G) = p ^ n * m AND gcd(p, m) = 1 AND p_subgroup_sylow?(G, p)(P)
       IMPLIES is_finite[setof[T]](p_subgroup_sylow(G, p));

  % Subtype TCC generated (at line 117, column 35) for  normalizer(G, P)
      % expected type  subgroup[T, *, one](G)
  Third_Sylow_Theorem_TCC2: OBLIGATION
    FORALL (m, n, p: posnat, G: finite_group[T, *, one],
            P: subgroup[T, *, one](G)):
      prime?(p) AND
       order(G) = p ^ n * m AND gcd(p, m) = 1 AND p_subgroup_sylow?(G, p)(P)
       IMPLIES
       (FORALL (np:
                  {n_1: nat | n_1 = Card[setof[T]](p_subgroup_sylow(G, p))}):
          np = card(p_subgroup_sylow(G, p)) IMPLIES
           group?[T, *, one](normalizer[T, *, one](G, P)) AND
            subgroup?[T, *, one](normalizer[T, *, one](G, P), G));


body:
  %% top.pvs
  %% Author: Cesar Munoz, Anthony Narkawicz
  %% Interval Arithmetic 

  top : THEORY
  BEGIN

    IMPORTING interval,
              proper_arith,
              safe_arith,
              IntervalExpr,
              box,
              interval_expr,
              interval_bexpr,
              simple_bandb,
              numerical_bandb,
              interval_bandb,
              interval_bolzano,
              interval_sqrt,
              interval_trig,
  	    interval_lnexp,
  	    interval_deriv,
              subinterval_deriv,
              interval_chain,
  	    interval_taylor,
              interval_io,
              interval_expr_sqrt,
              interval_expr_trig,
              interval_expr_lnexp,
              strategies4Q,
              examples4Q,
              strategies,
              examples,
              top_allen 

  END top


body:
  %% interval.pvs
  interval : THEORY
  BEGIN

  %% Comparison and arithmetic interl operators defined in this theory assume, without checking, 
  %% that their operands are non-empty. Their correctness lemmas have as hypotheses that the operands 
  %% are "proper", e.g., non-empty. Proper and safe versions arithmetic operators are defined in
  %% the theories proper_arith and safe_arith.  
  %%
  %% Since version 6.0.5 of the NASA PVS Library, symbols <,<=,>,>=,+,-,*,/,^ are no longer used in
  %% the interval arithmetic library. For convenience and backward compatibility the following theories
  %% are provided:
  %% - symbols_as_interval: Defines those symbols as the basic interval operators defined in this theory.
  %% - symbols_as_proper: Defines those symbols as the interval operators defined in the theory proper_arith.
  %% - symbols_as_safe: Defines those symbols as the interval operators defined in the theory safe_arith.
  %% To avoid name clashes only one these 3 theories may be included in an imported chain.

    IMPORTING reals@sq,reals@sigma_nat,ints@div_nat

  %%-------------------
  %% Type and Notations
  %%-------------------

    Interval : TYPE = [#
                 lb : real,
                 ub : real
               #]
    X,Y,Z : VAR Interval
    x,y   : VAR real
    n     : VAR nat
    i     : VAR int
    p     : VAR posnat
    f     : VAR [nat->real]
    F     : VAR [nat->Interval]

  %%----------
  %% Operators
  %%----------

    ;##(x,X) : bool =
      lb(X) <= x AND x <= ub(X)

    % membership
    Member?(X)(x) : MACRO bool =
      x ## X

    CONVERSION Member?

    % Type of reals in interval X 
    IntervalType(X) : TYPE = (Member?(X))

    % interval is non-empty
    Proper?(X:Interval) : bool =
      lb(X) <= ub(X)

    ProperInterval : TYPE = (Proper?)

    Member_Proper : LEMMA
      x ## X IMPLIES
      Proper?(X)

    Proper_Member : LEMMA
      Proper?(X) IMPLIES
      EXISTS (x): x ## X

    % interval has more than one element
    StrictInterval?(X:Interval) : bool = 
      lb(X) < ub(X)

    StrictInterval : TYPE = (StrictInterval?)

    [||](x,y) : Interval  = (# lb := x, ub := y #)

    [||](x)   : Interval = (# lb := x, ub := x #)

    r2i_Proper : JUDGEMENT
      [||](x) HAS_TYPE ProperInterval

    EmptyInterval : Interval = [|1,0|]

    EmptyInterval?(X) :  bool = 
      lb(X) > ub(X)

    Proper_eq_NonEmpty : LEMMA
      Proper?(X) IFF NOT EmptyInterval?(X)

    Proper_NonEmpty : LEMMA
      NOT Proper?(EmptyInterval)

    % inclusion
    ;<<(X,Y) : bool =
      lb(Y) <= lb(X) AND ub(X) <= ub(Y)

    eq_Incl : LEMMA
      X = Y IFF X << Y AND Y << X

    Incl_Member : LEMMA
      X << Y IMPLIES FORALL (x:real) : x ## X IMPLIES x ## Y

    Member_Incl : LEMMA
      Proper?(X) AND 
      (FORALL (x:real) : x ## X IMPLIES x ## Y) IMPLIES
      X << Y 

    Incl_Proper : LEMMA
      X << Y AND Proper?(X) IMPLIES
        Proper?(Y)

    % Type of subintervals included in interval X 
    SubInterval(X) : TYPE = {Y | Y << X}

    % Type of proper subintervals included in interval X 
    ProperIntervalOf(X) : TYPE = {Y:ProperInterval | Y << X}

    % Type of strictly proper subintervals included in interval X 
    StrictIntervalOf(X) : TYPE = {Y:StrictInterval | Y << X}

    slice(X,p) :  real = 
      ((p-1)*lb(X) + ub(X))/p
    
    % Midpoint of interval
    midpoint(X) : real =
      slice(X,2)

    midpoint_inclusion : LEMMA
      Proper?(X) IMPLIES
      midpoint(X) ## X

    % Interval size
    size(X) : real =
      ub(X) - lb(X)

    % Halves
    HalfLeft(X) : Interval =
      [| lb(X),midpoint(X) |]

    HalfRight(X) : Interval =
      [| midpoint(X),ub(X) |]

    % lt
    Lt(X,x) : bool =
      lb(X) < x AND ub(X) < x 

    % le
    Le(X,x) : bool =
       lb(X) <= x AND ub(X) <= x

    % gt
    Gt(X,x) : bool =
       lb(X) > x AND ub(X) > x 

    % ge
    Ge(X,x) : bool =
       lb(X) >= x AND ub(X) >= x 

    Pos?(X) : bool  = Gt(X,0)

    Neg?(X) : bool  = Lt(X,0)

    NonNeg?(X) : bool = Ge(X,0)

    Lt_Ge : LEMMA
      Lt(X,x) AND Ge(X,x) IMPLIES
      EmptyInterval?(X)

    Le_Gt : LEMMA
      Le(X,x) AND Gt(X,x) IMPLIES
      EmptyInterval?(X)

    % 0 is in X
    Zeroin?(X) :  bool =
      lb(X) < 0 AND 0 < ub(X) 

    % 0 is not in X
    Zeroless?(X) : bool =
      lb(X) > 0 OR ub(X) < 0

    Trichotomy : LEMMA
      Proper?(X) IMPLIES
        (Ge(X,0) OR Le(X,0) OR Zeroin?(X))

    % Addition
    Add(X,Y) : Interval =
      [|lb(X)+lb(Y),ub(X)+ub(Y)|]

    % Subtraction
    Sub(X,Y) : Interval =
      [|lb(X)-ub(Y),ub(X)-lb(Y)|]

    % Negation
    Neg(X): Interval =
      [|-ub(X),-lb(X)|]

    % Absolute value
    Abs(X) : (NonNeg?) =
      if Zeroin?(X) then 
       [|0,max(abs(lb(X)),abs(ub(X)))|]
      else
       [|min(abs(lb(X)),abs(ub(X))),max(abs(lb(X)),abs(ub(X)))|]
      endif

    % pos * pos
    pXp(X,Y) : Interval = 
      [|lb(X)*lb(Y),ub(X)*ub(Y)|]

    % neg * pos
    nXp(X,Y) : Interval = 
      Neg(pXp(Neg(X),Y))

    % pos * neg
    pXn(X,Y) : Interval = 
      nXp(Y,X)

    % neg * neg
    nXn(X,Y) : Interval = 
      pXp(Neg(X),Neg(Y))    

    % pos * med
    pXm(X,Y) : Interval =
      [|ub(X)*lb(Y),ub(X)*ub(Y)|]

    % med * pos
    mXp(X,Y) : Interval =
      pXm(Y,X)

    % neg * med
    nXm(X,Y) : Interval =
      Neg(pXm(Neg(X),Y))

    % med * neg
    mXn(X,Y) : Interval =
      nXm(Y,X)

    % med * med
    mXm(X,Y) : Interval =
      [|min(lb(X)*ub(Y),ub(X)*lb(Y)),
        max(lb(X)*lb(Y),ub(X)*ub(Y))|]	

    % Multiplication
    Mult(X,Y) : Interval = 
      IF    Ge(X,0) AND Ge(Y,0) THEN pXp(X,Y)
      ELSIF Ge(X,0) AND Le(Y,0) THEN pXn(X,Y)
      ELSIF Ge(X,0)             THEN pXm(X,Y)
      ELSIF Le(X,0) AND Le(Y,0) THEN nXn(X,Y)
      ELSIF Le(X,0) AND Ge(Y,0) THEN nXp(X,Y)
      ELSIF Le(X,0)             THEN nXm(X,Y)
      ELSIF Ge(Y,0)             THEN mXp(X,Y)
      ELSIF Le(Y,0)             THEN mXn(X,Y)
      ELSE                           mXm(X,Y)
      ENDIF
    
    % Square function
    Sq(X) : (NonNeg?) =
      IF    Ge(X,0) THEN [|sq(lb(X)),sq(ub(X))|]
      ELSIF Le(X,0) THEN [|sq(ub(X)),sq(lb(X))|]
      ELSE               [|0,max(sq(lb(X)),sq(ub(X)))|]
      ENDIF
   
    % Power by a natural number
    Pow(X,n) : Interval =
      IF    n = 0 THEN [|1|]
      ELSIF Ge(X,0) OR odd?(n) THEN [|lb(X)^n,ub(X)^n|]
      ELSIF Le(X,0) THEN [|ub(X)^n,lb(X)^n|]
      ELSE  [|0,max(lb(X)^n,ub(X)^n)|]
      ENDIF

    % Division
    Div(X,Y) : Interval =
      IF ub(Y) /= 0 AND lb(Y) /= 0 then Mult(X,[|1/ub(Y),1/lb(Y)|])
      ELSE EmptyInterval
      ENDIF

    % Union
    Union(X,Y) : Interval =
      [|min(lb(X),lb(Y)),max(ub(X),ub(Y))|]

    Intersection(X,Y): Interval =
      [|max(lb(X),lb(Y)),min(ub(X),ub(Y))|]

    Intersection_inclusion: LEMMA
      x ## Intersection(X,Y) IFF
      (x ## X AND x ## Y)

    Intersection_left_Empty : LEMMA
      EmptyInterval?(X) IMPLIES
      EmptyInterval?(Intersection(X,Y))

    Intersection_right_Empty : LEMMA
      EmptyInterval?(Y) IMPLIES
      EmptyInterval?(Intersection(X,Y))

  %%---------------
  %% Support Lemmas
  %%---------------

    Add_comm : LEMMA
      Add(X,Y) = Add(Y,X)

    Mult_comm : LEMMA
      Mult(X,Y) = Mult(Y,X)

    Neg_Incl : LEMMA
       X << Y IMPLIES
      Neg(X) << Neg(Y) 

    Zeroless0 : LEMMA
      x ## X AND
      Zeroless?(X) IMPLIES
      x /= 0

    Neg_Ge_0 : LEMMA
      Le(X,0) IMPLIES
      Ge(Neg(X),0)

    Strict_Lt : LEMMA
      x < y  AND
      x ## X AND
      y ## X IMPLIES
      StrictInterval?(X)

    Halves : LEMMA
      2*size(HalfLeft(X))  = size(X) AND
      2*size(HalfRight(X)) = size(X)

    Halves_Incl : LEMMA
      Proper?(X) IMPLIES
      (HalfLeft(X)  << X AND
       HalfRight(X) << X)

    Halves_inclusion : LEMMA
      x ## X IMPLIES
      x ## HalfLeft(X) OR x ## HalfRight(X)

    Incl_trans : LEMMA
      X << Y AND
      Y << Z IMPLIES
      X << Z

    Pow2_Sq : LEMMA 
      Pow(X,2) = Sq(X)

    Mult_Neg_Neg : LEMMA
      Mult(X,Y) = Mult(Neg(X),Neg(Y))

    Mult_Neg_left : LEMMA
      Mult(X,Y) = Neg(Mult(Neg(X),Y))

    Mult_Neg_right : LEMMA
      Mult(X,Y) = Neg(Mult(X,Neg(Y)))

    Sq_Neg_eq : LEMMA
      Sq(X) = Sq(Neg(X))

    Union_id : LEMMA
      Union(X,X) = X

    Union_symm : LEMMA
      Union(X,Y) = Union(Y,X)

    Union_Incl_left : LEMMA
      X << Union(X,Y)

    Union_Incl_right : LEMMA
      X << Union(Y,X)

  %%---------------
  %% Rewrite Lemmas
  %%---------------

    Add_0_r : LEMMA
      Add(X,[|0|]) = X

    Add_0_l : LEMMA
      Add([|0|],X) = X

    Mult_1_r : LEMMA
      Mult(X,[|1|]) = X

    Mult_1_l : LEMMA
      Mult([|1|],X) = X

    Div_1 : LEMMA
      Div(X,[|1|]) = X

    Pow_0 : LEMMA
      Pow(X,0) = [|1|]

    Pow_1 : LEMMA
      Pow(X,1) = X

    lb_interval : LEMMA
      lb([|x,y|]) = x

    lb_r2i : LEMMA
      lb([|x|]) = x

    ub_interval : LEMMA
      ub([|x,y|]) = y

    ub_r2i : LEMMA
      ub([|y|]) = y

    Incl_reflx : LEMMA
      X << X

    Incl_r2i : LEMMA
      ([|x|] << X) = (x ## X)

    Neg_Neg : LEMMA
      Neg(Neg(X)) = X

    AUTO_REWRITE+ Add_0_l,Add_0_r,Mult_1_l,Mult_1_r,Div_1,Pow_0,Pow_1,
  	        lb_interval,lb_r2i,ub_interval,ub_r2i,
  	        Incl_reflx, Incl_r2i,Neg_Neg 

    ub_inclusion : LEMMA
      Proper?(X) IMPLIES
      ub(X) ## X

    lb_inclusion : LEMMA
      Proper?(X) IMPLIES
      lb(X) ## X

    Neg_interval : LEMMA
      Neg([|x,y|]) = [|-y,-x|]

    Pos_Gt_0 : LEMMA
      Pos?(X) IMPLIES
      Gt(X,0)

    NonNeg_Ge_0 : LEMMA
      NonNeg?(X) IMPLIES
      Ge(X,0)

    Pos_Neg_Lt_0 : LEMMA
       Pos?(X) IMPLIES
       Lt(Neg(X),0)

    NonNeg_Neg_Le_0 : LEMMA
      NonNeg?(X) IMPLIES
      Le(Neg(X),0)

    r2i_sharp_eq : LEMMA
      x ## [| y |] IFF x = y

    r2i_Le : LEMMA
      x <= y IMPLIES
      Le([|x|],y)

    r2i_Lt : LEMMA
      x < y IMPLIES
      Lt([|x|],y)

    r2i_Ge : LEMMA
      x >= y IMPLIES
      Ge([|x|],y)

    r2i_Gt : LEMMA
      x > y IMPLIES
      Gt([|x|],y)

    Lt_Le : LEMMA
      Lt(X,x) IMPLIES
      Le(X,x)

    Gt_Ge : LEMMA
      Gt(X,x) IMPLIES
      Ge(X,x)

  %%-----------------
  %% Inclusion Lemmas
  %%-----------------

    inclusion_Gt : LEMMA
      x ## X AND
      Gt(X,y) IMPLIES
      x > y

    inclusion_Ge : LEMMA
      x ## X AND
      Ge(X,y) IMPLIES
      x >= y

    inclusion_Lt : LEMMA
      x ## X AND
      Lt(X,y) IMPLIES
      x < y

    inclusion_Le : LEMMA
      x ## X AND
      Le(X,y) IMPLIES
      x <= y

    r2i_trans : LEMMA
       x ## X   AND
       X << Y IMPLIES
       [|x|] << Y

    add2sub : LEMMA
       y ## Y AND
       x+y ## Z IMPLIES
       x ## Sub(Z,Y)

    sub2add : LEMMA
       y ## Y AND
       x-y ## Z IMPLIES
       x ## Add(Z,Y)

    Member_trans : LEMMA
       x ## X AND
       X << Y IMPLIES
       x ## Y

    r2i_inclusion : LEMMA
      x ## [|x|]

    Add_inclusion : LEMMA
      x ## X AND y ## Y IMPLIES
      x+y ## Add(X,Y)

    Sub_inclusion : LEMMA
      x ## X AND y ## Y IMPLIES
      x-y ## Sub(X,Y)

    Neg_inclusion : LEMMA
      x ## X IMPLIES
      -x ## Neg(X)

    pXp : LEMMA
      Ge(X,0) AND Ge(Y,0) AND 
      x ## X AND y ## Y IMPLIES
      x*y ## pXp(X,Y)

    nXp : LEMMA
      Le(X,0) AND Ge(Y,0) AND 
      x ## X AND y ## Y IMPLIES
      x*y ## nXp(X,Y)

    pXn : LEMMA
      Ge(X,0) AND Le(Y,0) AND 
      x ## X AND y ## Y IMPLIES
      x*y ## pXn(X,Y)

    nXn : LEMMA
      Le(X,0) AND Le(Y,0) AND 
      x ## X AND y ## Y IMPLIES
      x*y ## nXn(X,Y)

    pXm : LEMMA
      Ge(X,0) AND Zeroin?(Y) AND 
      x ## X AND y ## Y IMPLIES
      x*y ## pXm(X,Y)

    mXp : LEMMA
      Zeroin?(X) AND Ge(Y,0) AND
      x ## X AND y ## Y IMPLIES
      x*y ## mXp(X,Y)

    nXm : LEMMA
      Le(X,0) AND Zeroin?(Y) AND
      x ## X AND y ## Y IMPLIES
      x*y ## nXm(X,Y)

    mXn : LEMMA
      Zeroin?(X) AND Le(Y,0) AND
      x ## X AND y ## Y IMPLIES
      x*y ## mXn(X,Y)

    mXm : LEMMA
      Zeroin?(X) AND Zeroin?(Y) AND
      x ## X AND y ## Y IMPLIES
      x*y ## mXm(X,Y)

    Mult_inclusion : LEMMA
      x ## X AND
      y ## Y IMPLIES
      x*y ## Mult(X,Y)

    Abs_inclusion : LEMMA
      x ## X IMPLIES
      abs(x) ## Abs(X)

    abs_sharp_le : LEMMA
      abs(x) <= y IFF x ## [|-y,y|]

    abs_sharp_lt : LEMMA
      abs(x) < y IMPLIES x ## [|-y,y|]

    pow_0_0 : LEMMA
      0^p = 0

    pow_sq : LEMMA
      x^2 = sq(x)

    pow_neg_n_odd : LEMMA
      (-x)^(2*n+1) = -(x^(2*n+1))

    pow_neg_odd : LEMMA
      odd?(n) IMPLIES
      (-x)^n = -(x^n)

    pow_neg_n_even : LEMMA
      (-x)^(2*n) = x^(2*n)

    pow_neg_even : LEMMA
      even?(n) IMPLIES
      (-x)^n = x^n

    pow_pos : LEMMA
      x   >= 0 IMPLIES
      x^n >= 0

    pow_even_n_pos : LEMMA
      x^(2*n) >= 0

    pow_even_pos : LEMMA
      even?(n) IMPLIES
      x^n >= 0

    pow_odd_n_neg : LEMMA
      x         <= 0 IMPLIES
      x^(2*n+1) <= 0

    pow_odd_neg : LEMMA
      odd?(n) AND 
      x <= 0 IMPLIES
      x^n <= 0

    pow_incr_pos : LEMMA
      x >= 0 AND
      x <= y AND
      (x > 0 OR n > 0) IMPLIES
      x^n <= y^n

    pow_incr_odd : LEMMA
       odd?(n) AND
       x <= y     IMPLIES
       x^n <= y^n

    pow_decr_even : LEMMA
       even?(n) AND
       x <= 0      AND
       x >= y      AND
      (x < 0 OR n > 0) IMPLIES
       x^n <= y^n

    Pow_Neg_even : LEMMA
      even?(n) AND
      Proper?(X) IMPLIES
      Pow(X,n) = Pow(Neg(X),n)

    Pow_inclusion : LEMMA
      x ## X IMPLIES
      x^n ## Pow(X,n)

    Sq_inclusion : LEMMA
      x ## X IMPLIES
      sq(x) ## Sq(X)

    Div_inclusion : LEMMA
      x ## X AND
      y ## Y AND
      Zeroless?(Y) IMPLIES
      x/y ## Div(X,Y)

    Union_inclusion : LEMMA
      x ## Y OR x ## Z IMPLIES x ## Union(Y,Z)

    Overlap?(X,Y) : bool =
      lb(X) ## Y OR
      lb(Y) ## X 

    Reunion : LEMMA
      x ## Z AND 
      Z << Union(X,Y) AND
      Overlap?(X,Y)
      IMPLIES
        x ## X OR x ## Y

    Sigma(n,i,F) : RECURSIVE Interval = 
      IF n > i THEN [|0|]
      ELSE  Add(F(i),Sigma(n,i-1, F))
      ENDIF
      MEASURE (abs(i+1-n))

    Sigma_inclusion : LEMMA
      (FORALL (k:subrange(n,i)):f(k) ## F(k)) IMPLIES
      sigma(n,i,f) ## Sigma(n,i,F)

  %%-----------------
  %% Fundamental Lemmas
  %%-----------------

    X1,Y1 : VAR Interval

    Add_fundamental : LEMMA
      X1 << X AND Y1 << Y IMPLIES
      Add(X1,Y1) << Add(X,Y)

    Sub_fundamental : LEMMA
      X1 << X AND Y1 << Y IMPLIES
      Sub(X1,Y1) << Sub(X,Y)

    Abs_fundamental : LEMMA
      Proper?(X) AND
      X << Y IMPLIES
      Abs(X) << Abs(Y)

    Neg_fundamental : LEMMA
      X << Y IMPLIES
      Neg(X) << Neg(Y)

    pXp_fundamental : LEMMA
      Proper?(X1) AND Proper?(Y1) AND
      Ge(X,0) AND Ge(Y,0) AND
      X1 << X AND Y1 << Y IMPLIES
      Mult(X1,Y1) << Mult(X,Y)

    pXpm_fundamental : LEMMA
      Proper?(X1) AND Proper?(Y1) AND
      Ge(X,0) AND Zeroin?(Y) AND 
      X1 << X AND Y1 << Y AND Ge(Y1,0) IMPLIES
      Mult(X1,Y1) << Mult(X,Y)

    pXmm_fundamental : LEMMA
      Proper?(X1) AND Proper?(Y1) AND
      Ge(X,0) AND Zeroin?(Y) AND 
      X1 << X AND Y1 << Y AND Zeroin?(Y1) IMPLIES
      Mult(X1,Y1) << Mult(X,Y)

    pX_fundamental : LEMMA
      Proper?(X1) AND Proper?(Y1) AND
      Ge(X,0) AND 
      X1 << X AND Y1 << Y IMPLIES
      Mult(X1,Y1) << Mult(X,Y)

    nX_fundamental : LEMMA
      Proper?(X1) AND Proper?(Y1) AND
      Le(X,0) AND 
      X1 << X AND Y1 << Y IMPLIES
      Mult(X1,Y1) << Mult(X,Y)

    pmXpm_fundamental : LEMMA
      Proper?(X1) AND Proper?(Y1) AND
      Zeroin?(X) AND Zeroin?(Y) AND 
      X1 << X AND Y1 << Y AND Ge(X1,0) AND Ge(Y1,0) IMPLIES
      Mult(X1,Y1) << Mult(X,Y)

    pmXmm_fundamental : LEMMA
      Proper?(X1) AND Proper?(Y1) AND
      Zeroin?(X) AND Zeroin?(Y) AND 
      X1 << X AND Y1 << Y AND Ge(X1,0) AND Zeroin?(Y1) IMPLIES
      Mult(X1,Y1) << Mult(X,Y)

    mmXmm_fundamental : LEMMA
      Proper?(X1) AND Proper?(Y1) AND
      Zeroin?(X) AND Zeroin?(Y) AND 
      X1 << X AND Y1 << Y AND Zeroin?(X1) AND Zeroin?(Y1) IMPLIES
      Mult(X1,Y1) << Mult(X,Y)

    mX_fundamental : LEMMA
      Proper?(X1) AND Proper?(Y1) AND
      Zeroin?(X) AND X1 << X AND Y1 << Y IMPLIES
      Mult(X1,Y1) << Mult(X,Y)

    Mult_fundamental : LEMMA
      Proper?(X1) AND Proper?(Y1) AND
      X1 << X AND Y1 << Y IMPLIES
      Mult(X1,Y1) << Mult(X,Y)

    Sq_p_fundamental : LEMMA
      Proper?(X1) AND
      X1 << X AND Ge(X,0) IMPLIES
      Sq(X1) << Sq(X)

    Sq_pm_fundamental : LEMMA
      Proper?(X1) AND
      X1 << X AND Zeroin?(X) AND Ge(X1,0) IMPLIES
      Sq(X1) << Sq(X)

    Sq_fundamental : LEMMA
      Proper?(X1) AND
      X1 << X IMPLIES
      Sq(X1) << Sq(X)

    Div_fundamental : LEMMA
      Proper?(X1) AND Proper?(Y1) AND
      X1 << X AND Y1 << Y AND Zeroless?(Y) IMPLIES
      Div(X1,Y1) << Div(X,Y)

    Pow_p_fundamental : LEMMA
      Proper?(X1) AND 
      X1 << X AND n > 0 AND (odd?(n) OR Ge(X,0)) IMPLIES
      Pow(X1,n) << Pow(X,n)

    Pow_pm_fundamental : LEMMA
      Proper?(X1) AND 
      X1 << X AND n > 0 AND even?(n) AND Zeroin?(X) AND Ge(X1,0) IMPLIES
      Pow(X1,n) << Pow(X,n)

    Pow_m_fundamental : LEMMA
      Proper?(X1) AND 
      X1 << X AND n > 0 AND even?(n) AND Zeroin?(X) IMPLIES
      Pow(X1,n) << Pow(X,n)

    Pow_fundamental : LEMMA
      Proper?(X1) AND 
      X1 << X IMPLIES
      Pow(X1,n) << Pow(X,n)

    Union_fundamental : LEMMA
      X1 << X AND
      Y1 << Y IMPLIES
      Union(X1,Y1) << Union(X,Y)

    Includes?(x)(X:Interval) : bool = x ## X

    Inclusion?(Pre:PRED[Interval],f:[real->real])(F:[Interval->Interval]):bool =
      FORALL(x:real,X:(Pre)): x ## X IMPLIES f(x) ## F(X) 

    Fundamental?(Pre:PRED[Interval])(F:[Interval->Interval]):bool =
      FORALL(X1:ProperInterval,X:(Pre)): X1 << X IMPLIES F(X1) << F(X) 

    Precondition?(Pre:PRED[Interval]):bool =
      FORALL (X1:ProperInterval,X:Interval): X1 << X AND Pre(X) IMPLIES Pre(X1)

    Mult_Strict_r2i : LEMMA
        StrictInterval?(X) AND
        x /= 0 IMPLIES
        StrictInterval?(Mult([|x|],X))

    Mult_r2i_Strict : LEMMA
        StrictInterval?(X) AND
        x /= 0 IMPLIES
        StrictInterval?(Mult([|x|],X))

  %%----------
  %% Judgments 
  %%----------

    Pos_Zeroless   : JUDGEMENT (Pos?) SUBTYPE_OF (Zeroless?)

    Neg_Zeroless   : JUDGEMENT (Neg?) SUBTYPE_OF (Zeroless?)

    Pos_NonNeg     : JUDGEMENT (Pos?) SUBTYPE_OF (NonNeg?)

    Pos_Add_NonNeg : JUDGEMENT Add(X:(Pos?),Y:(NonNeg?)) HAS_TYPE (Pos?)

    NonNeg_Add_Pos : JUDGEMENT Add(X:(NonNeg?),Y:(Pos?)) HAS_TYPE (Pos?)

    Neg_Add        : JUDGEMENT Add(X,Y:(Neg?)) HAS_TYPE (Neg?)

    NonNeg_Add     : JUDGEMENT Add(X,Y:(NonNeg?)) HAS_TYPE (NonNeg?)

    Neg_Pos        : JUDGEMENT Neg(X:(Neg?)) HAS_TYPE (Pos?)

    Pos_Neg        : JUDGEMENT Neg(X:(Pos?)) HAS_TYPE (Neg?)

    Pos_Mult       : JUDGEMENT Mult(X,Y:(Pos?)) HAS_TYPE (Pos?)

    Neg_Mult       : JUDGEMENT Mult(X,Y:(Neg?)) HAS_TYPE (Pos?)

    NonNeg_Mult    : JUDGEMENT Mult(X,Y:(NonNeg?)) HAS_TYPE (NonNeg?)

    Pos_Div        : JUDGEMENT Div(X,Y:(Pos?)) HAS_TYPE (Pos?)

    Neg_Div        : JUDGEMENT Div(X,Y:(Neg?)) HAS_TYPE (Pos?)

    NonNeg_Div     : JUDGEMENT Div(X:(NonNeg?),Y:(Pos?)) HAS_TYPE (NonNeg?)

    r2i_Pos        : JUDGEMENT [||](x:posreal) HAS_TYPE (Pos?)

    r2i_Neg        : JUDGEMENT [||](x:negreal) HAS_TYPE (Neg?)

    r2i_Nneg       : JUDGEMENT [||](x:nnreal) HAS_TYPE (NonNeg?)

    Sq_Pos         : JUDGEMENT Sq(X:(Pos?)) HAS_TYPE (Pos?)
   
    Sq_Neg         : JUDGEMENT Sq(X:(Neg?)) HAS_TYPE (Pos?)

    Abs_Pos        : JUDGEMENT Abs(X:(Pos?)) HAS_TYPE (Pos?)

    Abs_Neg        : JUDGEMENT Abs(X:(Neg?)) HAS_TYPE (Pos?)

    Proper_midpoint: JUDGEMENT midpoint(X:ProperInterval) HAS_TYPE IntervalType(X)

    Includes_Proper : JUDGEMENT (Includes?(x)) SUBTYPE_OF ProperInterval

    Strict_Proper  : JUDGEMENT StrictInterval SUBTYPE_OF ProperInterval 

    Strict_Add     : JUDGEMENT Add(X:StrictInterval,Y:ProperInterval)
                                HAS_TYPE StrictInterval

    Add_Strict     : JUDGEMENT Add(X:ProperInterval,Y:StrictInterval)
                                HAS_TYPE StrictInterval

    Proper_Add     : JUDGEMENT Add(X,Y:ProperInterval) HAS_TYPE ProperInterval

    Strict_Sub     : JUDGEMENT Sub(X:StrictInterval,Y:ProperInterval)
                                HAS_TYPE StrictInterval

    Sub_Strict     : JUDGEMENT Sub(X:ProperInterval,Y:StrictInterval)
                                HAS_TYPE StrictInterval

    Proper_Sub     : JUDGEMENT Sub(X,Y:ProperInterval) HAS_TYPE ProperInterval

    Strict_Neg     : JUDGEMENT Neg(X:StrictInterval)
                                HAS_TYPE StrictInterval

    Proper_Neg     : JUDGEMENT Neg(X:ProperInterval) HAS_TYPE ProperInterval

    Strict_Abs     : JUDGEMENT Abs(X:StrictInterval) 
                               HAS_TYPE StrictInterval

    Proper_Abs     : JUDGEMENT Abs(X:ProperInterval) HAS_TYPE ProperInterval

    Proper_Mult    : JUDGEMENT Mult(X,Y:ProperInterval) HAS_TYPE ProperInterval

    Proper_Div     : JUDGEMENT Div(X:ProperInterval,(Y:ProperInterval|Zeroless?(Y))) HAS_TYPE ProperInterval

    Strict_Sq      : JUDGEMENT Sq(X:StrictInterval) 
                               HAS_TYPE StrictInterval

    Proper_Pow     : JUDGEMENT Pow(X:ProperInterval,n:nat) HAS_TYPE ProperInterval

    Proper_Sq      : JUDGEMENT Sq(X:ProperInterval) HAS_TYPE ProperInterval

    Proper_size    : JUDGEMENT size(X:ProperInterval) HAS_TYPE nnreal

    Strict_size    : JUDGEMENT size(X:StrictInterval) HAS_TYPE posreal


    Proper_HalfLeft : JUDGEMENT HalfLeft(X:ProperInterval) HAS_TYPE ProperInterval 

    Strict_HalfLeft : JUDGEMENT HalfLeft(X:StrictInterval) HAS_TYPE 
  	                      StrictInterval 

    Proper_HalfRight : JUDGEMENT HalfRight(X:ProperInterval) HAS_TYPE ProperInterval 

    Strict_HalfRightt : JUDGEMENT HalfRight(X:StrictInterval) HAS_TYPE 
  	                        StrictInterval 

    Zeroless_Precondition : JUDGEMENT Zeroless? HAS_TYPE (Precondition?)

    NonNeg_Precondition : JUDGEMENT NonNeg? HAS_TYPE (Precondition?)

    Pos_Precondition : JUDGEMENT Pos? HAS_TYPE (Precondition?)

    Neg_Precondition : JUDGEMENT Neg? HAS_TYPE (Precondition?)

  END interval

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

  % Judgement subtype TCC generated (at line 77, column 4) for  [||](x)
      % expected type  ProperInterval
  r2i_Proper: OBLIGATION FORALL (x): Proper?([||](x));

  % Subtype TCC generated (at line 197, column 5) for
      % [|0, max(abs(lb(X)), abs(ub(X)))|]
      % expected type  (NonNeg?)
  Abs_TCC1: OBLIGATION
    FORALL (X: Interval):
      Zeroin?(X) IMPLIES NonNeg?([|0, max(abs(lb(X)), abs(ub(X)))|]);

  % Subtype TCC generated (at line 199, column 5) for
      % [|min(abs(lb(X)), abs(ub(X))), max(abs(lb(X)), abs(ub(X)))|]
      % expected type  (NonNeg?)
  Abs_TCC2: OBLIGATION
    FORALL (X: Interval):
      NOT Zeroin?(X) IMPLIES
       NonNeg?([|min(abs(lb(X)), abs(ub(X))), max(abs(lb(X)), abs(ub(X)))|]);

  % Subtype TCC generated (at line 254, column 23) for
      % [|sq(lb(X)), sq(ub(X))|]
      % expected type  (NonNeg?)
  Sq_TCC1: OBLIGATION
    FORALL (X: Interval): Ge(X, 0) IMPLIES NonNeg?([|sq(lb(X)), sq(ub(X))|]);

  % Subtype TCC generated (at line 255, column 23) for
      % [|sq(ub(X)), sq(lb(X))|]
      % expected type  (NonNeg?)
  Sq_TCC2: OBLIGATION
    FORALL (X: Interval):
      Le(X, 0) AND NOT Ge(X, 0) IMPLIES NonNeg?([|sq(ub(X)), sq(lb(X))|]);

  % Subtype TCC generated (at line 256, column 23) for
      % [|0, max(sq(lb(X)), sq(ub(X)))|]
      % expected type  (NonNeg?)
  Sq_TCC3: OBLIGATION
    FORALL (X: Interval):
      NOT Le(X, 0) AND NOT Ge(X, 0) IMPLIES
       NonNeg?([|0, max(sq(lb(X)), sq(ub(X)))|]);

  % Subtype TCC generated (at line 262, column 42) for  n
      % expected type  {i: int | lb(X) /= 0 OR i >= 0}
  Pow_TCC1: OBLIGATION
    FORALL (X: Interval, n: nat):
      (Ge(X, 0) OR odd?(n)) AND NOT n = 0 IMPLIES lb(X) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 262, column 50) for  n
      % expected type  {i: int | ub(X) /= 0 OR i >= 0}
  Pow_TCC2: OBLIGATION
    FORALL (X: Interval, n: nat):
      (Ge(X, 0) OR odd?(n)) AND NOT n = 0 IMPLIES ub(X) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 263, column 31) for  n
      % expected type  {i: int | ub(X) /= 0 OR i >= 0}
  Pow_TCC3: OBLIGATION
    FORALL (X: Interval, n: nat):
      Le(X, 0) AND NOT Ge(X, 0) AND NOT odd?(n) AND NOT n = 0 IMPLIES
       ub(X) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 263, column 39) for  n
      % expected type  {i: int | lb(X) /= 0 OR i >= 0}
  Pow_TCC4: OBLIGATION
    FORALL (X: Interval, n: nat):
      Le(X, 0) AND NOT Ge(X, 0) AND NOT odd?(n) AND NOT n = 0 IMPLIES
       lb(X) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 264, column 24) for  n
      % expected type  {i: int | lb(X) /= 0 OR i >= 0}
  Pow_TCC5: OBLIGATION
    FORALL (X: Interval, n: nat):
      NOT Le(X, 0) AND NOT Ge(X, 0) AND NOT odd?(n) AND NOT n = 0 IMPLIES
       lb(X) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 264, column 32) for  n
      % expected type  {i: int | ub(X) /= 0 OR i >= 0}
  Pow_TCC6: OBLIGATION
    FORALL (X: Interval, n: nat):
      NOT Le(X, 0) AND NOT Ge(X, 0) AND NOT odd?(n) AND NOT n = 0 IMPLIES
       ub(X) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 593, column 6) for  2
      % expected type  {i: int | x /= 0 OR i >= 0}
  pow_sq_TCC1: OBLIGATION FORALL (x: real): x /= 0 OR 2 >= 0;

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

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

  % Subtype TCC generated (at line 600, column 9) for  n
      % expected type  {i: int | (-x) /= 0 OR i >= 0}
  pow_neg_odd_TCC1: OBLIGATION
    FORALL (n: nat, x: real): odd?(n) IMPLIES (-x) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 600, column 17) for  n
      % expected type  {i: int | x /= 0 OR i >= 0}
  pow_neg_odd_TCC2: OBLIGATION
    FORALL (n: nat, x: real): odd?(n) IMPLIES x /= 0 OR n >= 0;

  % Subtype TCC generated (at line 603, column 10) for  (2 * n)
      % expected type  {i: int | (-x) /= 0 OR i >= 0}
  pow_neg_n_even_TCC1: OBLIGATION
    FORALL (n: nat, x: real): (-x) /= 0 OR (2 * n) >= 0;

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

  % Subtype TCC generated (at line 607, column 9) for  n
      % expected type  {i: int | (-x) /= 0 OR i >= 0}
  pow_neg_even_TCC1: OBLIGATION
    FORALL (n: nat, x: real): even?(n) IMPLIES (-x) /= 0 OR n >= 0;

  % Subtype TCC generated (at line 607, column 15) for  n
      % expected type  {i: int | x /= 0 OR i >= 0}
  pow_neg_even_TCC2: OBLIGATION
    FORALL (n: nat, x: real): even?(n) IMPLIES x /= 0 OR n >= 0;

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

  % Subtype TCC generated (at line 633, column 13) for  n
      % expected type  {i: int | y /= 0 OR i >= 0}
  pow_incr_pos_TCC1: OBLIGATION
    FORALL (n: nat, x, y: real):
      (x > 0 OR n > 0) AND x <= y AND x >= 0 IMPLIES y /= 0 OR n >= 0;

  % Subtype TCC generated (at line 638, column 14) for  n
      % expected type  {i: int | y /= 0 OR i >= 0}
  pow_incr_odd_TCC1: OBLIGATION
    FORALL (n: nat, x, y: real): x <= y AND odd?(n) IMPLIES y /= 0 OR n >= 0;

  % Subtype TCC generated (at line 645, column 14) for  n
      % expected type  {i: int | y /= 0 OR i >= 0}
  pow_decr_even_TCC1: OBLIGATION
    FORALL (n: nat, x, y: real):
      (x < 0 OR n > 0) AND x >= y AND x <= 0 AND even?(n) IMPLIES
       y /= 0 OR n >= 0;

  % Subtype TCC generated (at line 654, column 6) for  n
      % expected type  {i: int | x /= 0 OR i >= 0}
  Pow_inclusion_TCC1: OBLIGATION
    FORALL (X: Interval, n: nat, x: real): x ## X IMPLIES x /= 0 OR n >= 0;

  % Subtype TCC generated (at line 664, column 6) for  y
      % expected type  nznum
  Div_inclusion_TCC1: OBLIGATION
    FORALL (X, Y: Interval, x, y: real):
      Zeroless?(Y) AND y ## Y AND x ## X IMPLIES y /= 0;

  % Subtype TCC generated (at line 682, column 16) for  i
      % expected type  nat
  Sigma_TCC1: OBLIGATION FORALL (n: nat, i: int): NOT n > i IMPLIES i >= 0;

  % Termination TCC generated (at line 682, column 19) for  Sigma(n, i - 1, F)
  Sigma_TCC2: OBLIGATION
    FORALL (n: nat, i: int):
      NOT n > i IMPLIES (abs(i - 1 + 1 - n)) < (abs(i + 1 - n));

  % Subtype TCC generated (at line 687, column 32) for  k
      % expected type  nat
  Sigma_inclusion_TCC1: OBLIGATION
    FORALL (i: int, n: nat, k: subrange(n, i)): k >= 0;

  % Subtype TCC generated (at line 688, column 12) for  i
      % expected type  T_high[nat]
  Sigma_inclusion_TCC2: OBLIGATION
    FORALL (F: [nat -> Interval], f: [nat -> real], i: int, n: nat):
      (FORALL (k: subrange(n, i)): f(k) ## F(k)) IMPLIES
       i >= 0 OR (EXISTS (j: nat): i <= j);

  % Judgement subtype TCC generated (at line 841, column 29) for  x
      % expected type  (Zeroless?)
  Pos_Zeroless: OBLIGATION FORALL (x: (Pos?)): Zeroless?(x);

  % Judgement subtype TCC generated (at line 843, column 29) for  x
      % expected type  (Zeroless?)
  Neg_Zeroless: OBLIGATION FORALL (x: (Neg?)): Zeroless?(x);

  % Judgement subtype TCC generated (at line 845, column 29) for  x
      % expected type  (NonNeg?)
  Pos_NonNeg: OBLIGATION FORALL (x: (Pos?)): NonNeg?(x);

  % Judgement subtype TCC generated (at line 847, column 29) for  Add(X, Y)
      % expected type  (Pos?)
  Pos_Add_NonNeg: OBLIGATION
    FORALL (X: (Pos?), Y: (NonNeg?)): Pos?(Add(X, Y));

  % Judgement subtype TCC generated (at line 849, column 29) for  Add(X, Y)
      % expected type  (Pos?)
  NonNeg_Add_Pos: OBLIGATION
    FORALL (X: (NonNeg?), Y: (Pos?)): Pos?(Add(X, Y));

  % Judgement subtype TCC generated (at line 851, column 29) for  Add(X, Y)
      % expected type  (Neg?)
  Neg_Add: OBLIGATION FORALL (X, Y: (Neg?)): Neg?(Add(X, Y));

  % Judgement subtype TCC generated (at line 853, column 29) for  Add(X, Y)
      % expected type  (NonNeg?)
  NonNeg_Add: OBLIGATION FORALL (X, Y: (NonNeg?)): NonNeg?(Add(X, Y));

  % Judgement subtype TCC generated (at line 855, column 29) for  Neg(X)
      % expected type  (Pos?)
  Neg_Pos: OBLIGATION FORALL (X: (Neg?)): Pos?(Neg(X));

  % Judgement subtype TCC generated (at line 857, column 29) for  Neg(X)
      % expected type  (Neg?)
  Pos_Neg: OBLIGATION FORALL (X: (Pos?)): Neg?(Neg(X));

  % Judgement subtype TCC generated (at line 859, column 29) for  Mult(X, Y)
      % expected type  (Pos?)
  Pos_Mult: OBLIGATION FORALL (X, Y: (Pos?)): Pos?(Mult(X, Y));

  % Judgement subtype TCC generated (at line 861, column 29) for  Mult(X, Y)
      % expected type  (Pos?)
  Neg_Mult: OBLIGATION FORALL (X, Y: (Neg?)): Pos?(Mult(X, Y));

  % Judgement subtype TCC generated (at line 863, column 29) for  Mult(X, Y)
      % expected type  (NonNeg?)
  NonNeg_Mult: OBLIGATION FORALL (X, Y: (NonNeg?)): NonNeg?(Mult(X, Y));

  % Judgement subtype TCC generated (at line 865, column 29) for  Div(X, Y)
      % expected type  (Pos?)
  Pos_Div: OBLIGATION FORALL (X, Y: (Pos?)): Pos?(Div(X, Y));

  % Judgement subtype TCC generated (at line 867, column 29) for  Div(X, Y)
      % expected type  (Pos?)
  Neg_Div: OBLIGATION FORALL (X, Y: (Neg?)): Pos?(Div(X, Y));

  % Judgement subtype TCC generated (at line 869, column 29) for  Div(X, Y)
      % expected type  (NonNeg?)
  NonNeg_Div: OBLIGATION FORALL (X: (NonNeg?), Y: (Pos?)): NonNeg?(Div(X, Y));

  % Judgement subtype TCC generated (at line 871, column 29) for  [||](x)
      % expected type  (Pos?)
  r2i_Pos: OBLIGATION FORALL (x: posreal): Pos?([||](x));

  % Judgement subtype TCC generated (at line 873, column 29) for  [||](x)
      % expected type  (Neg?)
  r2i_Neg: OBLIGATION FORALL (x: negreal): Neg?([||](x));

  % Judgement subtype TCC generated (at line 875, column 29) for  [||](x)
      % expected type  (NonNeg?)
  r2i_Nneg: OBLIGATION FORALL (x: nnreal): NonNeg?([||](x));

  % Judgement subtype TCC generated (at line 877, column 29) for  Sq(X)
      % expected type  (Pos?)
  Sq_Pos: OBLIGATION FORALL (X: (Pos?)): Pos?(Sq(X));

  % Judgement subtype TCC generated (at line 879, column 29) for  Sq(X)
      % expected type  (Pos?)
  Sq_Neg: OBLIGATION FORALL (X: (Neg?)): Pos?(Sq(X));

  % Judgement subtype TCC generated (at line 881, column 29) for  Abs(X)
      % expected type  (Pos?)
  Abs_Pos: OBLIGATION FORALL (X: (Pos?)): Pos?(Abs(X));

  % Judgement subtype TCC generated (at line 883, column 29) for  Abs(X)
      % expected type  (Pos?)
  Abs_Neg: OBLIGATION FORALL (X: (Neg?)): Pos?(Abs(X));

  % Judgement subtype TCC generated (at line 885, column 29) for  midpoint(X)
      % expected type  IntervalType(X)
  Proper_midpoint: OBLIGATION FORALL (X: ProperInterval): midpoint(X) ## X;

  % Judgement subtype TCC generated (at line 887, column 30) for  x1
      % expected type  ProperInterval
  Includes_Proper: OBLIGATION
    FORALL (x: real, x1: (Includes?(x))): Proper?(x1);

  % Judgement subtype TCC generated (at line 889, column 29) for  x
      % expected type  ProperInterval
  Strict_Proper: OBLIGATION FORALL (x: StrictInterval): Proper?(x);

  % Judgement subtype TCC generated (at line 891, column 29) for  Add(X, Y)
      % expected type  StrictInterval
  Strict_Add: OBLIGATION
    FORALL (X: StrictInterval, Y: ProperInterval): StrictInterval?(Add(X, Y));

  % Judgement subtype TCC generated (at line 894, column 29) for  Add(X, Y)
      % expected type  StrictInterval
  Add_Strict: OBLIGATION
    FORALL (X: ProperInterval, Y: StrictInterval): StrictInterval?(Add(X, Y));

  % Judgement subtype TCC generated (at line 897, column 29) for  Add(X, Y)
      % expected type  ProperInterval
  Proper_Add: OBLIGATION FORALL (X, Y: ProperInterval): Proper?(Add(X, Y));

  % Judgement subtype TCC generated (at line 899, column 29) for  Sub(X, Y)
      % expected type  StrictInterval
  Strict_Sub: OBLIGATION
    FORALL (X: StrictInterval, Y: ProperInterval): StrictInterval?(Sub(X, Y));

  % Judgement subtype TCC generated (at line 902, column 29) for  Sub(X, Y)
      % expected type  StrictInterval
  Sub_Strict: OBLIGATION
    FORALL (X: ProperInterval, Y: StrictInterval): StrictInterval?(Sub(X, Y));

  % Judgement subtype TCC generated (at line 905, column 29) for  Sub(X, Y)
      % expected type  ProperInterval
  Proper_Sub: OBLIGATION FORALL (X, Y: ProperInterval): Proper?(Sub(X, Y));

  % Judgement subtype TCC generated (at line 907, column 29) for  Neg(X)
      % expected type  StrictInterval
  Strict_Neg: OBLIGATION FORALL (X: StrictInterval): StrictInterval?(Neg(X));

  % Judgement subtype TCC generated (at line 910, column 29) for  Neg(X)
      % expected type  ProperInterval
  Proper_Neg: OBLIGATION FORALL (X: ProperInterval): Proper?(Neg(X));

  % Judgement subtype TCC generated (at line 912, column 29) for  Abs(X)
      % expected type  StrictInterval
  Strict_Abs: OBLIGATION FORALL (X: StrictInterval): StrictInterval?(Abs(X));

  % Judgement subtype TCC generated (at line 915, column 29) for  Abs(X)
      % expected type  ProperInterval
  Proper_Abs: OBLIGATION FORALL (X: ProperInterval): Proper?(Abs(X));

  % Judgement subtype TCC generated (at line 917, column 29) for  Mult(X, Y)
      % expected type  ProperInterval
  Proper_Mult: OBLIGATION FORALL (X, Y: ProperInterval): Proper?(Mult(X, Y));

  % Judgement subtype TCC generated (at line 919, column 29) for  Div(X, Y)
      % expected type  ProperInterval
  Proper_Div: OBLIGATION
    FORALL (X: ProperInterval, (Y: ProperInterval | Zeroless?(Y))):
      Proper?(Div(X, Y));

  % Judgement subtype TCC generated (at line 921, column 29) for  Sq(X)
      % expected type  StrictInterval
  Strict_Sq: OBLIGATION FORALL (X: StrictInterval): StrictInterval?(Sq(X));

  % Judgement subtype TCC generated (at line 924, column 29) for  Pow(X, n)
      % expected type  ProperInterval
  Proper_Pow: OBLIGATION
    FORALL (X: ProperInterval, n: nat): Proper?(Pow(X, n));

  % Judgement subtype TCC generated (at line 926, column 29) for  Sq(X)
      % expected type  ProperInterval
  Proper_Sq: OBLIGATION FORALL (X: ProperInterval): Proper?(Sq(X));

  % Judgement subtype TCC generated (at line 928, column 29) for  size(X)
      % expected type  nnreal
  Proper_size: OBLIGATION FORALL (X: ProperInterval): size(X) >= 0;

  % Judgement subtype TCC generated (at line 930, column 29) for  size(X)
      % expected type  posreal
  Strict_size: OBLIGATION FORALL (X: StrictInterval): size(X) > 0;

  % Judgement subtype TCC generated (at line 933, column 30) for  HalfLeft(X)
      % expected type  ProperInterval
  Proper_HalfLeft: OBLIGATION
    FORALL (X: ProperInterval): Proper?(HalfLeft(X));

  % Judgement subtype TCC generated (at line 935, column 30) for  HalfLeft(X)
      % expected type  StrictInterval
  Strict_HalfLeft: OBLIGATION
    FORALL (X: StrictInterval): StrictInterval?(HalfLeft(X));

  % Judgement subtype TCC generated (at line 938, column 31) for  HalfRight(X)
      % expected type  ProperInterval
  Proper_HalfRight: OBLIGATION
    FORALL (X: ProperInterval): Proper?(HalfRight(X));

  % Judgement subtype TCC generated (at line 940, column 32) for  HalfRight(X)
      % expected type  StrictInterval
  Strict_HalfRightt: OBLIGATION
    FORALL (X: StrictInterval): StrictInterval?(HalfRight(X));

  % Judgement subtype TCC generated (at line 943, column 36) for  Zeroless?
      % expected type  (Precondition?)
  Zeroless_Precondition: OBLIGATION Precondition?(Zeroless?);

  % Judgement subtype TCC generated (at line 945, column 34) for  NonNeg?
      % expected type  (Precondition?)
  NonNeg_Precondition: OBLIGATION Precondition?(NonNeg?);

  % Judgement subtype TCC generated (at line 947, column 31) for  Pos?
      % expected type  (Precondition?)
  Pos_Precondition: OBLIGATION Precondition?(Pos?);

  % Judgement subtype TCC generated (at line 949, column 31) for  Neg?
      % expected type  (Precondition?)
  Neg_Precondition: OBLIGATION Precondition?(Neg?);


body:
  %% allen_interval.pvs
  allen_interval : THEORY
  BEGIN
    IMPORTING interval
    
    s, t: VAR StrictInterval

    ;<(t, s): bool = t`ub < s`lb
    ;>(t, s): bool = s < t

    ;=(t, s): bool = t`lb = s`lb AND t`ub = s`ub

    overlaps(t, s): bool = t`lb < s`lb AND
                           t`ub > s`lb AND
                           t`ub < s`ub

    ;o(t, s): bool = overlaps(t, s)

    oi(t, s): bool = o(s, t)

    meets(t, s): bool = t`ub = s`lb;
    m(t, s): bool = meets(t, s)
    mi(t, s): bool = m(s, t)

    during(t, s): bool = ((t`lb > s`lb) AND (t`ub < s`ub))
    d(t, s): bool = during(t, s)
    di(t, s): bool = d(s, t)

    starts(t, s): bool = t`lb = s`lb AND t`ub < s`ub
    s(t, s): bool = starts(t, s)
    si(t, s): bool = s(s, t)

    finishes(t, s): bool = t`ub = s`ub AND t`lb > s`lb
    f(t, s): bool = finishes(t, s)
    fi(t, s): bool = f(s, t)

    dur(t, s): bool = d(t, s) OR s(t, s) OR f(t, s)
    con(t, s): bool = di(t, s) OR si(t, s) OR fi(t, s)

    AUTO_REWRITE+ <, >, =, overlaps, o, oi, meets, m, mi, during, d, di, 
                  starts, s, si, finishes, f, fi, dur, con

  END allen_interval


body:
  allen_interval_properties : THEORY
  BEGIN
    IMPORTING allen_interval
    
  % The Transitivity Temporal lemmas

    A, B, C: VAR StrictInterval

    before_before: LEMMA <(A, B) AND <(B, C) IMPLIES <(A, C)
    
    before_during: LEMMA A < B AND d(B, C) IMPLIES 
                        A < C OR o(A, C) OR m(A, C) OR d(A, C) OR s(A, C)

    before_contains: LEMMA <(A, B) AND di(B, C) IMPLIES <(A, C)

    before_overlaps: LEMMA <(A, B) AND o(B, C) IMPLIES <(A, C)

    before_overlapped_by: LEMMA <(A, B) AND oi(B, C) IMPLIES 
                                <(A, C) OR o(A, C) OR m(A, C) OR d(A, C) OR s(A, C)

    before_meets: LEMMA <(A, B) AND m(B, C) IMPLIES <(A, C)

    before_met_by: LEMMA <(A, B) AND mi(B, C) IMPLIES 
                         <(A, C) OR o(A, C) OR m(A, C) OR d(A, C) OR s(A, C)

    before_starts :LEMMA <(A, B) AND s(B, C) IMPLIES <(A, C)

    before_started_by :LEMMA <(A, B) AND si(B, C) IMPLIES <(A, C)

    before_finishes :LEMMA <(A, B) AND f(B, C) IMPLIES 
                              <(A, C) OR o(A, C) OR m(A, C) OR d(A, C) OR s(A, C)

    before_finished_by :LEMMA <(A, B) AND fi(B, C) IMPLIES <(A, C)

    after_after:LEMMA >(A, B) AND >(B, C) IMPLIES >(A, C)

    after_during :LEMMA >(A, B) AND d(B, C) IMPLIES 
                     >(A, C) OR oi(A, C) OR mi(A, C) OR d(A, C) OR f(A, C)

    after_contains :LEMMA >(A, B) AND di(B, C) IMPLIES >(A, C)

    after_overlaps :LEMMA >(A, B) AND o(B, C) IMPLIES 
                     >(A, C) OR oi(A, C) OR mi(A, C) OR d(A, C) OR f(A, C)

    after_meets :LEMMA >(A, B) AND m(B, C) IMPLIES 
                     >(A, C) OR oi(A, C) OR mi(A, C) OR d(A, C) OR f(A, C)

    after_met_by :LEMMA >(A, B) AND mi(B, C) IMPLIES >(A, C)

    after_starts :LEMMA >(A, B) AND s(B, C) IMPLIES 
                     >(A, C) OR oi(A, C) OR mi(A, C) OR d(A, C) OR f(A, C)

    after_started_by :LEMMA >(A, B) AND si(B, C) IMPLIES >(A, C)

    after_finishes :LEMMA >(A, B) AND f(B, C) IMPLIES >(A, C)

    after_finished_by :LEMMA >(A, B) AND fi(B, C) IMPLIES >(A, C)

    during_before :LEMMA d(A, B) AND >(B, C) IMPLIES >(A, C)

    during_after :LEMMA d(A, B) AND <(B, C) IMPLIES <(A, C)

    during_during :LEMMA d(A, B) AND d(B, C) IMPLIES d(A, C)

    during_overlaps :LEMMA d(A, B) AND o(B, C) IMPLIES 
                         <(A, C) OR o(A, C) OR m(A, C) OR d(A, C) OR s(A, C)

    during_overlapped_by:LEMMA d(A, B) AND oi(B, C) IMPLIES 
                              >(A, C) OR oi(A, C) OR mi(A, C) OR d(A, C) OR f(A, C)

    during_meets :LEMMA d(A, B) AND m(B, C) IMPLIES <(A, C)

    during_t_meet_bay :LEMMA d(A, B) AND mi(B, C) IMPLIES >(A, C)

    during_starts :LEMMA d(A, B) AND s(B, C) IMPLIES d(A, C)

    during_started_by :LEMMA d(A, B) AND si(B, C) IMPLIES 
                              >(A, C) OR oi(A, C) OR mi(A, C) OR d(A, C) OR f(A, C)

    during_finished_by: LEMMA d(A, B) AND fi(B, C) IMPLIES 
                           <(A, C) OR o(A, C) OR m(A, C) OR d(A, C) OR s(A, C)

    during_finishes:LEMMA d(A, B) AND f(B, C) IMPLIES  d(A, C)

    contains_before:LEMMA di(A, B) AND <(B, C) IMPLIES 
                        <(A, C) OR o(A, C) OR m(A, C) OR di(A, C) OR fi(A, C)

    contains_after :LEMMA di(A, B) AND >(B, C) IMPLIES 
                          >(A, C) OR oi(A, C) OR mi(A, C) OR di(A, C) OR si(A, C)

    contains_during: LEMMA di(A, B) AND d(B, C) IMPLIES
                           o(A, C) OR oi(A, C) OR dur(A, C) OR con(A, C) OR A = C

    contains_contains :LEMMA di(A, B) AND di(B, C) IMPLIES di(A, C)

    contains_overlaps :LEMMA di(A, B) AND o(B, C) IMPLIES 
                          o(A, C) OR di(A, C) OR fi(A, C)

    contains_overlapped_by :LEMMA di(A, B) AND oi(B, C) IMPLIES 
                               oi(A, C) OR di(A, C) OR si(A, C)

    contains_meets :LEMMA di(A, B) AND m(B, C) IMPLIES 
                        o(A, C) OR di(A, C) OR fi(A, C)

    contains_meet_by :LEMMA di(A, B) AND mi(B, C) IMPLIES 
                        oi(A, C) OR di(A, C) OR si(A, C)

    contains_starts :LEMMA di(A, B) AND s(B, C) IMPLIES 
                        di(A, C) OR fi(A, C) OR o(A, C)

    contains_started_by:LEMMA di(A, B) AND si(B, C) IMPLIES di(A, C) 

    contains_finishes :LEMMA di(A, B) AND f(B, C) IMPLIES 
                          di(A, C) OR si(A, C) OR oi(A, C)

    contains_finished_by :LEMMA di(A, B) AND fi(B, C) IMPLIES di(A, C)

    overlaps_before:LEMMA o(A, B) AND <(B, C) IMPLIES <(A, C)

    overlaps_after :LEMMA o(A, B) AND >(B, C) IMPLIES 
                       >(A, C) OR oi(A, C) OR mi(A, C) OR di(A, C) OR si(A, C)

    overlaps_during:LEMMA o(A, B) AND d(B, C) IMPLIES  o(A, C) OR d(A, C) OR s(A, C)

    overlaps_overlapped_by: LEMMA o(A, B) AND oi(B,C) IMPLIES 
                                o(A,C) OR  oi(A,C) OR dur(A,C) OR con(A,C) OR A = C

    overlaps_contains :LEMMA o(A, B) AND di(B, C) IMPLIES 
                          <(A, C) OR o(A, C) OR m(A, C) OR di(A, C) OR fi(A, C)

    overlaps_overlaps: LEMMA o(A, B) AND o(B, C) IMPLIES 
                          <(A, C) OR o(A, C) OR m(A, C)

    overlaps_meets: LEMMA o(A, B) AND m(B, C) IMPLIES  <(A, C) 
   
    overlaps_met_by: LEMMA o(A, B) AND mi(B, C) IMPLIES oi(A, C) OR di(A, C) OR si(A, C)

    overlaps_starts: LEMMA o(A, B) AND s(B, C) IMPLIES o(A, C)

    overlaps_start_by: LEMMA o(A, B) AND si(B, C) IMPLIES di(A, C) OR o(A, C) OR fi(A, C)

    overlaps_finishes: LEMMA o(A, B) AND f(B, C) IMPLIES  d(A, C) OR o(A, C) OR s(A, C)

    overlaps_finished_by:LEMMA o(A, B) AND fi(B, C) IMPLIES 
                          <(A, C) OR o(A, C) OR m(A, C)

    overlapped_by_before: LEMMA oi(A, B) AND <(B, C) IMPLIES 
                             <(A, C) OR o(A, C) OR m(A, C) OR di(A, C) OR fi(A, C)

    overlapped_by_after: LEMMA oi(A, B) AND >(B, C) IMPLIES  >(A, C)

    overlapped_by_during: LEMMA oi(A, B) AND d(B, C) IMPLIES  
                             oi(A, C) OR d(A, C) OR f(A, C)

    overlapped_by_contains: LEMMA oi(A, B) AND di(B, C) IMPLIES  
                               >(A, C) OR oi(A, C) OR di(A, C) OR mi(A, C) OR si(A, C) 

    overlapped_by_overlaps: LEMMA o(A, B) AND oi(B,C) IMPLIES 
                                o(A,C) OR  oi(A,C) OR dur(A,C) OR con(A,C) OR A = C

    overlapped_by_overlapped_by: LEMMA oi(A, B) AND oi(B, C) IMPLIES  
                                    >(A, C) OR oi(A, C) OR mi(A, C)

    overlapped_by_meets: LEMMA oi(A, B) AND m(B, C) IMPLIES  
                                    o(A, C) OR fi(A, C) OR di(A, C)
   
    overlapped_by_meet_by: LEMMA oi(A, B) AND mi(B, C) IMPLIES >(A, C)

    overlapped_by_starts: LEMMA oi(A, B) AND s(B, C) IMPLIES 
                             oi(A, C) OR d(A, C) OR f(A, C)

    overlapped_by_started_by: LEMMA oi(A, B) AND si(B, C) IMPLIES 
                                 >(A, C) OR oi(A, C) OR mi(A, C) 

    overlapped_by_finishes: LEMMA oi(A, B) AND f(B, C) IMPLIES oi(A, C)

    overlapped_by_finished_by: LEMMA oi(A, B) AND fi(B, C) IMPLIES 
                                  oi(A, C) OR di(A, C) OR si(A, C)

    meets_before: LEMMA m(A, B) AND <(B, C) IMPLIES <(A, C)
                                  
    meets_after: LEMMA m(A, B) AND >(B, C) IMPLIES 
                    >(A, C) OR oi(A, C) OR mi(A, C) OR di(A, C) OR si(A, C) 

    meets_during: LEMMA m(A, B) AND d(B, C) IMPLIES  
                     o(A, C) OR d(A, C) OR s(A, C)

    meets_contains: LEMMA m(A, B) AND di(B, C) IMPLIES <(A, C)

    meets_overlaps: LEMMA m(A, B) AND o(B, C) IMPLIES <(A, C)

    meets_overlapped_by: LEMMA m(A, B) AND oi(B, C) IMPLIES
                            o(A, C) OR d(A, C) OR s(A, C)

    meets_meets: LEMMA m(A, B) AND m(B, C) IMPLIES A < C 


    meets_meet_by: LEMMA m(A, B) AND mi(B, C) IMPLIES
                      f(A, C) OR fi(A, C) OR A = C 

    meets_starts: LEMMA m(A, B) AND s(B, C) IMPLIES m(A, C)

    meets_started_by: LEMMA m(A, B) AND si(B, C) IMPLIES m(A, C)

    meets_finishes: LEMMA m(A, B) AND f(B, C) IMPLIES 
                       d(A, C) OR s(A, C) OR o(A, C)

    meets_finished_by: LEMMA m(A, B) AND fi(B, C) IMPLIES <(A, C)

    meet_by_before: LEMMA mi(A, B) AND <(B, C) IMPLIES 
                       <(A, C) OR o(A, C) OR m(A, C) OR di(A, C)OR fi(A, C) 

    meet_by_after: LEMMA mi(A, B) AND >(B, C) IMPLIES >(A, C)

    meet_by_during: LEMMA mi(A, B) AND d(B, C) IMPLIES 
                       oi(A, C)OR d(A, C) OR f(A, C)

    meet_by_contains: LEMMA mi(A, B) AND di(B, C) IMPLIES >(A, C) 

    meet_by_overlaps: LEMMA mi(A, B) AND o(B, C) IMPLIES 
                         oi(A, C)OR d(A, C)OR f(A, C)

    meet_by_meet: LEMMA mi(A, B) AND m(B, C) IMPLIES 
                              si(A, C)OR s(A, C)OR A = C

    meet_by_overlapped_by: LEMMA mi(A, B) AND oi(B, C) IMPLIES >(A, C) 

    meet_by_meet_by: LEMMA mi(A, B) AND mi(B, C) IMPLIES >(A, C)

    meet_by_starts: LEMMA mi(A, B) AND s(B, C) IMPLIES 
                       d(A, C) OR f(A, C) OR oi(A, C)

    meet_by_started_by: LEMMA mi(A, B) AND si(B, C) IMPLIES A > C

    meet_by_finishes: LEMMA mi(A, B) AND f(B, C) IMPLIES mi(A, C)

    met_by_finished: LEMMA mi(A, B) AND fi(B, C) IMPLIES mi(A, C)

    starts_by_before: LEMMA s(A, B) AND <(B, C) IMPLIES <(A, C)

    starts_by_after: LEMMA s(A, B) AND >(B, C) IMPLIES >(A, C)

    starts_by_during: LEMMA s(A, B) AND d(B, C) IMPLIES d(A, C)

    starts_by_contains: LEMMA s(A, B) AND di(B, C) IMPLIES 
                           <(A, C) OR o(A, C) OR m(A, C) OR di(A, C) 
                           OR fi(A, C)                            

    starts_by_overlaps: LEMMA s(A, B) AND o(B, C) IMPLIES 
                           <(A, C) OR o(A, C) OR m(A, C)

    starts_by_overlapped_by: LEMMA s(A, B) AND oi(B, C) IMPLIES 
                                oi(A, C) OR d(A, C) OR f(A, C)

    starts_by_meet: LEMMA s(A, B) AND m(B, C) IMPLIES A < C

    starts_by_meet_by: LEMMA s(A, B) AND mi(B, C) IMPLIES mi(B, C)

    starts_by_starts: LEMMA s(A, B) AND s(B, C) IMPLIES s(B, C)

    starts_by_started_by: LEMMA s(A, B) AND si(B, C) IMPLIES 
                             s(B, C) OR si(B, C) OR A = C

    starts_by_finishes: LEMMA s(A, B) AND f(B, C) IMPLIES d(A, C)

    starts_by_finished_by :LEMMA s(A, B) AND fi(B, C) IMPLIES 
                              o(A, C) OR m(A, C) OR <(A, C)

    started_by_before: LEMMA si(A, B) AND <(B, C) IMPLIES 
                          o(A, C) OR m(A, C) OR <(A, C) OR di(A, C) OR fi(A, C)

    started_by_after: LEMMA si(A, B) AND >(B, C) IMPLIES >(A, C)

    started_by_during: LEMMA si(A, B) AND d(B, C) IMPLIES 
                          oi(A, C) OR d(A, C) OR f(A, C)

    started_by_contains: LEMMA si(A, B) AND di(B, C) IMPLIES di(A, C) 

    started_by_overlaps: LEMMA si(A, B) AND o(B, C) IMPLIES 
                            di(A, C) OR fi(A, C) OR o(A, C)

    started_by_overlapped_by: LEMMA si(A, B) AND oi(B, C) IMPLIES oi(A, C) 

    started_by_meet: LEMMA si(A, B) AND m(B, C) IMPLIES 
                        di(A, C) OR fi(A, C) OR o(A, C)

    started_by_meet_by: LEMMA si(A, B) AND mi(B, C) IMPLIES mi(A, C)

    started_by_starts: LEMMA si(A, B) AND s(B, C) IMPLIES 
                            si(A, C) OR s(A, C) OR A = C

    started_by_started_by: LEMMA si(A, B) AND si(B, C) IMPLIES si(A, C)

    started_by_finishes: LEMMA si(A, B) AND f(B, C) IMPLIES oi(A, C)

    started_by_finished_by: LEMMA si(A, B) AND fi(B, C) IMPLIES di(A, C)

    finishes_before: LEMMA f(A, B) AND <(B, C) IMPLIES <(A, C)

    finishes_after: LEMMA f(A, B) AND >(B, C) IMPLIES >(A, C)

    finishes_during :LEMMA f(A, B) AND d(B, C) IMPLIES d(A, C)

    finishes_contains: LEMMA f(A, B) AND di(B, C) IMPLIES 
                          >(A, C) OR oi(A, C) OR mi(A, C) OR di(A, C) OR si(A, C) 

    finishes_overlaps:  LEMMA f(A, B) AND o(B, C) IMPLIES
                          o(A, C) OR d(A, C) OR s(A, C)
  			
    finishes_overlapped_by: LEMMA f(A, B) AND oi(B, C) IMPLIES
                                >(A, C) OR mi(A, C) OR oi(A, C) 

    finishes_meets: LEMMA f(A, B) AND m(B, C) IMPLIES m(A, C)

    finishes_meet_by: LEMMA f(A, B) AND mi(B, C) IMPLIES >(A, C)

    finishes_starts: LEMMA f(A, B) AND s(B, C) IMPLIES d(A, C)

    finishes_started_by: LEMMA f(A, B) AND si(B, C) IMPLIES 
                            >(A, C) OR mi(A, C) OR oi(A, C)

    finishes_finishes: LEMMA f(A, B) AND f(B, C) IMPLIES f(A, C)

    finishes_finished_by: LEMMA f(A, B) AND fi(B, C) IMPLIES 
                             f(A, C) OR fi(A, C) OR A = C

    finished_by_before: LEMMA fi(A, B) AND <(B, C) IMPLIES A < C

    finished_by_after: LEMMA fi(A, B) AND >(B, C) IMPLIES
                           >(A, C) OR mi(A, C) OR oi(A, C) OR di(A, C) OR si(A, C)  

    finished_by_during: LEMMA fi(A, B) AND d(B, C) IMPLIES
                           o(A, C) OR d(A, C) OR s(A, C)

    finished_by_contains: LEMMA fi(A, B) AND di(B, C) IMPLIES di(A, C)

    finished_by_overlaps: LEMMA fi(A, B) AND o(B, C) IMPLIES o(A, C)

    finished_by_overlapped_by: LEMMA fi(A, B) AND oi(B, C) IMPLIES 
                                  oi(A, C) OR di(A, C) OR si(A, C)

    finished_by_meets: LEMMA fi(A, B) AND m(B, C) IMPLIES m(A, C)

    finished_by_meet_by: LEMMA fi(A, B) AND mi(B, C) IMPLIES
                            oi(A, C) OR di(A, C) OR si(A, C)

    finished_by_starts: LEMMA fi(A, B) AND s(B, C) IMPLIES o(A, C)

    finished_by_started_by :LEMMA fi(A, B) AND si(B, C) IMPLIES di(A, C) 

    finished_by_finishes:LEMMA fi(A, B) AND f(B, C) IMPLIES 
                             f(A, C) OR fi(A, C) OR A = C
   
    finished_by_finished_by: LEMMA fi(A, B) AND fi(B, C) IMPLIES fi(B, C)

  END allen_interval_properties


body:
  %% Allen interval temporal logic as defined in the paper 
  %% "Maintaining Knowledge about Temporal Intervals" by
  %% James F. Allen (CACM, Vol. 26, No. 11, Nov. 1983).
  %% 
  %% Contributed by Dragan Stosic

  top_allen : THEORY
  BEGIN

    IMPORTING allen_interval,
              allen_interval_properties

  END top_allen


body:
  proper_arith : THEORY
  BEGIN

  %
  % The comparison and arithmetic operators defined in this theory require operands to be non-empty 
  % (and in the case of division a non-zero divisor). The PVS's type-checker will generate TCCs that enforces
  % these properties. 
  %
  % The theory symbols_as_proper defines the symbols +,-,*,/,^ using the functions in this theory
  %

    IMPORTING interval

    x,y : VAR real
    X,Y : VAR ProperInterval
    n   : VAR nat

    NzInterval     : TYPE = { X | Zeroless?(X) }
    PosInterval    : TYPE = { X | Pos?(X) }
    NegInterval    : TYPE = { X | Neg?(X) }
    NonNegInterval : TYPE = { X | NonNeg?(X) }

    proper_Lt(X,x) : bool =
      Lt(X,x)

    proper_Le(X,x) : bool =
      Le(X,x)

    proper_Gt(X,x) : bool =
      Gt(X,x)

    proper_Ge(X,x) : bool =
      Ge(X,x)

    proper_Add(X,Y) : ProperInterval =
      Add(X,Y)    

    proper_Sub(X,Y) : ProperInterval =
      Sub(X,Y)

    proper_Neg(X) : ProperInterval =
      Neg(X)

    proper_Mult(X,Y) : ProperInterval = 
      Mult(X,Y)

    YNz : VAR NzInterval
    ynz : VAR nzreal

    proper_Div(X,YNz) : ProperInterval =
      Div(X,YNz)

    proper_Pow(X,n) : ProperInterval = 
      Pow(X,n)

    proper_Abs(X) : ProperInterval =
      Abs(X)

    proper_Sq(X) : ProperInterval =
      Sq(X)

  END proper_arith


body:
  safe_arith : THEORY
  BEGIN

  % 
  % The comparison interval operators defined in this theory return false when the interval 
  % operand is empty. The arithmetic interval operators defined in this theory return an empty 
  % interval when one of the operands is empty (or in the case of division a non-zero divisor).
  %
  % The theory symbols_as_safe defines the symbols <,<=,>,>=,+,-,*,/,^ using the functions in this theory
  %

    IMPORTING interval

    X,Y : VAR Interval
    x,y : VAR real
    n   : VAR nat

    safe_Lt(X,x) : bool =
      Proper?(X) AND Lt(X,x)

    safe_Le(X,x) : bool =
      Proper?(X) AND Le(X,x)

    safe_Gt(X,x) : bool =
      Proper?(X) AND Gt(X,x)

    safe_Ge(X,x) : bool =
      Proper?(X) AND Ge(X,x)

    op1 : VAR [Interval->Interval]
    pre : VAR PRED[Interval]
    op2 : VAR [Interval,Interval->Interval]    

    Safe1(op1)(X) : Interval =
      IF Proper?(X) THEN op1(X)
      ELSE EmptyInterval
      ENDIF

    Proper_Safe1 : LEMMA
      Proper?(Safe1(op1)(X)) IMPLIES
        Proper?(X) AND 
        Safe1(op1)(X) = op1(X)

    Safe1(pre,op1)(X) : Interval =
      IF pre(X) THEN Safe1(op1)(X)
      ELSE EmptyInterval
      ENDIF

    Proper_Safe1_pre : LEMMA
      Proper?(Safe1(pre,op1)(X)) IMPLIES
        pre(X) AND Proper?(X) AND
        Safe1(pre,op1)(X) = op1(X)

    Safe2(op2)(X,Y): Interval =
      IF Proper?(X) AND Proper?(Y) THEN op2(X,Y)
      ELSE EmptyInterval
      ENDIF

    Proper_Safe2 : LEMMA
      Proper?(Safe2(op2)(X,Y)) IMPLIES
        Proper?(X) AND Proper?(Y) AND 
        Safe2(op2)(X,Y) = op2(X,Y)

    safe_Add :  [Interval,Interval->Interval] = Safe2(Add)

    safe_Sub :  [Interval,Interval->Interval] = Safe2(Sub)

    safe_Neg :  [Interval->Interval] = Safe1(Neg)

    safe_Abs:  [Interval->Interval] = Safe1(Abs)

    safe_Mult:  [Interval,Interval->Interval] = Safe2(Mult)

    safe_Sq: [Interval->Interval] = Safe1(Sq)

    safe_Pow(X,n) : Interval =
      IF Proper?(X) THEN Pow(X,n)
      ELSE EmptyInterval
      ENDIF

    safe_Div(X,Y) : Interval =
      IF Zeroless?(Y) THEN Safe2(Div)(X,Y)
      ELSE EmptyInterval
      ENDIF

  END safe_arith


body:
  %% interval_lnexp.pvs

  interval_lnexp : THEORY
  BEGIN
    IMPORTING lnexp_fnd@exp_approx,
              lnexp_fnd@ln_approx,
              interval

    X,Y : VAR Interval
    x   : VAR real
    n   : VAR nat

    Exp(n)(X) : (Pos?) =
     [|exp_lb(lb(X),n),exp_ub(ub(X),n)|]

    Exp_fundamental: LEMMA
     X << Y IMPLIES
     Exp(n)(X) << Exp(n)(Y)

    Ln(n)(X) : Interval = 
      if lb(X) > 0 AND ub(X) > 0 then
        [|ln_lb(lb(X),n),ln_ub(ub(X),n)|]
      else 
        EmptyInterval
      endif 

    % lemmas

    Ln_fundamental: LEMMA
      Pos?(Y) AND Proper?(X) AND
      X << Y IMPLIES
      Ln(n)(X) << Ln(n)(Y)

    Exp_inclusion : LEMMA
      x ## X IMPLIES
      exp(x) ## Exp(n)(X)

    % En
    En(n) : (Pos?) = Exp(n)([|1|])

    Ln_inclusion : LEMMA
      Pos?(X) AND
      x ## X IMPLIES
      ln(x) ## Ln(n)(X)

    %% Safe version of ln and exp
    IMPORTING safe_arith

    safe_Ln(n) : [Interval->Interval] = Safe1(Ln(n))
    safe_Exp(n) : [Interval->Interval] = Safe1(Exp(n))

    %% Proper version of ln and exp
    IMPORTING proper_arith

    Xp   : VAR ProperInterval
    XP   : VAR PosInterval

    Proper_Ln : JUDGEMENT
      Ln(n)(XP) HAS_TYPE ProperInterval

    Proper_Exp : JUDGEMENT
      Exp(n)(Xp) HAS_TYPE ProperInterval

    proper_Ln(n)(XP) : ProperInterval = Ln(n)(XP)

    proper_Exp(n)(Xp) : PosInterval = Exp(n)(Xp)

  END interval_lnexp

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

  % Subtype TCC generated (at line 14, column 3) for
      % [|exp_lb(lb(X), n), exp_ub(ub(X), n)|]
      % expected type  (Pos?)
  Exp_TCC1: OBLIGATION
    FORALL (n: nat, X: Interval):
      Pos?([|exp_lb(lb(X), n), exp_ub(ub(X), n)|]);

  % Subtype TCC generated (at line 22, column 14) for  lb(X)
      % expected type  posreal
  Ln_TCC1: OBLIGATION
    FORALL (X: Interval): lb(X) > 0 AND ub(X) > 0 IMPLIES lb(X) >= 0;

  % Subtype TCC generated (at line 22, column 29) for  ub(X)
      % expected type  posreal
  Ln_TCC2: OBLIGATION
    FORALL (X: Interval): lb(X) > 0 AND ub(X) > 0 IMPLIES ub(X) >= 0;

  % Subtype TCC generated (at line 44, column 7) for  x
      % expected type  posreal
  Ln_inclusion_TCC1: OBLIGATION
    FORALL (X: Interval, x: real):
      x ## X AND Pos?(X) IMPLIES x >= 0 AND x > 0;

  % Judgement subtype TCC generated (at line 59, column 4) for  Ln(n)(XP)
      % expected type  ProperInterval
  Proper_Ln: OBLIGATION FORALL (XP, n): Proper?(Ln(n)(XP));

  % Judgement subtype TCC generated (at line 62, column 4) for  Exp(n)(Xp)
      % expected type  ProperInterval
  Proper_Exp: OBLIGATION FORALL (Xp, n): Proper?(Exp(n)(Xp));

  % Subtype TCC generated (at line 66, column 36) for  Exp(n)(Xp)
      % expected type  PosInterval
  proper_Exp_TCC1: OBLIGATION
    FORALL (n: nat, Xp: ProperInterval): Pos?(Exp(n)(Xp));


body:
  box : THEORY
  BEGIN

    IMPORTING interval, structures@listn

    Box : TYPE = list[Interval]
    Env : TYPE = ARRAY[nat->real]
    box : VAR Box
    vs  : VAR Env

    ProperBox?(box:Box) : bool =
      every(Proper?)(box)

    ProperBox : TYPE = (ProperBox?)
    pox : VAR ProperBox

    proper_box : LEMMA
      FORALL (pox:ProperBox,i:below(length(pox))) : Proper?(nth(pox,i))

    proper_append : LEMMA
      FORALL (pox1,pox2: ProperBox):
        ProperBox?(append(pox1,pox2))

    vars_in_box?(box)(vs) : bool =
      FORALL(i:below(length(box))):vs(i) ## nth(box,i)

    vars_in_box_rec(box:Box,n:nat,(i:nat | i+length(box) = n))(vs) : RECURSIVE 
      { b : bool | b = (FORALL (k:subrange(i,n-1)): vs(k) ## nth(box,k-i)) } =
      null?(box) OR (vs(i) ## car(box) AND vars_in_box_rec(cdr(box),n,i+1)(vs))
    MEASURE box BY <<

    vars_in_box : LEMMA
      FORALL (box:Box):
        vars_in_box?(box) = vars_in_box_rec(box,length(box),0)

    midvars(pox) : (vars_in_box?(pox)) =
      LAMBDA(v:nat) : IF v < length(pox) THEN midpoint(nth(pox,v)) ELSE 0 ENDIF

    Lbbox(box:Box): listn[Interval](length(box)) =
      map(LAMBDA (X:Interval): [|lb(X)|])(box)   

    length_Lbbox : LEMMA
      length(Lbbox(pox))=length(pox)

    Ubbox(box:Box): listn[Interval](length(box)) =
      map(LAMBDA (X:Interval): [|ub(X)|])(box)   

    length_Ubbox : LEMMA
      length(Ubbox(pox))=length(pox)

    Midbox(box:Box): listn[Interval](length(box)) =
      map(LAMBDA (X:Interval): [|midpoint(X)|])(box)   

    length_Midbox : LEMMA
      length(Midbox(pox))=length(pox)

    box1,box2 : VAR Box

    Inclusion?(box1,box2) : bool =
      length(box1) = length(box2) AND
      FORALL(i:below(length(box1))) : nth(box1,i) << nth(box2,i)

    Inclusion_reflx : LEMMA
      FORALL(box:Box): Inclusion?(box,box)

    Inclusion_trans : LEMMA
      FORALL(box1,box2,box:Box): 
        Inclusion?(box1,box2) AND Inclusion?(box2,box) IMPLIES
        Inclusion?(box1,box)

    Inclusion_Proper : LEMMA
      Inclusion?(pox,box) IMPLIES
      ProperBox?(box)

    Lbbox_Proper : JUDGEMENT Lbbox(pox) HAS_TYPE ProperBox

    Ubbox_Proper : JUDGEMENT Ubbox(pox) HAS_TYPE ProperBox

    Midbox_Proper : JUDGEMENT Midbox(pox) HAS_TYPE ProperBox

    Lbbox_Inclusion : LEMMA
      Inclusion?(Lbbox(pox),pox) 

    Ubbox_Inclusion : LEMMA
      Inclusion?(Ubbox(pox),pox) 

    Midbox_Inclusion : LEMMA
      Inclusion?(Midbox(pox),pox) 

    vars_in_box_Inclusion : LEMMA
      Inclusion?(box1,box2) AND
      vars_in_box?(box1)(vs) IMPLIES
      vars_in_box?(box2)(vs)

  END box

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

  % Subtype TCC generated (at line 28, column 53) for  k
      % expected type  nat
  vars_in_box_rec_TCC1: OBLIGATION
    FORALL (box: Box, n: nat, (i: nat | i + length(box) = n),
            k: subrange(i, n - 1)):
      k >= 0;

  % Subtype TCC generated (at line 28, column 67) for  k - i
      % expected type  below[length[Interval](box)]
  vars_in_box_rec_TCC2: OBLIGATION
    FORALL (box: Box, n: nat, (i: nat | i + length(box) = n),
            k: subrange(i, n - 1)):
      k - i >= 0 AND k - i < length[Interval](box);

  % Subtype TCC generated (at line 29, column 32) for  box
      % expected type  (cons?[Interval])
  vars_in_box_rec_TCC3: OBLIGATION
    FORALL (box: Box, n: nat, (i: nat | i + length[Interval](box) = n)):
      NOT null?(box) IMPLIES cons?[Interval](box);

  % Subtype TCC generated (at line 29, column 68) for  i + 1
      % expected type  {i: nat | i + length(cdr(box)) = n}
  vars_in_box_rec_TCC4: OBLIGATION
    FORALL (box: Box, n: nat, (i: nat | i + length[Interval](box) = n),
            vs: Env):
      vs(i) ## car(box) AND NOT null?(box) IMPLIES
       i + 1 + length[Interval](cdr[Interval](box)) = n;

  % Termination TCC generated (at line 29, column 41) for
      % vars_in_box_rec(cdr(box), n, i + 1)
  vars_in_box_rec_TCC5: OBLIGATION
    FORALL (box: Box, n: nat, (i: nat | i + length[Interval](box) = n),
            vs: Env):
      vs(i) ## car(box) AND NOT null?(box) IMPLIES
       <<[Interval](cdr[Interval](box), box);

  % Subtype TCC generated (at line 29, column 4) for
      % null?(box) OR
      %  (vs(i) ## car(box) AND vars_in_box_rec(cdr(box), n, i + 1)(vs))
      % expected type  {b: bool |
                     %          b =
                     %           (FORALL (k: subrange(i, n - 1)):
                     %              vs(k) ## nth(box, k - i))}
  vars_in_box_rec_TCC6: OBLIGATION
    FORALL (box: Box,
            v:
              [d1:
                 {z: [box: Box, n: nat, {i: nat | i + length(box) = n}] |
                          z`1 << box} ->
                 [vs: Env ->
                    {b: bool |
                             b =
                              (FORALL (k: subrange(d1`3, d1`2 - 1)):
                                 vs(k) ## nth(d1`1, k - d1`3))}]],
            n: nat, (i: nat | i + length[Interval](box) = n), vs: Env):
      (null?[Interval](box) OR
        (vs(i) ## car[Interval](box) AND
          v(cdr[Interval](box), n, i + 1)(vs)))
       = (FORALL (k: subrange(i, n - 1)): vs(k) ## nth[Interval](box, k - i));

  % Subtype TCC generated (at line 37, column 4) for
      % LAMBDA (v: nat):
      %   IF v < length(pox) THEN midpoint(nth(pox, v)) ELSE 0 ENDIF
      % expected type  (vars_in_box?(pox))
  midvars_TCC1: OBLIGATION
    FORALL (pox: ProperBox):
      vars_in_box?(pox)
                  (LAMBDA (v: nat):
                     IF v < length[Interval](pox)
                       THEN midpoint(nth[Interval](pox, v))
                     ELSE 0
                     ENDIF);

  % Subtype TCC generated (at line 40, column 4) for
      % map(LAMBDA (X: Interval): [|lb(X)|])(box)
      % expected type  listn[Interval](length(box))
  Lbbox_TCC1: OBLIGATION
    FORALL (box: Box):
      length[Interval]
          (map[Interval, Interval](LAMBDA (X: Interval): [|lb(X)|])(box))
       = length[Interval](box);

  % Subtype TCC generated (at line 46, column 4) for
      % map(LAMBDA (X: Interval): [|ub(X)|])(box)
      % expected type  listn[Interval](length(box))
  Ubbox_TCC1: OBLIGATION
    FORALL (box: Box):
      length[Interval]
          (map[Interval, Interval](LAMBDA (X: Interval): [|ub(X)|])(box))
       = length[Interval](box);

  % Subtype TCC generated (at line 52, column 4) for
      % map(LAMBDA (X: Interval): [|midpoint(X)|])(box)
      % expected type  listn[Interval](length(box))
  Midbox_TCC1: OBLIGATION
    FORALL (box: Box):
      length[Interval]
          (map[Interval, Interval]
               (LAMBDA (X: Interval): [|midpoint(X)|])(box))
       = length[Interval](box);

  % Subtype TCC generated (at line 61, column 60) for  i
      % expected type  below[length[Interval](box2)]
  Inclusion?_TCC1: OBLIGATION
    FORALL (box1: Box, box2: Box):
      length(box1) = length(box2) IMPLIES
       (FORALL (i: below(length[Interval](box1))):
          i < length[Interval](box2));

  % Judgement subtype TCC generated (at line 75, column 27) for  Lbbox(pox)
      % expected type  ProperBox
  Lbbox_Proper: OBLIGATION FORALL (pox): ProperBox?(Lbbox(pox));

  % Judgement subtype TCC generated (at line 77, column 27) for  Ubbox(pox)
      % expected type  ProperBox
  Ubbox_Proper: OBLIGATION FORALL (pox): ProperBox?(Ubbox(pox));

  % Judgement subtype TCC generated (at line 79, column 28) for  Midbox(pox)
      % expected type  ProperBox
  Midbox_Proper: OBLIGATION FORALL (pox): ProperBox?(Midbox(pox));


body:
  IntervalExpr : DATATYPE WITH SUBTYPES RealExpr, BoolExpr
  BEGIN

    IMPORTING interval, 
              structures@Unit,
              reals@real_orders

    % Irrational constants are modeled a functions to force lazy evaluation
    CONST(opc:[Unit->real],opC:(Includes?(opc(unit)))) : const? : RealExpr
    VARIDX(varidx:nat) : varidx?                                : RealExpr
    ADD(op1,op2:RealExpr) : add?                                : RealExpr
    ABS(op:RealExpr) : abs?                                     : RealExpr
    NEG(op:RealExpr) : neg?                                     : RealExpr
    SUB(op1,op2:RealExpr) : sub?                                : RealExpr
    MULT(op1,op2:RealExpr) : mult?                              : RealExpr
    SQ(op:RealExpr) : sq?                                       : RealExpr
    POW(op:RealExpr,opn:nat) : pow?                             : RealExpr
    DIV(op1,op2:RealExpr) : div?                                : RealExpr
    FUN(pre:(Precondition?),opf:[real->real],
        opF:{F:[Interval->Interval]| Inclusion?(pre,opf)(F) 
        AND Fundamental?(pre)(F)}, op:RealExpr) : fun?          : RealExpr
    LETIN(rlet:RealExpr,rin:RealExpr) : letin?                  : RealExpr
    BCONST(opb:bool) : bconst?                                  : BoolExpr
    BNOT(bop:BoolExpr) : bnot?                                  : BoolExpr
    BAND(bop1,bop2:BoolExpr) : band?                            : BoolExpr
    BOR(bop1,bop2:BoolExpr) : bor?                              : BoolExpr
    BIMPLIES(bop1,bop2:BoolExpr) : bimplies?                    : BoolExpr
    BREL(rel:RealOrder,op1,op2:RealExpr) : brel?                : BoolExpr
    BINCLUDES(op:RealExpr,opi:Interval) : bincludes?            : BoolExpr
    BITE(bif,bthen,belse:BoolExpr) : bite?                      : BoolExpr
    BLETIN(blet:IntervalExpr,bin:BoolExpr) : bletin?            : BoolExpr

  END IntervalExpr


body:
  interval_expr : THEORY
  BEGIN

    IMPORTING IntervalExpr,
              box,
  	    structures@more_list_props

    v,n  : VAR nat
    vs   : VAR Env
    box  : VAR Box
    pox,
    qox  : VAR ProperBox

    r2E(r:real) : RealExpr =
      CONST(LAMBDA(u:Unit):r,[| r |])

    I2E(X:ProperInterval) : RealExpr =
      CONST(LAMBDA(u:Unit):midpoint(X),X)

    PreTrue : (Precondition?) = LAMBDA (X:Interval) : true

    CONVERSION r2E
    CONVERSION I2E

    X(v:nat): RealExpr = VARIDX(v)

    realexpr?(expr:IntervalExpr) : bool =
      const?(expr) OR varidx?(expr) OR
      add?(expr) OR abs?(expr) OR
      neg?(expr) OR sub?(expr) OR
      mult?(expr) OR sq?(expr) OR
      pow?(expr) OR div?(expr) OR
      fun?(expr) OR letin?(expr)

    boolexpr?(expr:IntervalExpr) : bool =
      bconst?(expr) OR bnot?(expr) OR
      band?(expr) OR bor?(expr) OR
      bimplies?(expr) OR brel?(expr) OR
      bincludes?(expr) OR bite?(expr) OR
      bletin?(expr)

     real_bool_expr : LEMMA
       FORALL (expr:IntervalExpr):
         realexpr?(expr) OR boolexpr?(expr) 

    expr : VAR RealExpr

    eval(expr,vs,n) : RECURSIVE real =
      IF const?(expr) THEN opc(expr)(unit)
      ELSIF varidx?(expr) THEN 
         vs(varidx(expr))
      ELSIF add?(expr) THEN
        eval(op1(expr),vs,n)+eval(op2(expr),vs,n)
      ELSIF abs?(expr) THEN
        abs(eval(op(expr),vs,n))
      ELSIF neg?(expr) THEN
        -eval(op(expr),vs,n)
      ELSIF sub?(expr) THEN
        eval(op1(expr),vs,n)-eval(op2(expr),vs,n)
      ELSIF mult?(expr) THEN
        eval(op1(expr),vs,n)*eval(op2(expr),vs,n)
      ELSIF sq?(expr) THEN
        sq(eval(op(expr),vs,n))
      ELSIF pow?(expr) THEN
        eval(op(expr),vs,n)^opn(expr)
      ELSIF div?(expr) THEN
        LET d = eval(op2(expr),vs,n) IN
        IF d = 0 THEN 0 
        ELSE 
          eval(op1(expr),vs,n)/eval(op2(expr),vs,n)
        ENDIF
      ELSIF fun?(expr) THEN 
        opf(expr)(eval(op(expr),vs,n))
      ELSE
        LET rlet = eval(rlet(expr),vs,n) IN
          eval(rin(expr),vs WITH [`n := rlet],n+1)
      ENDIF
    MEASURE expr BY <<

    Eval(expr,box) : RECURSIVE Interval =
      IF const?(expr) THEN opC(expr)
      ELSIF varidx?(expr) THEN 
        IF varidx(expr) >= length(box) THEN EmptyInterval
        ELSE nth(box,varidx(expr))
        ENDIF
      ELSIF add?(expr) THEN
        LET op1 = Eval(op1(expr),box) IN
        IF Proper?(op1) THEN
          LET op2 = Eval(op2(expr),box) IN
          IF Proper?(op2) THEN Add(op1,op2) ELSE EmptyInterval ENDIF
        ELSE EmptyInterval
        ENDIF
      ELSIF abs?(expr) THEN
        LET op = Eval(op(expr),box) IN
        IF Proper?(op) THEN Abs(op) ELSE EmptyInterval ENDIF
      ELSIF neg?(expr) THEN
        Neg(Eval(op(expr),box))
      ELSIF sub?(expr) THEN
        LET op1 = Eval(op1(expr),box) IN
        IF Proper?(op1) THEN
          LET op2 = Eval(op2(expr),box) IN
          IF Proper?(op2) THEN Sub(op1,op2) ELSE EmptyInterval ENDIF
        ELSE EmptyInterval
        ENDIF
      ELSIF mult?(expr) THEN
        LET op1 = Eval(op1(expr),box) IN
        IF Proper?(op1) THEN
          LET op2 = Eval(op2(expr),box) IN
          IF Proper?(op2) THEN Mult(op1,op2) ELSE EmptyInterval ENDIF
        ELSE EmptyInterval
        ENDIF
      ELSIF sq?(expr) THEN
        LET op = Eval(op(expr),box) IN
        IF Proper?(op) THEN Sq(op) ELSE EmptyInterval ENDIF
      ELSIF pow?(expr) THEN
        LET op = Eval(op(expr),box) IN
        IF Proper?(op) THEN Pow(op,opn(expr)) ELSE EmptyInterval ENDIF
      ELSIF div?(expr) THEN
        LET op1 = Eval(op1(expr),box) IN
        IF Proper?(op1) THEN
          LET op2 = Eval(op2(expr),box) IN
          IF Proper?(op2) AND Zeroless?(op2) THEN Div(op1,op2) 
          ELSE EmptyInterval ENDIF
        ELSE EmptyInterval
        ENDIF
      ELSIF fun?(expr) THEN
        LET op = Eval(op(expr),box) IN
        IF Proper?(op) AND pre(expr)(op) THEN opF(expr)(op) ELSE EmptyInterval ENDIF
      ELSE
        LET rlet = Eval(rlet(expr),box) IN
        IF Proper?(rlet) THEN
          Eval(rin(expr),append(box,(: rlet :)))
        ELSE EmptyInterval
        ENDIF
      ENDIF
    MEASURE expr BY <<

    Eval(expr) : Interval = Eval(expr,null)

    well_typed?(box)(expr) : INDUCTIVE bool =
      const?(expr) OR
      (varidx?(expr) AND varidx(expr) < length(box)) OR
      (add?(expr) AND well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr))) OR
      (abs?(expr) AND well_typed?(box)(op(expr))) OR
      (sub?(expr) AND well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr))) OR
      (neg?(expr) AND well_typed?(box)(op(expr))) OR
      (mult?(expr) AND well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr))) OR
      (sq?(expr) AND well_typed?(box)(op(expr))) OR
      (div?(expr) AND well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)) AND
       Zeroless?(Eval(op2(expr),box))) OR
      (pow?(expr) AND well_typed?(box)(op(expr))) OR
      (fun?(expr) AND well_typed?(box)(op(expr)) AND pre(expr)(Eval(op(expr),box))) OR
      (letin?(expr) AND well_typed?(box)(rlet(expr)) AND 
        well_typed?(append(box,(: Eval(rlet(expr),box) :)))(rin(expr)))

    Proper_well_typed : LEMMA
      Proper?(Eval(expr,box)) IMPLIES
      well_typed?(box)(expr) 

    Eval_inclusion : THEOREM
       FORALL (box:Box,vs:(vars_in_box?(box)),expr) :
          well_typed?(box)(expr) IMPLIES
          eval(expr,vs,length(box)) ## Eval(expr,box)

    Eval_inclusion_Proper : THEOREM
      FORALL (box:Box,vs:(vars_in_box?(box)))(expr) :
        LET E = Eval(expr,box) IN
          Proper?(E) IMPLIES
          eval(expr,vs,length(box)) ## E

    well_typed_Proper : LEMMA
      well_typed?(pox)(expr) IMPLIES
      Proper?(Eval(expr,pox))

    Eval_fundamental_aux : LEMMA
      FORALL (expr):
        Inclusion?(box,pox) IMPLIES 
        well_typed?(pox)(expr) AND Proper?(Eval(expr,box)) IMPLIES 
        Eval(expr,box) << Eval(expr,pox)

    well_typed_Inclusion_aux : LEMMA
      FORALL (expr):
        Inclusion?(pox,box) IMPLIES
        well_typed?(box)(expr) 
        IMPLIES
        well_typed?(pox)(expr)

    well_typed_Inclusion : LEMMA
      Inclusion?(pox,box) IMPLIES
      FORALL (expr):
        well_typed?(box)(expr) 
        IMPLIES
        well_typed?(pox)(expr)

    Proper_Inclusion : LEMMA
      Inclusion?(pox,box) IMPLIES
        FORALL (expr):
          Proper?(Eval(expr,box))
          IMPLIES
          Proper?(Eval(expr,pox))

    Eval_fundamental : THEOREM
      Inclusion?(pox,box) IMPLIES 
      FORALL (expr):
        well_typed?(box)(expr) IMPLIES 
        Eval(expr,pox) << Eval(expr,box)

    Eval_fundamental_proper : THEOREM
      Inclusion?(pox,box) IMPLIES 
      FORALL (expr):
        LET E = Eval(expr,box) IN
        Proper?(E) IMPLIES
        Eval(expr,pox) << E

    split(v,box) : RECURSIVE {lrb:[Box,Box] | LET (lb,rb) = lrb IN 
                              length(lb) = length(box) AND length(rb) = length(box) AND
                              FORALL (i:below(length(box))) : IF i=v THEN nth(lb,i) = HalfLeft(nth(box,i)) AND
                                                                            nth(rb,i) = HalfRight(nth(box,i)) 
                                                                ELSE nth(lb,i) = nth(box,i) AND
                                                                     nth(rb,i) = nth(box,i)
                                                                ENDIF} =
      IF null?(box) THEN (null,null)
      ELSIF v = 0 THEN (cons(HalfLeft(car(box)),cdr(box)),
                        cons(HalfRight(car(box)),cdr(box)))
      ELSE LET (lb,rb) = split(v-1,cdr(box)) IN
               (cons(car(box),lb),cons(car(box),rb))
      ENDIF
    MEASURE box BY <<

    split_eq : RECURSIVE JUDGEMENT 
      split(v,(box:Box|length(box) <= v)) HAS_TYPE {lrb:[Box,Box] | LET (lb,rb)=lrb IN lb = box AND rb=box}

    split_vars_in_box : LEMMA
      FORALL (box:Box,vs:(vars_in_box?(box)),v) :
        LET (bl,br) = split(v,box) IN
          vars_in_box?(bl)(vs) OR vars_in_box?(br)(vs)

    split_Inclusion : LEMMA
      FORALL (pox,v):
        LET (bl,br) = split(v,pox) IN
        Inclusion?(bl,pox) AND Inclusion?(br,pox)

    split_Proper : JUDGEMENT split(v,pox) HAS_TYPE [ProperBox,ProperBox]

    length_split_1 : LEMMA
      length(split(v,pox)`1) = length(pox)

    length_split_2 : LEMMA
      length(split(v,pox)`2) = length(pox)
   
  END interval_expr

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

  well_typed?_weak_induction: AXIOM
    FORALL (P: [Box -> [RealExpr -> boolean]]):
      (FORALL (box, expr):
             const?(expr) OR (varidx?(expr) AND varidx(expr) < length(box))
          OR (add?(expr) AND P(box)(op1(expr)) AND P(box)(op2(expr)))
          OR (abs?(expr) AND P(box)(op(expr)))
          OR (sub?(expr) AND P(box)(op1(expr)) AND P(box)(op2(expr)))
          OR (neg?(expr) AND P(box)(op(expr)))
          OR (mult?(expr) AND P(box)(op1(expr)) AND P(box)(op2(expr)))
          OR (sq?(expr) AND P(box)(op(expr)))
          OR (div?(expr) AND
               P(box)(op1(expr)) AND
                P(box)(op2(expr)) AND Zeroless?(Eval(op2(expr), box)))
          OR (pow?(expr) AND P(box)(op(expr)))
          OR (fun?(expr) AND
               P(box)(op(expr)) AND pre(expr)(Eval(op(expr), box)))
          OR (letin?(expr) AND
               P(box)(rlet(expr)) AND
                P(append(box, (: Eval(rlet(expr), box) :)))(rin(expr)))
          IMPLIES P(box)(expr))
       IMPLIES
       (FORALL (box, expr): well_typed?(box)(expr) IMPLIES P(box)(expr));

  well_typed?_induction: AXIOM
    FORALL (P: [Box -> [RealExpr -> boolean]]):
      (FORALL (box, expr):
             const?(expr) OR (varidx?(expr) AND varidx(expr) < length(box))
          OR (     add?(expr) AND well_typed?(box)(op1(expr))
               AND P(box)(op1(expr)) AND well_typed?(box)(op2(expr))
               AND P(box)(op2(expr)))
          OR (abs?(expr) AND well_typed?(box)(op(expr)) AND P(box)(op(expr)))
          OR (     sub?(expr) AND well_typed?(box)(op1(expr))
               AND P(box)(op1(expr)) AND well_typed?(box)(op2(expr))
               AND P(box)(op2(expr)))
          OR (neg?(expr) AND well_typed?(box)(op(expr)) AND P(box)(op(expr)))
          OR (     mult?(expr) AND well_typed?(box)(op1(expr))
               AND P(box)(op1(expr)) AND well_typed?(box)(op2(expr))
               AND P(box)(op2(expr)))
          OR (sq?(expr) AND well_typed?(box)(op(expr)) AND P(box)(op(expr)))
          OR (     div?(expr) AND well_typed?(box)(op1(expr))
               AND P(box)(op1(expr)) AND well_typed?(box)(op2(expr))
               AND P(box)(op2(expr)) AND Zeroless?(Eval(op2(expr), box)))
          OR (pow?(expr) AND well_typed?(box)(op(expr)) AND P(box)(op(expr)))
          OR (fun?(expr) AND
               (well_typed?(box)(op(expr)) AND P(box)(op(expr))) AND
                pre(expr)(Eval(op(expr), box)))
          OR (     letin?(expr) AND well_typed?(box)(rlet(expr))
               AND P(box)(rlet(expr))
               AND well_typed?(append(box, (: Eval(rlet(expr), box) :)))
                              (rin(expr))
               AND P(append(box, (: Eval(rlet(expr), box) :)))(rin(expr)))
          IMPLIES P(box)(expr))
       IMPLIES
       (FORALL (box, expr): well_typed?(box)(expr) IMPLIES P(box)(expr));

  % Recursive judgement axiom generated for judgement
  % split_eq
  split_eq: AXIOM
    FORALL (v, (box: Box | length(box) <= v)):
      split(v, box)`1 = box AND split(v, box)`2 = box;

  % Subtype TCC generated (at line 15, column 27) for  [|r|]
      % expected type  (Includes?(r))
  r2E_TCC1: OBLIGATION FORALL (r: real): Includes?(r)([|r|]);

  % Subtype TCC generated (at line 18, column 37) for  X
      % expected type  (Includes?(midpoint(X)))
  I2E_TCC1: OBLIGATION FORALL (X: ProperInterval): Includes?(midpoint(X))(X);

  % Subtype TCC generated (at line 20, column 30) for
      % LAMBDA (X: Interval): TRUE
      % expected type  (Precondition?)
  PreTrue_TCC1: OBLIGATION Precondition?(LAMBDA (X: Interval): TRUE);

  % Well-founded TCC generated (at line 78, column 18) for
      % restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
      %     (<<)
      % for eval
  eval_TCC1: OBLIGATION
    well_founded?(LAMBDA (x: RealExpr, y: RealExpr):
                    restrict
                        [[IntervalExpr, IntervalExpr], [RealExpr, RealExpr],
                         boolean]
                        (<<)(x, y));

  % Subtype TCC generated (at line 53, column 15) for  expr
      % expected type  {x: IntervalExpr |
                     %              brel?(x) OR div?(x) OR mult?(x) OR sub?(x)
                     %           OR add?(x)}
  eval_TCC2: OBLIGATION
    FORALL (expr: RealExpr):
      add?(expr) AND NOT varidx?(expr) AND NOT const?(expr) IMPLIES
           brel?(expr) OR div?(expr) OR mult?(expr) OR sub?(expr)
        OR add?(expr);

  % Termination TCC generated (at line 53, column 6) for
      % eval(op1(expr), vs, n)
  eval_TCC3: OBLIGATION
    FORALL (expr: RealExpr):
      add?(expr) AND NOT varidx?(expr) AND NOT const?(expr) IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op1(expr), expr);

  % Termination TCC generated (at line 53, column 27) for
      % eval(op2(expr), vs, n)
  eval_TCC4: OBLIGATION
    FORALL (expr: RealExpr):
      add?(expr) AND NOT varidx?(expr) AND NOT const?(expr) IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op2(expr), expr);

  % Subtype TCC generated (at line 55, column 18) for  expr
      % expected type  {x: IntervalExpr |
                     %              bincludes?(x) OR fun?(x) OR pow?(x)
                     %           OR sq?(x) OR neg?(x) OR abs?(x)}
  eval_TCC5: OBLIGATION
    FORALL (expr: RealExpr):
      abs?(expr) AND
       NOT add?(expr) AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
           bincludes?(expr) OR fun?(expr) OR pow?(expr) OR sq?(expr)
        OR neg?(expr) OR abs?(expr);

  % Termination TCC generated (at line 55, column 10) for
      % eval(op(expr), vs, n)
  eval_TCC6: OBLIGATION
    FORALL (expr: RealExpr):
      abs?(expr) AND
       NOT add?(expr) AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op(expr), expr);

  % Subtype TCC generated (at line 57, column 15) for  expr
      % expected type  {x: IntervalExpr |
                     %              bincludes?(x) OR fun?(x) OR pow?(x)
                     %           OR sq?(x) OR neg?(x) OR abs?(x)}
  eval_TCC7: OBLIGATION
    FORALL (expr: RealExpr):
           neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
           bincludes?(expr) OR fun?(expr) OR pow?(expr) OR sq?(expr)
        OR neg?(expr) OR abs?(expr);

  % Termination TCC generated (at line 57, column 7) for
      % eval(op(expr), vs, n)
  eval_TCC8: OBLIGATION
    FORALL (expr: RealExpr):
           neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op(expr), expr);

  % Subtype TCC generated (at line 59, column 15) for  expr
      % expected type  {x: IntervalExpr |
                     %              brel?(x) OR div?(x) OR mult?(x) OR sub?(x)
                     %           OR add?(x)}
  eval_TCC9: OBLIGATION
    FORALL (expr: RealExpr):
           sub?(expr) AND NOT neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
           brel?(expr) OR div?(expr) OR mult?(expr) OR sub?(expr)
        OR add?(expr);

  % Termination TCC generated (at line 59, column 6) for
      % eval(op1(expr), vs, n)
  eval_TCC10: OBLIGATION
    FORALL (expr: RealExpr):
           sub?(expr) AND NOT neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op1(expr), expr);

  % Termination TCC generated (at line 59, column 27) for
      % eval(op2(expr), vs, n)
  eval_TCC11: OBLIGATION
    FORALL (expr: RealExpr):
           sub?(expr) AND NOT neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op2(expr), expr);

  % Subtype TCC generated (at line 61, column 15) for  expr
      % expected type  {x: IntervalExpr |
                     %              brel?(x) OR div?(x) OR mult?(x) OR sub?(x)
                     %           OR add?(x)}
  eval_TCC12: OBLIGATION
    FORALL (expr: RealExpr):
           mult?(expr) AND NOT sub?(expr) AND NOT neg?(expr)
       AND NOT abs?(expr) AND NOT add?(expr) AND NOT varidx?(expr)
       AND NOT const?(expr)
       IMPLIES
           brel?(expr) OR div?(expr) OR mult?(expr) OR sub?(expr)
        OR add?(expr);

  % Termination TCC generated (at line 61, column 6) for
      % eval(op1(expr), vs, n)
  eval_TCC13: OBLIGATION
    FORALL (expr: RealExpr):
           mult?(expr) AND NOT sub?(expr) AND NOT neg?(expr)
       AND NOT abs?(expr) AND NOT add?(expr) AND NOT varidx?(expr)
       AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op1(expr), expr);

  % Termination TCC generated (at line 61, column 27) for
      % eval(op2(expr), vs, n)
  eval_TCC14: OBLIGATION
    FORALL (expr: RealExpr):
           mult?(expr) AND NOT sub?(expr) AND NOT neg?(expr)
       AND NOT abs?(expr) AND NOT add?(expr) AND NOT varidx?(expr)
       AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op2(expr), expr);

  % Subtype TCC generated (at line 63, column 17) for  expr
      % expected type  {x: IntervalExpr |
                     %              bincludes?(x) OR fun?(x) OR pow?(x)
                     %           OR sq?(x) OR neg?(x) OR abs?(x)}
  eval_TCC15: OBLIGATION
    FORALL (expr: RealExpr):
           sq?(expr) AND NOT mult?(expr) AND NOT sub?(expr) AND NOT neg?(expr)
       AND NOT abs?(expr) AND NOT add?(expr) AND NOT varidx?(expr)
       AND NOT const?(expr)
       IMPLIES
           bincludes?(expr) OR fun?(expr) OR pow?(expr) OR sq?(expr)
        OR neg?(expr) OR abs?(expr);

  % Termination TCC generated (at line 63, column 9) for
      % eval(op(expr), vs, n)
  eval_TCC16: OBLIGATION
    FORALL (expr: RealExpr):
           sq?(expr) AND NOT mult?(expr) AND NOT sub?(expr) AND NOT neg?(expr)
       AND NOT abs?(expr) AND NOT add?(expr) AND NOT varidx?(expr)
       AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op(expr), expr);

  % Subtype TCC generated (at line 65, column 14) for  expr
      % expected type  {x: IntervalExpr |
                     %              bincludes?(x) OR fun?(x) OR pow?(x)
                     %           OR sq?(x) OR neg?(x) OR abs?(x)}
  eval_TCC17: OBLIGATION
    FORALL (expr: RealExpr):
           pow?(expr) AND NOT sq?(expr) AND NOT mult?(expr) AND NOT sub?(expr)
       AND NOT neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
           bincludes?(expr) OR fun?(expr) OR pow?(expr) OR sq?(expr)
        OR neg?(expr) OR abs?(expr);

  % Termination TCC generated (at line 65, column 6) for
      % eval(op(expr), vs, n)
  eval_TCC18: OBLIGATION
    FORALL (expr: RealExpr):
           pow?(expr) AND NOT sq?(expr) AND NOT mult?(expr) AND NOT sub?(expr)
       AND NOT neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op(expr), expr);

  % Subtype TCC generated (at line 65, column 26) for  opn(expr)
      % expected type  {i: int | eval(op(expr), vs, n) /= 0 OR i >= 0}
  eval_TCC19: OBLIGATION
    FORALL (expr: RealExpr,
            v:
              [{z: [RealExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [RealExpr, RealExpr], boolean]
                            (<<)(z`1, expr)} ->
                 real],
            vs: Env, n: nat):
           pow?(expr) AND NOT sq?(expr) AND NOT mult?(expr) AND NOT sub?(expr)
       AND NOT neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES v(op(expr), vs, n) /= 0 OR opn(expr) >= 0;

  % Subtype TCC generated (at line 70, column 17) for  expr
      % expected type  {x: IntervalExpr |
                     %              brel?(x) OR div?(x) OR mult?(x) OR sub?(x)
                     %           OR add?(x)}
  eval_TCC20: OBLIGATION
    FORALL (expr: RealExpr,
            v:
              [{z: [RealExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [RealExpr, RealExpr], boolean]
                            (<<)(z`1, expr)} ->
                 real],
            vs: Env, n: nat):
           div?(expr) AND NOT pow?(expr) AND NOT sq?(expr) AND NOT mult?(expr)
       AND NOT sub?(expr) AND NOT neg?(expr) AND NOT abs?(expr)
       AND NOT add?(expr) AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       (FORALL (d: real):
          NOT d = 0 AND d = v(op2(expr), vs, n) IMPLIES
               brel?(expr) OR div?(expr) OR mult?(expr) OR sub?(expr)
            OR add?(expr));

  % Termination TCC generated (at line 70, column 8) for
      % eval(op1(expr), vs, n)
  eval_TCC21: OBLIGATION
    FORALL (expr: RealExpr,
            v:
              [{z: [RealExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [RealExpr, RealExpr], boolean]
                            (<<)(z`1, expr)} ->
                 real],
            vs: Env, n: nat):
           div?(expr) AND NOT pow?(expr) AND NOT sq?(expr) AND NOT mult?(expr)
       AND NOT sub?(expr) AND NOT neg?(expr) AND NOT abs?(expr)
       AND NOT add?(expr) AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       (FORALL (d: real):
          NOT d = 0 AND d = v(op2(expr), vs, n) IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
               (<<)(op1(expr), expr));

  % Termination TCC generated (at line 70, column 29) for
      % eval(op2(expr), vs, n)
  eval_TCC22: OBLIGATION
    FORALL (expr: RealExpr,
            v:
              [{z: [RealExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [RealExpr, RealExpr], boolean]
                            (<<)(z`1, expr)} ->
                 real],
            vs: Env, n: nat):
           div?(expr) AND NOT pow?(expr) AND NOT sq?(expr) AND NOT mult?(expr)
       AND NOT sub?(expr) AND NOT neg?(expr) AND NOT abs?(expr)
       AND NOT add?(expr) AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       (FORALL (d: real):
          NOT d = 0 AND d = v(op2(expr), vs, n) IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
               (<<)(op2(expr), expr));

  % Subtype TCC generated (at line 70, column 29) for  eval(op2(expr), vs, n)
      % expected type  nznum
  eval_TCC23: OBLIGATION
    FORALL (expr: RealExpr,
            v:
              [{z: [RealExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [RealExpr, RealExpr], boolean]
                            (<<)(z`1, expr)} ->
                 real],
            vs: Env, n: nat):
           div?(expr) AND NOT pow?(expr) AND NOT sq?(expr) AND NOT mult?(expr)
       AND NOT sub?(expr) AND NOT neg?(expr) AND NOT abs?(expr)
       AND NOT add?(expr) AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       (FORALL (d: real):
          NOT d = 0 AND d = v(op2(expr), vs, n) IMPLIES
           v(op2(expr), vs, n) /= 0);

  % Subtype TCC generated (at line 67, column 23) for  expr
      % expected type  {x: IntervalExpr |
                     %              brel?(x) OR div?(x) OR mult?(x) OR sub?(x)
                     %           OR add?(x)}
  eval_TCC24: OBLIGATION
    FORALL (expr: RealExpr):
           div?(expr) AND NOT pow?(expr) AND NOT sq?(expr) AND NOT mult?(expr)
       AND NOT sub?(expr) AND NOT neg?(expr) AND NOT abs?(expr)
       AND NOT add?(expr) AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
           brel?(expr) OR div?(expr) OR mult?(expr) OR sub?(expr)
        OR add?(expr);

  % Termination TCC generated (at line 67, column 14) for
      % eval(op2(expr), vs, n)
  eval_TCC25: OBLIGATION
    FORALL (expr: RealExpr):
           div?(expr) AND NOT pow?(expr) AND NOT sq?(expr) AND NOT mult?(expr)
       AND NOT sub?(expr) AND NOT neg?(expr) AND NOT abs?(expr)
       AND NOT add?(expr) AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op2(expr), expr);

  % Subtype TCC generated (at line 73, column 24) for  expr
      % expected type  {x: IntervalExpr |
                     %              bincludes?(x) OR fun?(x) OR pow?(x)
                     %           OR sq?(x) OR neg?(x) OR abs?(x)}
  eval_TCC26: OBLIGATION
    FORALL (expr: RealExpr):
           fun?(expr) AND NOT div?(expr) AND NOT pow?(expr) AND NOT sq?(expr)
       AND NOT mult?(expr) AND NOT sub?(expr) AND NOT neg?(expr)
       AND NOT abs?(expr) AND NOT add?(expr) AND NOT varidx?(expr)
       AND NOT const?(expr)
       IMPLIES
           bincludes?(expr) OR fun?(expr) OR pow?(expr) OR sq?(expr)
        OR neg?(expr) OR abs?(expr);

  % Termination TCC generated (at line 73, column 16) for
      % eval(op(expr), vs, n)
  eval_TCC27: OBLIGATION
    FORALL (expr: RealExpr):
           fun?(expr) AND NOT div?(expr) AND NOT pow?(expr) AND NOT sq?(expr)
       AND NOT mult?(expr) AND NOT sub?(expr) AND NOT neg?(expr)
       AND NOT abs?(expr) AND NOT add?(expr) AND NOT varidx?(expr)
       AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op(expr), expr);

  % Subtype TCC generated (at line 76, column 17) for  expr
      % expected type  (letin?)
  eval_TCC28: OBLIGATION
    FORALL (expr: RealExpr,
            v:
              [{z: [RealExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [RealExpr, RealExpr], boolean]
                            (<<)(z`1, expr)} ->
                 real],
            vs: Env, n: nat):
           NOT fun?(expr) AND NOT div?(expr) AND NOT pow?(expr)
       AND NOT sq?(expr) AND NOT mult?(expr) AND NOT sub?(expr)
       AND NOT neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       (FORALL (rlet: real):
          rlet = v(rlet(expr), vs, n) IMPLIES letin?(expr));

  % Termination TCC generated (at line 76, column 8) for
      % eval(rin(expr), vs WITH [`n := rlet], n + 1)
  eval_TCC29: OBLIGATION
    FORALL (expr: RealExpr,
            v:
              [{z: [RealExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [RealExpr, RealExpr], boolean]
                            (<<)(z`1, expr)} ->
                 real],
            vs: Env, n: nat):
           NOT fun?(expr) AND NOT div?(expr) AND NOT pow?(expr)
       AND NOT sq?(expr) AND NOT mult?(expr) AND NOT sub?(expr)
       AND NOT neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       (FORALL (rlet: real):
          rlet = v(rlet(expr), vs, n) IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
               (<<)(rin(expr), expr));

  % Subtype TCC generated (at line 75, column 27) for  expr
      % expected type  (letin?)
  eval_TCC30: OBLIGATION
    FORALL (expr: RealExpr):
           NOT fun?(expr) AND NOT div?(expr) AND NOT pow?(expr)
       AND NOT sq?(expr) AND NOT mult?(expr) AND NOT sub?(expr)
       AND NOT neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES letin?(expr);

  % Termination TCC generated (at line 75, column 17) for
      % eval(rlet(expr), vs, n)
  eval_TCC31: OBLIGATION
    FORALL (expr: RealExpr):
           NOT fun?(expr) AND NOT div?(expr) AND NOT pow?(expr)
       AND NOT sq?(expr) AND NOT mult?(expr) AND NOT sub?(expr)
       AND NOT neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(rlet(expr), expr);

  % Subtype TCC generated (at line 84, column 19) for  varidx(expr)
      % expected type  below[length[Interval](box)]
  Eval_TCC1: OBLIGATION
    FORALL (expr: RealExpr, box: Box):
      NOT varidx(expr) >= length(box) AND varidx?(expr) AND NOT const?(expr)
       IMPLIES varidx(expr) < length[Interval](box);

  % Termination TCC generated (at line 119, column 16) for
      % Eval(op1(expr), box)
  Eval_TCC2: OBLIGATION
    FORALL (expr: RealExpr):
           div?(expr) AND NOT pow?(expr) AND NOT sq?(expr) AND NOT mult?(expr)
       AND NOT sub?(expr) AND NOT neg?(expr) AND NOT abs?(expr)
       AND NOT add?(expr) AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
           (<<)(op1(expr), expr);

  % Termination TCC generated (at line 132, column 8) for
      % Eval(rin(expr), append(box, (: rlet :)))
  Eval_TCC3: OBLIGATION
    FORALL (expr: RealExpr,
            v:
              [{z: [RealExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [RealExpr, RealExpr], boolean]
                            (<<)(z`1, expr)} ->
                 Interval],
            box: Box):
           NOT fun?(expr) AND NOT div?(expr) AND NOT pow?(expr)
       AND NOT sq?(expr) AND NOT mult?(expr) AND NOT sub?(expr)
       AND NOT neg?(expr) AND NOT abs?(expr) AND NOT add?(expr)
       AND NOT varidx?(expr) AND NOT const?(expr)
       IMPLIES
       (FORALL (rlet: Interval):
          Proper?(rlet) AND rlet = v(rlet(expr), box) IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [RealExpr, RealExpr], boolean]
               (<<)(rin(expr), expr));

  % Subtype TCC generated (at line 143, column 41) for  expr
      % expected type  {x: IntervalExpr |
                     %              brel?(x) OR div?(x) OR mult?(x) OR sub?(x)
                     %           OR add?(x)}
  well_typed?_TCC1: OBLIGATION
    FORALL (box: Box, expr: RealExpr):
      add?(expr) AND
       NOT (varidx?(expr) AND varidx(expr) < length(box)) AND
        NOT const?(expr)
       IMPLIES
           brel?(expr) OR div?(expr) OR mult?(expr) OR sub?(expr)
        OR add?(expr);

  % Subtype TCC generated (at line 144, column 40) for  expr
      % expected type  {x: IntervalExpr |
                     %              bincludes?(x) OR fun?(x) OR pow?(x)
                     %           OR sq?(x) OR neg?(x) OR abs?(x)}
  well_typed?_TCC2: OBLIGATION
    FORALL (box: Box, expr: RealExpr):
      abs?(expr) AND
       NOT (add?(expr) AND
             well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
        AND
        NOT (varidx?(expr) AND varidx(expr) < length(box)) AND
         NOT const?(expr)
       IMPLIES
           bincludes?(expr) OR fun?(expr) OR pow?(expr) OR sq?(expr)
        OR neg?(expr) OR abs?(expr);

  % Subtype TCC generated (at line 145, column 41) for  expr
      % expected type  {x: IntervalExpr |
                     %              brel?(x) OR div?(x) OR mult?(x) OR sub?(x)
                     %           OR add?(x)}
  well_typed?_TCC3: OBLIGATION
    FORALL (box: Box, expr: RealExpr):
           sub?(expr) AND NOT (abs?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (add?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (varidx?(expr) AND varidx(expr) < length(box))
       AND NOT const?(expr)
       IMPLIES
           brel?(expr) OR div?(expr) OR mult?(expr) OR sub?(expr)
        OR add?(expr);

  % Subtype TCC generated (at line 146, column 40) for  expr
      % expected type  {x: IntervalExpr |
                     %              bincludes?(x) OR fun?(x) OR pow?(x)
                     %           OR sq?(x) OR neg?(x) OR abs?(x)}
  well_typed?_TCC4: OBLIGATION
    FORALL (box: Box, expr: RealExpr):
           neg?(expr)
       AND NOT (sub?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (abs?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (add?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (varidx?(expr) AND varidx(expr) < length(box))
       AND NOT const?(expr)
       IMPLIES
           bincludes?(expr) OR fun?(expr) OR pow?(expr) OR sq?(expr)
        OR neg?(expr) OR abs?(expr);

  % Subtype TCC generated (at line 147, column 42) for  expr
      % expected type  {x: IntervalExpr |
                     %              brel?(x) OR div?(x) OR mult?(x) OR sub?(x)
                     %           OR add?(x)}
  well_typed?_TCC5: OBLIGATION
    FORALL (box: Box, expr: RealExpr):
           mult?(expr) AND NOT (neg?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (sub?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (abs?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (add?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (varidx?(expr) AND varidx(expr) < length(box))
       AND NOT const?(expr)
       IMPLIES
           brel?(expr) OR div?(expr) OR mult?(expr) OR sub?(expr)
        OR add?(expr);

  % Subtype TCC generated (at line 148, column 39) for  expr
      % expected type  {x: IntervalExpr |
                     %              bincludes?(x) OR fun?(x) OR pow?(x)
                     %           OR sq?(x) OR neg?(x) OR abs?(x)}
  well_typed?_TCC6: OBLIGATION
    FORALL (box: Box, expr: RealExpr):
           sq?(expr)
       AND NOT (mult?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (neg?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (sub?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (abs?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (add?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (varidx?(expr) AND varidx(expr) < length(box))
       AND NOT const?(expr)
       IMPLIES
           bincludes?(expr) OR fun?(expr) OR pow?(expr) OR sq?(expr)
        OR neg?(expr) OR abs?(expr);

  % Subtype TCC generated (at line 149, column 41) for  expr
      % expected type  {x: IntervalExpr |
                     %              brel?(x) OR div?(x) OR mult?(x) OR sub?(x)
                     %           OR add?(x)}
  well_typed?_TCC7: OBLIGATION
    FORALL (box: Box, expr: RealExpr):
           div?(expr) AND NOT (sq?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (mult?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (neg?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (sub?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (abs?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (add?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (varidx?(expr) AND varidx(expr) < length(box))
       AND NOT const?(expr)
       IMPLIES
           brel?(expr) OR div?(expr) OR mult?(expr) OR sub?(expr)
        OR add?(expr);

  % Subtype TCC generated (at line 151, column 40) for  expr
      % expected type  {x: IntervalExpr |
                     %              bincludes?(x) OR fun?(x) OR pow?(x)
                     %           OR sq?(x) OR neg?(x) OR abs?(x)}
  well_typed?_TCC8: OBLIGATION
    FORALL (box: Box, expr: RealExpr):
           pow?(expr)
       AND NOT (div?(expr) AND
                 well_typed?(box)(op1(expr)) AND
                  well_typed?(box)(op2(expr)) AND
                   Zeroless?(Eval(op2(expr), box)))
       AND NOT (sq?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (mult?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (neg?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (sub?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (abs?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (add?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (varidx?(expr) AND varidx(expr) < length(box))
       AND NOT const?(expr)
       IMPLIES
           bincludes?(expr) OR fun?(expr) OR pow?(expr) OR sq?(expr)
        OR neg?(expr) OR abs?(expr);

  % Subtype TCC generated (at line 152, column 40) for  expr
      % expected type  {x: IntervalExpr |
                     %              bincludes?(x) OR fun?(x) OR pow?(x)
                     %           OR sq?(x) OR neg?(x) OR abs?(x)}
  well_typed?_TCC9: OBLIGATION
    FORALL (box: Box, expr: RealExpr):
           fun?(expr) AND NOT (pow?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (div?(expr) AND
                 well_typed?(box)(op1(expr)) AND
                  well_typed?(box)(op2(expr)) AND
                   Zeroless?(Eval(op2(expr), box)))
       AND NOT (sq?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (mult?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (neg?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (sub?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (abs?(expr) AND well_typed?(box)(op(expr)))
       AND NOT (add?(expr) AND
                 well_typed?(box)(op1(expr)) AND well_typed?(box)(op2(expr)))
       AND NOT (varidx?(expr) AND varidx(expr) < length(box))
       AND NOT const?(expr)
       IMPLIES
           bincludes?(expr) OR fun?(expr) OR pow?(expr) OR sq?(expr)
        OR neg?(expr) OR abs?(expr);

  % Subtype TCC generated (at line 217, column 79) for  i
      % expected type  below[length[Interval](lb)]
  split_TCC1: OBLIGATION
    FORALL (box, v, lrb: [Box, Box], lb: Box, rb: Box):
      length(rb) = length(box) AND
       length(lb) = length(box) AND rb = lrb`2 AND lb = lrb`1
       IMPLIES
       (FORALL (i: below(length[Interval](box))):
          i = v AND rb = lrb`2 AND lb = lrb`1 IMPLIES
           i < length[Interval](lb));

  % Subtype TCC generated (at line 218, column 81) for  i
      % expected type  below[length[Interval](rb)]
  split_TCC2: OBLIGATION
    FORALL (box, v, lrb: [Box, Box], lb: Box, rb: Box):
      length(rb) = length(box) AND
       length(lb) = length(box) AND rb = lrb`2 AND lb = lrb`1
       IMPLIES
       (FORALL (i: below(length[Interval](box))):
          nth(lb, i) = HalfLeft(nth(box, i)) AND
           i = v AND rb = lrb`2 AND lb = lrb`1
           IMPLIES i < length[Interval](rb));

  % Subtype TCC generated (at line 219, column 74) for  i
      % expected type  below[length[Interval](lb)]
  split_TCC3: OBLIGATION
    FORALL (box, v, lrb: [Box, Box], lb: Box, rb: Box):
      length(rb) = length(box) AND
       length(lb) = length(box) AND rb = lrb`2 AND lb = lrb`1
       IMPLIES
       (FORALL (i: below(length[Interval](box))):
          NOT i = v AND rb = lrb`2 AND lb = lrb`1 IMPLIES
           i < length[Interval](lb));

  % Subtype TCC generated (at line 220, column 74) for  i
      % expected type  below[length[Interval](rb)]
  split_TCC4: OBLIGATION
    FORALL (box, v, lrb: [Box, Box], lb: Box, rb: Box):
      length(rb) = length(box) AND
       length(lb) = length(box) AND rb = lrb`2 AND lb = lrb`1
       IMPLIES
       (FORALL (i: below(length[Interval](box))):
          nth(lb, i) = nth(box, i) AND
           NOT i = v AND rb = lrb`2 AND lb = lrb`1
           IMPLIES i < length[Interval](rb));

  % Subtype TCC generated (at line 222, column 23) for  (null, null)
      % expected type  {lrb: [Box, Box] |
                     %          length(lrb`1) = length(box) AND
                     %           length(lrb`2) = length(box) AND
                     %            (FORALL (i: below(length(box))):
                     %               IF i = v
                     %                 THEN nth(lrb`1, i)
                     %                      =
                     %                      HalfLeft(nth(box, i))
                     %                      AND
                     %                      nth(lrb`2, i)
                     %                      =
                     %                      HalfRight(nth(box, i))
                     %               ELSE nth(lrb`1, i) = nth(box, i)
                     %                    AND
                     %                    nth(lrb`2, i) = nth(box, i)
                     %               ENDIF)}
  split_TCC5: OBLIGATION
    FORALL (v: nat, box: Box):
      null?(box) IMPLIES
       length[Interval](null[Interval]) = length[Interval](box) AND
        length[Interval](null[Interval]) = length[Interval](box) AND
         (FORALL (i: below(length[Interval](box))):
            IF i = v
              THEN nth[Interval](null[Interval], i) =
                    HalfLeft(nth[Interval](box, i))
                    AND
                    nth[Interval](null[Interval], i) =
                     HalfRight(nth[Interval](box, i))
            ELSE nth[Interval](null[Interval], i) = nth[Interval](box, i) AND
                  nth[Interval](null[Interval], i) = nth[Interval](box, i)
            ENDIF);

  % Subtype TCC generated (at line 223, column 40) for  box
      % expected type  (cons?[Interval])
  split_TCC6: OBLIGATION
    FORALL (v: nat, box: Box):
      v = 0 AND NOT null?(box) IMPLIES cons?[Interval](box);

  % Subtype TCC generated (at line 223, column 21) for
      % (cons(HalfLeft(car(box)), cdr(box)),
      %  cons(HalfRight(car(box)), cdr(box)))
      % expected type  {lrb: [Box, Box] |
                     %          length(lrb`1) = length(box) AND
                     %           length(lrb`2) = length(box) AND
                     %            (FORALL (i: below(length(box))):
                     %               IF i = v
                     %                 THEN nth(lrb`1, i)
                     %                      =
                     %                      HalfLeft(nth(box, i))
                     %                      AND
                     %                      nth(lrb`2, i)
                     %                      =
                     %                      HalfRight(nth(box, i))
                     %               ELSE nth(lrb`1, i) = nth(box, i)
                     %                    AND
                     %                    nth(lrb`2, i) = nth(box, i)
                     %               ENDIF)}
  split_TCC7: OBLIGATION
    FORALL (v: nat, box: Box):
      v = 0 AND NOT null?(box) IMPLIES
       length[Interval]
           (cons[Interval](HalfLeft(car[Interval](box)), cdr[Interval](box)))
        = length[Interval](box)
        AND
        length[Interval]
            (cons[Interval]
                 (HalfRight(car[Interval](box)), cdr[Interval](box)))
         = length[Interval](box)
         AND
         (FORALL (i: below(length[Interval](box))):
            IF i = v
              THEN nth[Interval]
                       (cons[Interval]
                            (HalfLeft(car[Interval](box)),
                             cdr[Interval](box)),
                        i)
                    = HalfLeft(nth[Interval](box, i))
                    AND
                    nth[Interval]
                        (cons[Interval]
                             (HalfRight(car[Interval](box)),
                              cdr[Interval](box)),
                         i)
                     = HalfRight(nth[Interval](box, i))
            ELSE nth[Interval]
                     (cons[Interval]
                          (HalfLeft(car[Interval](box)), cdr[Interval](box)),
                      i)
                  = nth[Interval](box, i)
                  AND
                  nth[Interval]
                      (cons[Interval]
                           (HalfRight(car[Interval](box)),
                            cdr[Interval](box)),
                       i)
                   = nth[Interval](box, i)
            ENDIF);

  % Subtype TCC generated (at line 226, column 23) for  box
      % expected type  (cons?[Interval])
  split_TCC8: OBLIGATION
    FORALL (v: nat, box: Box,
            v1:
              [d1: {z: [nat, Box] | z`2 << box} ->
                 {lrb: [Box, Box] |
                          length(lrb`1) = length(d1`2) AND
                           length(lrb`2) = length(d1`2) AND
                            (FORALL (i: below(length(d1`2))):
                               IF i = d1`1
                                 THEN nth(lrb`1, i) = HalfLeft(nth(d1`2, i))
                                      AND
                                      nth(lrb`2, i) = HalfRight(nth(d1`2, i))
                               ELSE nth(lrb`1, i) = nth(d1`2, i) AND
                                     nth(lrb`2, i) = nth(d1`2, i)
                               ENDIF)}]):
      NOT v = 0 AND NOT null?(box) IMPLIES
       (FORALL (lb: Box, rb: Box):
          rb = v1(v - 1, cdr(box))`2 AND lb = v1(v - 1, cdr(box))`1 IMPLIES
           cons?[Interval](box));

  % Subtype TCC generated (at line 226, column 13) for
      % (cons(car(box), lb), cons(car(box), rb))
      % expected type  {lrb: [Box, Box] |
                     %          length(lrb`1) = length(box) AND
                     %           length(lrb`2) = length(box) AND
                     %            (FORALL (i: below(length(box))):
                     %               IF i = v
                     %                 THEN nth(lrb`1, i)
                     %                      =
                     %                      HalfLeft(nth(box, i))
                     %                      AND
                     %                      nth(lrb`2, i)
                     %                      =
                     %                      HalfRight(nth(box, i))
                     %               ELSE nth(lrb`1, i) = nth(box, i)
                     %                    AND
                     %                    nth(lrb`2, i) = nth(box, i)
                     %               ENDIF)}
  split_TCC9: OBLIGATION
    FORALL (v: nat, box: Box,
            v1:
              [d1: {z: [nat, Box] | z`2 << box} ->
                 {lrb: [Box, Box] |
                          length(lrb`1) = length(d1`2) AND
                           length(lrb`2) = length(d1`2) AND
                            (FORALL (i: below(length(d1`2))):
                               IF i = d1`1
                                 THEN nth(lrb`1, i) = HalfLeft(nth(d1`2, i))
                                      AND
                                      nth(lrb`2, i) = HalfRight(nth(d1`2, i))
                               ELSE nth(lrb`1, i) = nth(d1`2, i) AND
                                     nth(lrb`2, i) = nth(d1`2, i)
                               ENDIF)}]):
      NOT v = 0 AND NOT null?(box) IMPLIES
       (FORALL (lb: Box, rb: Box):
          rb = v1(v - 1, cdr(box))`2 AND lb = v1(v - 1, cdr(box))`1 IMPLIES
           length[Interval](cons[Interval](car[Interval](box), lb)) =
            length[Interval](box)
            AND
            length[Interval](cons[Interval](car[Interval](box), rb)) =
             length[Interval](box)
             AND
             (FORALL (i: below(length[Interval](box))):
                IF i = v
                  THEN nth[Interval]
                           (cons[Interval](car[Interval](box), lb), i)
                        = HalfLeft(nth[Interval](box, i))
                        AND
                        nth[Interval]
                            (cons[Interval](car[Interval](box), rb), i)
                         = HalfRight(nth[Interval](box, i))
                ELSE nth[Interval](cons[Interval](car[Interval](box), lb), i)
                      = nth[Interval](box, i)
                      AND
                      nth[Interval]
                          (cons[Interval](car[Interval](box), rb), i)
                       = nth[Interval](box, i)
                ENDIF));

  % Subtype TCC generated (at line 225, column 29) for  v - 1
      % expected type  nat
  split_TCC10: OBLIGATION
    FORALL (v: nat, box: Box):
      NOT v = 0 AND NOT null?(box) IMPLIES v - 1 >= 0;

  % Subtype TCC generated (at line 225, column 37) for  box
      % expected type  (cons?[Interval])
  split_TCC11: OBLIGATION
    FORALL (v: nat, box: Box):
      NOT v = 0 AND NOT null?(box) IMPLIES cons?[Interval](box);

  % Termination TCC generated (at line 225, column 23) for
      % split(v - 1, cdr(box))
  split_TCC12: OBLIGATION
    FORALL (v: nat, box: Box):
      NOT v = 0 AND NOT null?(box) IMPLIES
       <<[Interval](cdr[Interval](box), box);

  % Recursive judgement subtype TCC generated (at line 1, column 19) for  (null, null)
      % expected type  {lrb: [Box, Box] | lrb`1 = box AND lrb`2 = box}
  split_eq_TCC1: OBLIGATION
    FORALL (v: nat, (box: Box | length[Interval](box) <= v)):
      null?(box) IMPLIES null[Interval] = box AND null[Interval] = box;

  % Recursive judgement subtype TCC generated (at line 3, column 7) for
      % (cons(HalfLeft(car(box)), cdr(box)),
      %  cons(HalfRight(car(box)), cdr(box)))
      % expected type  {lrb: [Box, Box] | lrb`1 = box AND lrb`2 = box}
  split_eq_TCC2: OBLIGATION
    FORALL (v: nat, (box: Box | length[Interval](box) <= v)):
      v = 0 AND NOT null?(box) IMPLIES
       cons[Interval](HalfLeft(car[Interval](box)), cdr[Interval](box)) = box
        AND
        cons[Interval](HalfRight(car[Interval](box)), cdr[Interval](box)) =
         box;

  % Recursive judgement subtype TCC generated (at line 5, column 30) for  cdr(box)
      % expected type  {box: Box | length(box) <= v - 1}
  split_eq_TCC3: OBLIGATION
    FORALL (v: nat, (box: Box | length[Interval](box) <= v)):
      NOT v = 0 AND NOT null?(box) IMPLIES
       length[Interval](cdr[Interval](box)) <= v - 1;

  % Recursive judgement subtype TCC generated (at line 6, column 7) for
      % (cons(car(box), lb), cons(car(box), rb))
      % expected type  {lrb: [Box, Box] | lrb`1 = box AND lrb`2 = box}
  split_eq_TCC4: OBLIGATION
    FORALL (v1:
              [d: [v: nat, {box: Box | length(box) <= v}] ->
                 {lrb: [Box, Box] | lrb`1 = d`2 AND lrb`2 = d`2}],
            v: nat, (box: Box | length[Interval](box) <= v)):
      NOT v = 0 AND NOT null?(box) IMPLIES
       (FORALL (lb: Box, rb: Box):
          rb = v1(v - 1, cdr(box))`2 AND lb = v1(v - 1, cdr(box))`1 IMPLIES
           cons[Interval](car[Interval](box), lb) = box AND
            cons[Interval](car[Interval](box), rb) = box);

  % Judgement subtype TCC generated (at line 243, column 27) for  split(v, pox)
      % expected type  [ProperBox, ProperBox]
  split_Proper: OBLIGATION
    FORALL (pox, v):
      ProperBox?(split(v, pox)`2) AND ProperBox?(split(v, pox)`1);


body:
  interval_expr_lnexp : THEORY
  BEGIN

    IMPORTING interval_expr,
              interval_lnexp
    
    expr : VAR RealExpr
    n    : VAR nat

    ln_safe(x:real): real = IF x <= 0 THEN 0 ELSE ln(x) ENDIF

    Ln_Inclusion : JUDGEMENT
      Ln(n) HAS_TYPE (Inclusion?(Pos?,ln_safe))

    Ln_Fundamental : JUDGEMENT
      Ln(n) HAS_TYPE (Fundamental?(Pos?))

    LN_n(n:nat)(expr): MACRO RealExpr = FUN(Pos?,ln_safe,Ln(n),expr)

    exp_safe(x:real) : posreal  = exp(x)

    Exp_Inclusion : JUDGEMENT
      Exp(n) HAS_TYPE (Inclusion?(PreTrue,exp_safe))

    Exp_Fundamental : JUDGEMENT
      Exp(n) HAS_TYPE (Fundamental?(PreTrue))

    EXP_n(n:nat)(expr): MACRO RealExpr = FUN(PreTrue,exp_safe,Exp(n),expr)

    e_safe : [Unit->real] = LAMBDA(u:Unit) : e

    E_Inclusion : JUDGEMENT
      En(n) HAS_TYPE (Includes?(e_safe(unit)))

    E_n(n): MACRO RealExpr = CONST(e_safe,En(n))

  END interval_expr_lnexp

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

  % Subtype TCC generated (at line 10, column 51) for  x
      % expected type  posreal
  ln_safe_TCC1: OBLIGATION
    FORALL (x: real): NOT x <= 0 IMPLIES x >= 0 AND x > 0;

  % Judgement subtype TCC generated (at line 13, column 4) for  Ln(n)
      % expected type  (Inclusion?(Pos?, ln_safe))
  Ln_Inclusion: OBLIGATION FORALL (n): Inclusion?(Pos?, ln_safe)(Ln(n));

  % Judgement subtype TCC generated (at line 16, column 4) for  Ln(n)
      % expected type  (Fundamental?(Pos?))
  Ln_Fundamental: OBLIGATION FORALL (n): Fundamental?(Pos?)(Ln(n));

  % Subtype TCC generated (at line 18, column 55) for  Ln(n)
      % expected type  {F: [Interval -> Interval] |
                     %          Inclusion?(Pos?, ln_safe)(F) AND
                     %           Fundamental?(Pos?)(F)}
  LN_n_TCC1: OBLIGATION
    FORALL (n: nat, expr: RealExpr):
      Inclusion?(Pos?, ln_safe)(Ln(n)) AND Fundamental?(Pos?)(Ln(n));

  % Judgement subtype TCC generated (at line 23, column 4) for  Exp(n)
      % expected type  (Inclusion?(PreTrue, exp_safe))
  Exp_Inclusion: OBLIGATION FORALL (n): Inclusion?(PreTrue, exp_safe)(Exp(n));

  % Judgement subtype TCC generated (at line 26, column 4) for  Exp(n)
      % expected type  (Fundamental?(PreTrue))
  Exp_Fundamental: OBLIGATION FORALL (n): Fundamental?(PreTrue)(Exp(n));

  % Subtype TCC generated (at line 28, column 60) for  Exp(n)
      % expected type  {F: [Interval -> Interval] |
                     %          Inclusion?(PreTrue, exp_safe)(F) AND
                     %           Fundamental?(PreTrue)(F)}
  EXP_n_TCC1: OBLIGATION
    FORALL (n: nat, expr: RealExpr):
      Inclusion?(PreTrue, exp_safe)(Exp(n)) AND Fundamental?(PreTrue)(Exp(n));

  % Judgement subtype TCC generated (at line 33, column 4) for  En(n)
      % expected type  (Includes?(e_safe(unit)))
  E_Inclusion: OBLIGATION FORALL (n): Includes?(e_safe(unit))(En(n));


body:
  %% interval_trig.pvs

  interval_trig : THEORY
  BEGIN
    IMPORTING trig_fnd@trig_basic,
              trig_fnd@trig_approx,
              trig_fnd@trig_ineq,
              trig_fnd@tan_approx,
              trig_fnd@atan_approx,
              trig_fnd@trig_values,
              interval

    X,Y : VAR Interval
    x   : VAR real
    n   : VAR nat

    cos_error_pi_lbn_bound: LEMMA
      abs(cos_term(pi_lbn(n))(2*n+2)) < 
      3.2^(4+4*n)/factorial(4+4*n)

    % Pi
    Pi(n) : (Pos?) = [|pi_lbn(n),pi_ubn(n)|]

    % Sin
    sin_npi2_pi2(n)(X) : Interval =
      [|sin_lb(lb(X),n),sin_ub(ub(X),n)|]

    sin_pi2_pi(n)(X) : Interval =
      [|sin_lb(ub(X),n),sin_ub(lb(X),n)|]

    sin_0_pi(n)(X) : Interval =
      [|min(sin_lb(lb(X),n),sin_lb(ub(X),n)),1|]

    % Cos
    cos_0_pi(n)(X) : Interval =
      [|cos_lb(ub(X),n),cos_ub(lb(X),n)|]

    cos_npi2_pi2(n)(X) : Interval =
      [|min(cos_lb(lb(X),n),cos_lb(ub(X),n)),1|]

    Cos(n)(X) : Interval =
        if    X << [|0,pi_lb_est(n)|]             then cos_0_pi(n)(X)
        elsif X << [|-pi_lb_est(n),0|]            then cos_0_pi(n)(Neg(X))
        elsif X << [|-pi_lb_est(n)/2,pi_lb_est(n)/2|] then cos_npi2_pi2(n)(X)
        else  [|-1-(3.2^(4+4*n)/factorial(4+4*n)),1|]
        endif

    Cos_fundamental: LEMMA
      Proper?(X) AND
      X << Y IMPLIES
      Cos(n)(X) << Cos(n)(Y)

    %%% The next function translates

    Sin(n)(X) : Interval =
      LET Xpos    = Intersection(X,[|0,ub(X)|]),
      	Xneg    = Intersection(X,[|lb(X),0|]),
  	CosXpos = Cos(n)(Add(Xpos,[|-pi_ubn(n)/2,-pi_lbn(n)/2|])),
  	CosXneg = Neg(Cos(n)(Add(Neg(Xneg),[|-pi_ubn(n)/2,-pi_lbn(n)/2|])))
      IN  IF Proper?(Xpos) AND Proper?(Xneg) THEN
             		 Union(CosXpos,CosXneg)
  	ELSIF Proper?(Xpos) THEN CosXpos
  	ELSIF Proper?(Xneg) THEN CosXneg
  	ELSE [| 1, 0 |] ENDIF

    Sin_fundamental: LEMMA
      Proper?(X) AND
      X << Y IMPLIES
      Sin(n)(X) << Sin(n)(Y)
    
    tan_0_pi2(n)(X) : Interval = 
      let cos_ub_lb = cos_ub(lb(X),n) in
      let cos_lb_ub = cos_lb(ub(X),n) in
      if cos_ub_lb > 0 AND cos_lb_ub > 0 then
        [|sin_lb(lb(X),n)/cos_ub_lb,sin_ub(ub(X),n)/cos_lb_ub|]
      else
        EmptyInterval
      endif

    tan_npi2_pi2(n)(X) : Interval = 
      let cos_lb_lb = cos_lb(lb(X),n) in
      let cos_lb_ub = cos_lb(ub(X),n) in
      if cos_lb_lb > 0 AND cos_lb_ub > 0 then
        [|sin_lb(lb(X),n)/cos_lb_lb,sin_ub(ub(X),n)/cos_lb_ub|]
      else 
        EmptyInterval
      endif

    tan_npi2_pi2_union: LEMMA
      n>=5 AND
      0 ## X AND X << [|-pi_lb_est(n)/2,pi_lb_est(n)/2|]
      IMPLIES
      tan_npi2_pi2(n)(X) =
      Union(Neg(tan_0_pi2(n)(Neg(Intersection(X,[|-pi_lb_est(n)/2,0|])))),
  	  tan_0_pi2(n)(Intersection(X,[|0,pi_lb_est(n)/2|])))

    % Approximation to guarantee cos_lb > 0
    Cos_pos_n : MACRO posnat = 5 

    Tan(n)(X) : Interval = 
      let n = n+Cos_pos_n in
      if    X << [|0,pi_lb_est(n)/2|]        then  tan_0_pi2(n)(X) 
      elsif X << [|-pi_lb_est(n)/2,0|]       then  Neg(tan_0_pi2(n)(Neg(X)))
      elsif X << [|-pi_lb_est(n)/2,pi_lb_est(n)/2|] then  tan_npi2_pi2(n)(X)
      else  EmptyInterval
      endif

    Tan_proper: LEMMA
      Proper?(X) AND X << [|-pi_lb_est(n+Cos_pos_n)/2,pi_lb_est(n+Cos_pos_n)/2|]
      IMPLIES
      Proper?(Tan(n)(X))

    Atan(n)(X) : Interval =
      [|atan_lb(lb(X),n),atan_ub(ub(X),n)|]

    Atan_fundamental: LEMMA
      X << Y IMPLIES
      Atan(n)(X) << Atan(n)(Y)

    % lemmas

    Pi_inclusion : LEMMA
      pi ## Pi(n)

    Pi_proper : JUDGEMENT Pi(n) HAS_TYPE ProperInterval

    sin_npi2_pi2 : LEMMA
      X << [|-pi_lbn(n)/2,pi_lbn(n)/2|] AND
      x ## X          
      IMPLIES 
      sin(x) ## sin_npi2_pi2(n)(X)

    sin_pi2_pi : LEMMA
      X << [|pi_ubn(n)/2,pi_lbn(n)|] AND
      x ## X     
      IMPLIES 
      sin(x) ## sin_pi2_pi(n)(X)

    sin_0_pi : LEMMA
      X << [|0,pi_lbn(n)|] AND
      x ## X        
      IMPLIES 
      sin(x) ## sin_0_pi(n)(X)

    sin_npi_0 : LEMMA
      X << [|-pi_lbn(n),0|] AND
      x ## X IMPLIES 
      sin(x) ## Neg(sin_0_pi(n)(Neg(X)))

    sin_npi_npi2 : LEMMA
      X << [|-pi_lbn(n),-pi_ubn(n)/2|] AND
      x ## X     
      IMPLIES 
      sin(x) ## Neg(sin_pi2_pi(n)(Neg(X)))

    cos_0_pi : LEMMA
      X << [|0,pi_lbn(n)|] AND
      x ## X IMPLIES 
      cos(x) ## cos_0_pi(n)(X)

    cos_npi_0 : LEMMA
      X << [|-pi_lbn(n),0|] AND
      x ## X IMPLIES 
      cos(x) ## cos_0_pi(n)(Neg(X))

    cos_npi2_pi2 : LEMMA
      X << [|-pi_lbn(n)/2,pi_lbn(n)/2|] AND
      x ## X IMPLIES	 
      cos(x) ## cos_npi2_pi2(n)(X)

    Cos_inclusion : LEMMA
       x ## X IMPLIES
       cos(x) ## Cos(n)(X)

    Sin_inclusion : LEMMA
       x  ## X 
       IMPLIES
       sin(x) ## Sin(n)(X)

    Tan_pi2_def : LEMMA
      x ## X AND 
      X << [| -pi_lbn(n)/2, pi_lbn(n)/2 |]
      IMPLIES
        Tan?(x)

    cos_lb_gt_0_pos : LEMMA
      x ## [|0,pi_lbn(n)/2|] AND
      n >= Cos_pos_n IMPLIES
      cos_lb(x,n) > 0

    cos_lb_gt_0 : LEMMA
      x ## [|-pi_lbn(n)/2,pi_lbn(n)/2|] AND
      n >= Cos_pos_n IMPLIES
      cos_lb(x,n) > 0

    cos_ub_gt_0 : LEMMA
      x ## [|-pi_lbn(n)/2,pi_lbn(n)/2|] AND
      cos_lb(x,n) > 0 IMPLIES
      cos_ub(x,n) > 0 

    cos_lb_ub_gt_0 : LEMMA
      X << [|-pi_lbn(n)/2,pi_lbn(n)/2|] AND
      Proper?(X) AND
      n >= Cos_pos_n  IMPLIES
      cos_lb(lb(X),n) > 0 AND
      cos_lb(ub(X),n) > 0 AND
      cos_ub(lb(X),n) > 0 AND
      cos_ub(ub(X),n) > 0 

    tan_0_pi2 : LEMMA
      X << [|0,pi_lbn(n)/2|] AND
      n >= Cos_pos_n AND
      x ## X IMPLIES
      tan(x) ## tan_0_pi2(n)(X)

    tan_npi2_0 : LEMMA
      X << [|-pi_lbn(n)/2,0|] AND
      n >= Cos_pos_n AND
      x ## X IMPLIES
      tan(x) ## Neg(tan_0_pi2(n)(Neg(X)))

    tan_npi2_pi2 : LEMMA
      X << [|-pi_lbn(n)/2,pi_lbn(n)/2|] AND
      Zeroin?(X) AND
      n >= Cos_pos_n AND
      x ## X IMPLIES
      tan(x) ## tan_npi2_pi2(n)(X)

    TAN?(n)(X) : bool =
      X << [| -pi_lb_est(n+Cos_pos_n)/2, pi_lb_est(n+Cos_pos_n)/2 |] 

    TAN_Tan : LEMMA
      TAN?(n)(X) AND
      x ## X IMPLIES
        Tan?(x)

    Tan_inclusion : LEMMA
      TAN?(n)(X) AND
      x ## X IMPLIES
      tan(x) ## Tan(n)(X)

    Tan_fundamental: LEMMA
      Proper?(X) AND TAN?(n)(Y) AND
      X << Y IMPLIES
      Tan(n)(X) << Tan(n)(Y)

    Atan_inclusion : LEMMA
      x ## X IMPLIES
      atan(x) ## Atan(n)(X)

    Strict_Tan : LEMMA
      TAN?(n)(X) AND
      StrictInterval?(X) IMPLIES
      StrictInterval?(Tan(n)(X))

    %% Safe version of trigonometric functions
    IMPORTING safe_arith

    safe_Sin(n) : [Interval->Interval] = Safe1(Sin(n))
    safe_Cos(n) : [Interval->Interval] = Safe1(Cos(n))
    safe_Tan(n) : [Interval->Interval] = Safe1(TAN?(n),Tan(n))
    safe_Atan(n) : [Interval->Interval] = Safe1(Atan(n))
  	    
    %% Proper version of trigonometric functions
    IMPORTING proper_arith

    Xp   : VAR ProperInterval

    Proper_Sin : JUDGEMENT
      Sin(n)(Xp) HAS_TYPE ProperInterval

    Proper_Cos : JUDGEMENT
      Cos(n)(Xp) HAS_TYPE ProperInterval

    Proper_Tan : JUDGEMENT
      Tan(n)(Xp|TAN?(n)(Xp)) HAS_TYPE ProperInterval

    Proper_Atan : JUDGEMENT
      Atan(n)(Xp) HAS_TYPE ProperInterval

    proper_Sin(n)(Xp): ProperInterval =
      Sin(n)(Xp)

    proper_Cos(n)(Xp): ProperInterval =
      Cos(n)(Xp)

    proper_Tan(n)(Xp|TAN?(n)(Xp)): ProperInterval =
      Tan(n)(Xp)

    proper_Atan(n)(Xp): ProperInterval =
      Atan(n)(Xp)

  END interval_trig

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

  % Subtype TCC generated (at line 22, column 19) for
      % [|pi_lbn(n), pi_ubn(n)|]
      % expected type  (Pos?)
  Pi_TCC1: OBLIGATION FORALL (n: nat): Pos?([|pi_lbn(n), pi_ubn(n)|]);

  % Subtype TCC generated (at line 75, column 24) for  cos_ub_lb
      % expected type  nznum
  tan_0_pi2_TCC1: OBLIGATION
    FORALL (n: nat, X: Interval, cos_ub_lb: real):
      cos_ub_lb = cos_ub(lb(X), n) IMPLIES
       (FORALL (cos_lb_ub: real):
          cos_ub_lb > 0 AND cos_lb_ub > 0 AND cos_lb_ub = cos_lb(ub(X), n)
           IMPLIES cos_ub_lb /= 0);

  % Subtype TCC generated (at line 75, column 50) for  cos_lb_ub
      % expected type  nznum
  tan_0_pi2_TCC2: OBLIGATION
    FORALL (n: nat, X: Interval, cos_ub_lb: real):
      cos_ub_lb = cos_ub(lb(X), n) IMPLIES
       (FORALL (cos_lb_ub: real):
          cos_ub_lb > 0 AND cos_lb_ub > 0 AND cos_lb_ub = cos_lb(ub(X), n)
           IMPLIES cos_lb_ub /= 0);

  % Subtype TCC generated (at line 84, column 24) for  cos_lb_lb
      % expected type  nznum
  tan_npi2_pi2_TCC1: OBLIGATION
    FORALL (n: nat, X: Interval, cos_lb_lb: real):
      cos_lb_lb = cos_lb(lb(X), n) IMPLIES
       (FORALL (cos_lb_ub: real):
          cos_lb_lb > 0 AND cos_lb_ub > 0 AND cos_lb_ub = cos_lb(ub(X), n)
           IMPLIES cos_lb_lb /= 0);

  % Subtype TCC generated (at line 84, column 50) for  cos_lb_ub
      % expected type  nznum
  tan_npi2_pi2_TCC2: OBLIGATION
    FORALL (n: nat, X: Interval, cos_lb_lb: real):
      cos_lb_lb = cos_lb(lb(X), n) IMPLIES
       (FORALL (cos_lb_ub: real):
          cos_lb_lb > 0 AND cos_lb_ub > 0 AND cos_lb_ub = cos_lb(ub(X), n)
           IMPLIES cos_lb_ub /= 0);

  % Judgement subtype TCC generated (at line 125, column 24) for  Pi(n)
      % expected type  ProperInterval
  Pi_proper: OBLIGATION FORALL (n): Proper?(Pi(n));

  % Subtype TCC generated (at line 214, column 8) for  x
      % expected type  (Tan?)
  tan_0_pi2_TCC3: OBLIGATION
    FORALL (X: Interval, n: nat, x: real):
      x ## X AND n >= 5 AND X << [|0, pi_lbn(n) / 2|] IMPLIES Tan?(x);

  % Subtype TCC generated (at line 220, column 8) for  x
      % expected type  (Tan?)
  tan_npi2_0_TCC1: OBLIGATION
    FORALL (X: Interval, n: nat, x: real):
      x ## X AND n >= 5 AND X << [|-pi_lbn(n) / 2, 0|] IMPLIES Tan?(x);

  % Subtype TCC generated (at line 227, column 8) for  x
      % expected type  (Tan?)
  tan_npi2_pi2_TCC3: OBLIGATION
    FORALL (X: Interval, n: nat, x: real):
      x ## X AND
       n >= 5 AND Zeroin?(X) AND X << [|-pi_lbn(n) / 2, pi_lbn(n) / 2|]
       IMPLIES Tan?(x);

  % Subtype TCC generated (at line 230, column 23) for  n + 5
      % expected type  nat
  TAN?_TCC1: OBLIGATION FORALL (n: nat): n + 5 >= 0;

  % Subtype TCC generated (at line 240, column 8) for  x
      % expected type  (Tan?)
  Tan_inclusion_TCC1: OBLIGATION
    FORALL (X: Interval, n: nat, x: real):
      x ## X AND TAN?(n)(X) IMPLIES Tan?(x);

  % Judgement subtype TCC generated (at line 270, column 4) for  Sin(n)(Xp)
      % expected type  ProperInterval
  Proper_Sin: OBLIGATION FORALL (Xp, n): Proper?(Sin(n)(Xp));

  % Judgement subtype TCC generated (at line 273, column 4) for  Cos(n)(Xp)
      % expected type  ProperInterval
  Proper_Cos: OBLIGATION FORALL (Xp, n): Proper?(Cos(n)(Xp));

  % Judgement subtype TCC generated (at line 276, column 4) for  Tan(n)(Xp)
      % expected type  ProperInterval
  Proper_Tan: OBLIGATION
    FORALL (n, Xp: ProperInterval | TAN?(n)(Xp)): Proper?(Tan(n)(Xp));

  % Judgement subtype TCC generated (at line 279, column 4) for  Atan(n)(Xp)
      % expected type  ProperInterval
  Proper_Atan: OBLIGATION FORALL (Xp, n): Proper?(Atan(n)(Xp));


body:
  interval_expr_trig : THEORY
  BEGIN

    IMPORTING interval_expr,
              interval_trig
    
    expr : VAR RealExpr
    n    : VAR nat

    pi_safe : [Unit->real] = LAMBDA(u:Unit) : pi

    Pi_Inclusion : JUDGEMENT
      Pi(n) HAS_TYPE (Includes?(pi_safe(unit)))

    PI_n(n): MACRO RealExpr = CONST(pi_safe,Pi(n))

    Sin_Inclusion : JUDGEMENT
      Sin(n) HAS_TYPE (Inclusion?(PreTrue,sin))

    Sin_Fundamental : JUDGEMENT
      Sin(n) HAS_TYPE (Fundamental?(PreTrue))

    SIN_n(n)(expr): MACRO RealExpr = FUN(PreTrue,sin,Sin(n),expr)

    Cos_Inclusion : JUDGEMENT
      Cos(n) HAS_TYPE (Inclusion?(PreTrue,cos))

    Cos_Fundamental : JUDGEMENT
      Cos(n) HAS_TYPE (Fundamental?(PreTrue))

    COS_n(n)(expr): MACRO RealExpr = FUN(PreTrue,cos,Cos(n),expr)

    tan_safe(x:real): real = IF Tan?(x) THEN tan(x) ELSE 0 ENDIF

    Tan_Inclusion : JUDGEMENT
      Tan(n) HAS_TYPE (Inclusion?(TAN?(n),tan_safe))

    Tan_Fundamental : JUDGEMENT
      Tan(n) HAS_TYPE (Fundamental?(TAN?(n)))

    TAN_Precondition : JUDGEMENT
      TAN?(n) HAS_TYPE (Precondition?)

    TAN_n(n)(expr): MACRO RealExpr = FUN(TAN?(n),tan_safe,Tan(n),expr)

    Atan_Inclusion : JUDGEMENT
      Atan(n) HAS_TYPE (Inclusion?(PreTrue,atan))

    Atan_Fundamental : JUDGEMENT
      Atan(n) HAS_TYPE (Fundamental?(PreTrue))

    ATAN_n(n)(expr): MACRO RealExpr = FUN(PreTrue,atan,Atan(n),expr)

  END interval_expr_trig

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

  % Judgement subtype TCC generated (at line 13, column 4) for  Pi(n)
      % expected type  (Includes?(pi_safe(unit)))
  Pi_Inclusion: OBLIGATION FORALL (n): Includes?(pi_safe(unit))(Pi(n));

  % Judgement subtype TCC generated (at line 18, column 4) for  Sin(n)
      % expected type  (Inclusion?(PreTrue, sin))
  Sin_Inclusion: OBLIGATION FORALL (n): Inclusion?(PreTrue, sin)(Sin(n));

  % Judgement subtype TCC generated (at line 21, column 4) for  Sin(n)
      % expected type  (Fundamental?(PreTrue))
  Sin_Fundamental: OBLIGATION FORALL (n): Fundamental?(PreTrue)(Sin(n));

  % Subtype TCC generated (at line 23, column 51) for  Sin(n)
      % expected type  {F: [Interval -> Interval] |
                     %          Inclusion?(PreTrue, sin)(F) AND
                     %           Fundamental?(PreTrue)(F)}
  SIN_n_TCC1: OBLIGATION
    FORALL (n: nat, expr: RealExpr):
      Inclusion?(PreTrue, sin)(Sin(n)) AND Fundamental?(PreTrue)(Sin(n));

  % Judgement subtype TCC generated (at line 26, column 4) for  Cos(n)
      % expected type  (Inclusion?(PreTrue, cos))
  Cos_Inclusion: OBLIGATION FORALL (n): Inclusion?(PreTrue, cos)(Cos(n));

  % Judgement subtype TCC generated (at line 29, column 4) for  Cos(n)
      % expected type  (Fundamental?(PreTrue))
  Cos_Fundamental: OBLIGATION FORALL (n): Fundamental?(PreTrue)(Cos(n));

  % Subtype TCC generated (at line 31, column 51) for  Cos(n)
      % expected type  {F: [Interval -> Interval] |
                     %          Inclusion?(PreTrue, cos)(F) AND
                     %           Fundamental?(PreTrue)(F)}
  COS_n_TCC1: OBLIGATION
    FORALL (n: nat, expr: RealExpr):
      Inclusion?(PreTrue, cos)(Cos(n)) AND Fundamental?(PreTrue)(Cos(n));

  % Judgement subtype TCC generated (at line 36, column 4) for  Tan(n)
      % expected type  (Inclusion?(TAN?(n), tan_safe))
  Tan_Inclusion: OBLIGATION FORALL (n): Inclusion?(TAN?(n), tan_safe)(Tan(n));

  % Judgement subtype TCC generated (at line 39, column 4) for  Tan(n)
      % expected type  (Fundamental?(TAN?(n)))
  Tan_Fundamental: OBLIGATION FORALL (n): Fundamental?(TAN?(n))(Tan(n));

  % Judgement subtype TCC generated (at line 42, column 4) for  TAN?(n)
      % expected type  (Precondition?)
  TAN_Precondition: OBLIGATION FORALL (n): Precondition?(TAN?(n));

  % Subtype TCC generated (at line 44, column 56) for  Tan(n)
      % expected type  {F: [Interval -> Interval] |
                     %          Inclusion?(TAN?(n), tan_safe)(F) AND
                     %           Fundamental?(TAN?(n))(F)}
  TAN_n_TCC1: OBLIGATION
    FORALL (n: nat, expr: RealExpr):
      Inclusion?(TAN?(n), tan_safe)(Tan(n)) AND Fundamental?(TAN?(n))(Tan(n));

  % Judgement subtype TCC generated (at line 47, column 4) for  Atan(n)
      % expected type  (Inclusion?(PreTrue, atan))
  Atan_Inclusion: OBLIGATION FORALL (n): Inclusion?(PreTrue, atan)(Atan(n));

  % Judgement subtype TCC generated (at line 50, column 4) for  Atan(n)
      % expected type  (Fundamental?(PreTrue))
  Atan_Fundamental: OBLIGATION FORALL (n): Fundamental?(PreTrue)(Atan(n));

  % Subtype TCC generated (at line 52, column 53) for  Atan(n)
      % expected type  {F: [Interval -> Interval] |
                     %          Inclusion?(PreTrue, atan)(F) AND
                     %           Fundamental?(PreTrue)(F)}
  ATAN_n_TCC1: OBLIGATION
    FORALL (n: nat, expr: RealExpr):
      Inclusion?(PreTrue, atan)(Atan(n)) AND Fundamental?(PreTrue)(Atan(n));


body:
  %% interval_sqrt.pvs

  interval_sqrt : THEORY
  BEGIN
    IMPORTING interval,
  	    reals@sqrt_approx

    X,Y : VAR Interval
    x,y : VAR real
    n   : VAR nat

    % Sqrt
    Sqrt(n)(X) : (NonNeg?) =
      IF Ge(X,0) THEN
        [|sqrt_lb(lb(X),n),sqrt_ub(ub(X),n)|]  
      ELSE EmptyInterval
      endif

    Sqrt_inclusion : LEMMA
      NonNeg?(X) AND 
      x ## X IMPLIES 
      sqrt(x) ## Sqrt(n)(X)

    Sqrt_fundamental : LEMMA
      NonNeg?(Y) AND Proper?(X) AND
      X << Y IMPLIES
      Sqrt(n)(X) << Sqrt(n)(Y)

    % Safe version of Sqrt
    IMPORTING safe_arith

    safe_Sqrt(n) : [Interval->Interval] = Safe1(NonNeg?,Sqrt(n))

    % Proper version of Sqrt
    IMPORTING proper_arith

    XNn : VAR NonNegInterval

    Proper_Sqrt : JUDGEMENT
      Sqrt(n)(XNn) HAS_TYPE NonNegInterval

    proper_Sqrt(n)(XNn): ProperInterval =
      Sqrt(n)(XNn)

  END interval_sqrt

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

  % Subtype TCC generated (at line 15, column 16) for  lb(X)
      % expected type  nnreal
  Sqrt_TCC1: OBLIGATION FORALL (X: Interval): Ge(X, 0) IMPLIES lb(X) >= 0;

  % Subtype TCC generated (at line 15, column 33) for  ub(X)
      % expected type  nnreal
  Sqrt_TCC2: OBLIGATION FORALL (X: Interval): Ge(X, 0) IMPLIES ub(X) >= 0;

  % Subtype TCC generated (at line 15, column 6) for
      % [|sqrt_lb(lb(X), n), sqrt_ub(ub(X), n)|]
      % expected type  (NonNeg?)
  Sqrt_TCC3: OBLIGATION
    FORALL (n: nat, X: Interval):
      Ge(X, 0) IMPLIES NonNeg?([|sqrt_lb(lb(X), n), sqrt_ub(ub(X), n)|]);

  % Subtype TCC generated (at line 16, column 9) for  EmptyInterval
      % expected type  (NonNeg?)
  Sqrt_TCC4: OBLIGATION
    FORALL (X: Interval): NOT Ge(X, 0) IMPLIES NonNeg?(EmptyInterval);

  % Subtype TCC generated (at line 22, column 9) for  x
      % expected type  nnx: nonneg_real
  Sqrt_inclusion_TCC1: OBLIGATION
    FORALL (X: Interval, x: real): x ## X AND NonNeg?(X) IMPLIES x >= 0;

  % Judgement subtype TCC generated (at line 40, column 4) for  Sqrt(n)(XNn)
      % expected type  NonNegInterval
  Proper_Sqrt: OBLIGATION
    FORALL (XNn, n): Proper?(Sqrt(n)(XNn)) AND NonNeg?(Sqrt(n)(XNn));


body:
  interval_expr_sqrt : THEORY
  BEGIN

    IMPORTING interval_expr,
              interval_sqrt
    
    expr : VAR RealExpr
     
    sqrt_safe(x:real): real = sqrt(max(x,0))

    nnx : VAR nnreal
    n   : VAR nat

    sqrt_is_safe : LEMMA
      sqrt_safe(nnx) = sqrt(nnx)
     
    Sqrt_Inclusion : JUDGEMENT
      Sqrt(n) HAS_TYPE (Inclusion?(NonNeg?,sqrt_safe))

    Sqrt_Fundamental : JUDGEMENT
      Sqrt(n) HAS_TYPE (Fundamental?(NonNeg?))

    SQRT_n(n)(expr): MACRO RealExpr = FUN(NonNeg?,sqrt_safe,Sqrt(n),expr)

  END interval_expr_sqrt

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

  % Judgement subtype TCC generated (at line 18, column 4) for  Sqrt(n)
      % expected type  (Inclusion?(NonNeg?, sqrt_safe))
  Sqrt_Inclusion: OBLIGATION
    FORALL (n): Inclusion?(NonNeg?, sqrt_safe)(Sqrt(n));

  % Judgement subtype TCC generated (at line 21, column 4) for  Sqrt(n)
      % expected type  (Fundamental?(NonNeg?))
  Sqrt_Fundamental: OBLIGATION FORALL (n): Fundamental?(NonNeg?)(Sqrt(n));

  % Subtype TCC generated (at line 23, column 58) for  Sqrt(n)
      % expected type  {F: [Interval -> Interval] |
                     %          Inclusion?(NonNeg?, sqrt_safe)(F) AND
                     %           Fundamental?(NonNeg?)(F)}
  SQRT_n_TCC1: OBLIGATION
    FORALL (n: nat, expr: RealExpr):
      Inclusion?(NonNeg?, sqrt_safe)(Sqrt(n)) AND
       Fundamental?(NonNeg?)(Sqrt(n));


body:
  %% interval_io.pvs

  interval_io : THEORY
  BEGIN

    IMPORTING interval

    interval2str(X:Interval): string =
      "[|"+lb(X)+","+ub(X)+"|]"

    tostr(i:Interval): string =
      interval2str(i)

    CONVERSION interval2str

  END interval_io


body:
  interval_bexpr : THEORY
  BEGIN

    IMPORTING interval_expr,
              structures@Maybe,
  	    reals@RealInt

    bexpr : VAR BoolExpr
    vs    : VAR Env
    b     : VAR bool
    box   : VAR Box
    pox   : VAR ProperBox 
    n     : VAR nat

    b2B(b) : BoolExpr =
      BCONST(b)

    CONVERSIOn b2B

    REL(rel:RealOrder)(e1,e2:RealExpr) : MACRO BoolExpr = 
      BREL(rel,e1,e2)

    EQ(e1,e2:RealExpr) : MACRO BoolExpr =
     BAND(BREL(<=,e1,e2),BREL(>=,e1,e2))

    POS?(e:RealExpr) : MACRO BoolExpr =
      BREL(>,e,0)

    BINCLUDEX(op:RealExpr,opi:Interval) : MACRO BoolExpr =
      BINCLUDES(op,opi)

    BINCLUDEX(op:RealExpr,ri:RealInt) : MACRO BoolExpr =
      IF ri`bounded_below AND ri`bounded_above THEN
        BAND(BREL(IF ri`closed_below THEN <= ELSE < ENDIF,
                  r2E(ri`lb),op),
             BREL(IF ri`closed_above THEN <= ELSE < ENDIF,
                  op,r2E(ri`ub)))
      ELSIF ri`bounded_below THEN
         BREL(IF ri`closed_below THEN <= ELSE < ENDIF,
              r2E(ri`lb),op)
      ELSIF ri`bounded_above THEN
         BREL(IF ri`closed_above THEN <= ELSE < ENDIF,
              op,r2E(ri`ub))
      ELSE b2B(TRUE)
      ENDIF

    beval(bexpr,vs,n) : RECURSIVE bool =
      IF bconst?(bexpr) THEN opb(bexpr)
      ELSIF bnot?(bexpr) THEN  
        NOT beval(bop(bexpr),vs,n)   
      ELSIF band?(bexpr) THEN  
        beval(bop1(bexpr),vs,n) AND beval(bop2(bexpr),vs,n)
      ELSIF bor?(bexpr) THEN  
        beval(bop1(bexpr),vs,n) OR beval(bop2(bexpr),vs,n)
      ELSIF bimplies?(bexpr) THEN  
        beval(bop1(bexpr),vs,n) IMPLIES beval(bop2(bexpr),vs,n)
      ELSIF brel?(bexpr) THEN 
        rel(bexpr)(eval(op1(bexpr),vs,n),eval(op2(bexpr),vs,n)) 
      ELSIF bincludes?(bexpr) THEN
        eval(op(bexpr),vs,n) ## opi(bexpr) 
      ELSIF bletin?(bexpr) THEN
        IF realexpr?(blet(bexpr)) THEN
          LET blet = eval(blet(bexpr),vs,n) IN
            beval(bin(bexpr),vs WITH [`n := blet],n+1)
        ELSE
          LET blet = beval(blet(bexpr),vs,n) IN
            beval(bin(bexpr),vs WITH [`n := IF blet THEN 1 ELSE -1 ENDIF],n+1)
        ENDIF 
      ELSIF beval(bif(bexpr),vs,n) THEN 
        beval(bthen(bexpr),vs,n) 
      ELSE beval(belse(bexpr),vs,n)
      ENDIF
    MEASURE bexpr BY <<

    BEval(bexpr,box) : RECURSIVE Maybe[bool] =
      IF bconst?(bexpr) THEN 
        Some(opb(bexpr))
      ELSIF bnot?(bexpr) THEN
        LET bop = BEval(bop(bexpr),box) IN
        IF none?(bop) THEN None
        ELSE Some(NOT val(bop))
        ENDIF
      ELSIF band?(bexpr) THEN 
        LET bop1 = BEval(bop1(bexpr),box) IN
        IF none?(bop1) OR val(bop1) THEN
          LET bop2 = BEval(bop2(bexpr),box) IN
          IF some?(bop2) AND val(bop2) THEN bop1
          ELSE bop2
          ENDIF
        ELSE bop1
        ENDIF
      ELSIF bor?(bexpr) THEN  
        LET bop1 = BEval(bop1(bexpr),box) IN
        IF none?(bop1) OR NOT val(bop1) THEN
          LET bop2 = BEval(bop2(bexpr),box) IN
          IF some?(bop2) AND (val(bop2) OR some?(bop1)) THEN bop2
          ELSE None
          ENDIF
        ELSE bop1
        ENDIF
      ELSIF bimplies?(bexpr) THEN  
        LET bop1 = BEval(bop1(bexpr),box) IN
        IF none?(bop1) OR val(bop1) THEN
          LET bop2 = BEval(bop2(bexpr),box) IN
          IF some?(bop2) AND (val(bop2) OR some?(bop1)) THEN bop2
          ELSE None
          ENDIF
        ELSE Some(TRUE)
        ENDIF
      ELSIF brel?(bexpr) THEN 
        LET op1 = Eval(op1(bexpr),box) IN
        IF Proper?(op1) THEN
          LET op2 = Eval(op2(bexpr),box) IN
          IF Proper?(op2) THEN
            IF rel(bexpr)(0,1) THEN % Case <= or <
              IF rel(bexpr)(op1`ub,op2`lb) THEN Some(TRUE)
              ELSIF neg_rel(rel(bexpr))(op1`lb,op2`ub) THEN Some(FALSE)
              ELSE None
              ENDIF
            ELSIF rel(bexpr)(op1`lb,op2`ub) THEN Some(TRUE) % Case >, >=
            ELSIF neg_rel(rel(bexpr))(op1`ub,op2`lb) THEN Some(FALSE)
            ELSE None
            ENDIF
          ELSE None
          ENDIF
        ELSE None
        ENDIF
      ELSIF bincludes?(bexpr) THEN
        LET op = Eval(op(bexpr),box) IN
        IF Proper?(op) THEN
          LET opi = opi(bexpr) IN
          IF Proper?(opi) THEN
            IF op << opi THEN Some(TRUE)
            ELSIF opi`ub < op`lb OR op`ub < opi`lb THEN Some(FALSE)
            ELSE None
            ENDIF
          ELSE 
            None
          ENDIF
        ELSE
          None
        ENDIF
      ELSIF bletin?(bexpr) THEN
        IF realexpr?(blet(bexpr)) THEN
          LET blet = Eval(blet(bexpr),box) IN
          IF Proper?(blet) THEN
            BEval(bin(bexpr),append(box,(: blet :)))
          ELSE None 
          ENDIF
        ELSE
          LET blet = BEval(blet(bexpr),box) IN
          BEval(bin(bexpr),
                append(box,(: IF none?(blet) THEN [|-1,1|] 
                              ELSIF val(blet) THEN [|1/2,1|]
                              ELSE [|-1,-1/2|] ENDIF :)))
        ENDIF 
      ELSE 
        LET bif = BEval(bif(bexpr),box) IN
        IF some?(bif) AND val(bif) THEN
          BEval(bthen(bexpr),box)
        ELSIF some?(bif) AND NOT val(bif) THEN
          BEval(belse(bexpr),box)
        ELSE 
          LET bt = BEval(bthen(bexpr),box) IN
          IF some?(bt) THEN
            LET be = BEval(belse(bexpr),box) IN
              IF some?(be) AND val(bt)=val(be) THEN bt
              ELSE None
              ENDIF
            ELSE None
          ENDIF
        ENDIF
      ENDIF
    MEASURE bexpr BY <<

    BEval_inclusion : THEOREM
      FORALL (box:Box,vs:(vars_in_box?(box)),bexpr) :
        LET be = BEval(bexpr,box) IN
        some?(be) IMPLIES
          val(be) = beval(bexpr,vs,length(box)) 

    BEval_inclusion_Proper : THEOREM
      LET be = BEval(bexpr,pox) IN
      some?(be) IMPLIES
        val(be) = FORALL(vs:(vars_in_box?(pox))): beval(bexpr,vs,length(pox)) 

    BEval_fundamental : THEOREM
      Inclusion?(pox,box) IMPLIES
        LET beb = BEval(bexpr,box),
            bep = BEval(bexpr,pox) IN
        some?(beb) IMPLIES 
        some?(bep) AND val(bep) = val(beb)

  END interval_bexpr

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

  % Well-founded TCC generated (at line 73, column 19) for
      % restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
      %     (<<)
      % for beval
  beval_TCC1: OBLIGATION
    well_founded?(LAMBDA (x: BoolExpr, y: BoolExpr):
                    restrict
                        [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr],
                         boolean]
                        (<<)(x, y));

  % Termination TCC generated (at line 50, column 10) for
      % beval(bop(bexpr), vs, n)
  beval_TCC2: OBLIGATION
    FORALL (bexpr: BoolExpr):
      bnot?(bexpr) AND NOT bconst?(bexpr) IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
           (<<)(bop(bexpr), bexpr);

  % Subtype TCC generated (at line 52, column 17) for  bexpr
      % expected type  {x: IntervalExpr | bimplies?(x) OR bor?(x) OR band?(x)}
  beval_TCC3: OBLIGATION
    FORALL (bexpr: BoolExpr):
      band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr) IMPLIES
       bimplies?(bexpr) OR bor?(bexpr) OR band?(bexpr);

  % Termination TCC generated (at line 52, column 6) for
      % beval(bop1(bexpr), vs, n)
  beval_TCC4: OBLIGATION
    FORALL (bexpr: BoolExpr):
      band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr) IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
           (<<)(bop1(bexpr), bexpr);

  % Termination TCC generated (at line 52, column 34) for
      % beval(bop2(bexpr), vs, n)
  beval_TCC5: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 bool],
            vs: Env, n: nat):
      v(bop1(bexpr), vs, n) AND
       band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
           (<<)(bop2(bexpr), bexpr);

  % Subtype TCC generated (at line 54, column 17) for  bexpr
      % expected type  {x: IntervalExpr | bimplies?(x) OR bor?(x) OR band?(x)}
  beval_TCC6: OBLIGATION
    FORALL (bexpr: BoolExpr):
      bor?(bexpr) AND
       NOT band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES bimplies?(bexpr) OR bor?(bexpr) OR band?(bexpr);

  % Termination TCC generated (at line 54, column 6) for
      % beval(bop1(bexpr), vs, n)
  beval_TCC7: OBLIGATION
    FORALL (bexpr: BoolExpr):
      bor?(bexpr) AND
       NOT band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
           (<<)(bop1(bexpr), bexpr);

  % Termination TCC generated (at line 54, column 33) for
      % beval(bop2(bexpr), vs, n)
  beval_TCC8: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 bool],
            vs: Env, n: nat):
           NOT v(bop1(bexpr), vs, n) AND bor?(bexpr) AND NOT band?(bexpr)
       AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
           (<<)(bop2(bexpr), bexpr);

  % Subtype TCC generated (at line 56, column 17) for  bexpr
      % expected type  {x: IntervalExpr | bimplies?(x) OR bor?(x) OR band?(x)}
  beval_TCC9: OBLIGATION
    FORALL (bexpr: BoolExpr):
           bimplies?(bexpr) AND NOT bor?(bexpr) AND NOT band?(bexpr)
       AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES bimplies?(bexpr) OR bor?(bexpr) OR band?(bexpr);

  % Termination TCC generated (at line 56, column 6) for
      % beval(bop1(bexpr), vs, n)
  beval_TCC10: OBLIGATION
    FORALL (bexpr: BoolExpr):
           bimplies?(bexpr) AND NOT bor?(bexpr) AND NOT band?(bexpr)
       AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
           (<<)(bop1(bexpr), bexpr);

  % Termination TCC generated (at line 56, column 38) for
      % beval(bop2(bexpr), vs, n)
  beval_TCC11: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 bool],
            vs: Env, n: nat):
           v(bop1(bexpr), vs, n) AND bimplies?(bexpr) AND NOT bor?(bexpr)
       AND NOT band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
           (<<)(bop2(bexpr), bexpr);

  % Subtype TCC generated (at line 58, column 26) for  bexpr
      % expected type  {x: IntervalExpr |
                     %              brel?(x) OR div?(x) OR mult?(x) OR sub?(x)
                     %           OR add?(x)}
  beval_TCC12: OBLIGATION
    FORALL (bexpr: BoolExpr):
           brel?(bexpr) AND NOT bimplies?(bexpr) AND NOT bor?(bexpr)
       AND NOT band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
           brel?(bexpr) OR div?(bexpr) OR mult?(bexpr) OR sub?(bexpr)
        OR add?(bexpr);

  % Subtype TCC generated (at line 60, column 14) for  bexpr
      % expected type  {x: IntervalExpr |
                     %              bincludes?(x) OR fun?(x) OR pow?(x)
                     %           OR sq?(x) OR neg?(x) OR abs?(x)}
  beval_TCC13: OBLIGATION
    FORALL (bexpr: BoolExpr):
           bincludes?(bexpr) AND NOT brel?(bexpr) AND NOT bimplies?(bexpr)
       AND NOT bor?(bexpr) AND NOT band?(bexpr) AND NOT bnot?(bexpr)
       AND NOT bconst?(bexpr)
       IMPLIES
           bincludes?(bexpr) OR fun?(bexpr) OR pow?(bexpr) OR sq?(bexpr)
        OR neg?(bexpr) OR abs?(bexpr);

  % Termination TCC generated (at line 64, column 10) for
      % beval(bin(bexpr), vs WITH [`n := blet], n + 1)
  beval_TCC14: OBLIGATION
    FORALL (bexpr: BoolExpr, vs: Env, n: nat):
           realexpr?(blet(bexpr)) AND bletin?(bexpr) AND NOT bincludes?(bexpr)
       AND NOT brel?(bexpr) AND NOT bimplies?(bexpr) AND NOT bor?(bexpr)
       AND NOT band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (blet: real):
          blet = eval(blet(bexpr), vs, n) IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
               (<<)(bin(bexpr), bexpr));

  % Subtype TCC generated (at line 63, column 24) for  blet(bexpr)
      % expected type  RealExpr
  beval_TCC15: OBLIGATION
    FORALL (bexpr: BoolExpr):
           realexpr?(blet(bexpr)) AND bletin?(bexpr) AND NOT bincludes?(bexpr)
       AND NOT brel?(bexpr) AND NOT bimplies?(bexpr) AND NOT bor?(bexpr)
       AND NOT band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
           const?(blet(bexpr)) OR varidx?(blet(bexpr)) OR add?(blet(bexpr))
        OR abs?(blet(bexpr)) OR neg?(blet(bexpr)) OR sub?(blet(bexpr))
        OR mult?(blet(bexpr)) OR sq?(blet(bexpr)) OR pow?(blet(bexpr))
        OR div?(blet(bexpr)) OR fun?(blet(bexpr)) OR letin?(blet(bexpr));

  % Termination TCC generated (at line 67, column 10) for
      % beval(bin(bexpr), vs WITH [`n := IF blet THEN 1 ELSE -1 ENDIF], n + 1)
  beval_TCC16: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 bool],
            vs: Env, n: nat):
           NOT realexpr?(blet(bexpr)) AND bletin?(bexpr)
       AND NOT bincludes?(bexpr) AND NOT brel?(bexpr) AND NOT bimplies?(bexpr)
       AND NOT bor?(bexpr) AND NOT band?(bexpr) AND NOT bnot?(bexpr)
       AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (blet: bool):
          blet = v(blet(bexpr), vs, n) IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
               (<<)(bin(bexpr), bexpr));

  % Subtype TCC generated (at line 66, column 25) for  blet(bexpr)
      % expected type  BoolExpr
  beval_TCC17: OBLIGATION
    FORALL (bexpr: BoolExpr):
           NOT realexpr?(blet(bexpr)) AND bletin?(bexpr)
       AND NOT bincludes?(bexpr) AND NOT brel?(bexpr) AND NOT bimplies?(bexpr)
       AND NOT bor?(bexpr) AND NOT band?(bexpr) AND NOT bnot?(bexpr)
       AND NOT bconst?(bexpr)
       IMPLIES
           bconst?(blet(bexpr)) OR bnot?(blet(bexpr)) OR band?(blet(bexpr))
        OR bor?(blet(bexpr)) OR bimplies?(blet(bexpr)) OR brel?(blet(bexpr))
        OR bincludes?(blet(bexpr)) OR bite?(blet(bexpr))
        OR bletin?(blet(bexpr));

  % Termination TCC generated (at line 66, column 19) for
      % beval(blet(bexpr), vs, n)
  beval_TCC18: OBLIGATION
    FORALL (bexpr: BoolExpr):
           NOT realexpr?(blet(bexpr)) AND bletin?(bexpr)
       AND NOT bincludes?(bexpr) AND NOT brel?(bexpr) AND NOT bimplies?(bexpr)
       AND NOT bor?(bexpr) AND NOT band?(bexpr) AND NOT bnot?(bexpr)
       AND NOT bconst?(bexpr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
           (<<)(blet(bexpr), bexpr);

  % Subtype TCC generated (at line 69, column 20) for  bexpr
      % expected type  (bite?)
  beval_TCC19: OBLIGATION
    FORALL (bexpr: BoolExpr):
           NOT bletin?(bexpr) AND NOT bincludes?(bexpr) AND NOT brel?(bexpr)
       AND NOT bimplies?(bexpr) AND NOT bor?(bexpr) AND NOT band?(bexpr)
       AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES bite?(bexpr);

  % Termination TCC generated (at line 69, column 10) for
      % beval(bif(bexpr), vs, n)
  beval_TCC20: OBLIGATION
    FORALL (bexpr: BoolExpr):
           NOT bletin?(bexpr) AND NOT bincludes?(bexpr) AND NOT brel?(bexpr)
       AND NOT bimplies?(bexpr) AND NOT bor?(bexpr) AND NOT band?(bexpr)
       AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
           (<<)(bif(bexpr), bexpr);

  % Termination TCC generated (at line 70, column 6) for
      % beval(bthen(bexpr), vs, n)
  beval_TCC21: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 bool],
            vs: Env, n: nat):
           v(bif(bexpr), vs, n) AND NOT bletin?(bexpr)
       AND NOT bincludes?(bexpr) AND NOT brel?(bexpr) AND NOT bimplies?(bexpr)
       AND NOT bor?(bexpr) AND NOT band?(bexpr) AND NOT bnot?(bexpr)
       AND NOT bconst?(bexpr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
           (<<)(bthen(bexpr), bexpr);

  % Termination TCC generated (at line 71, column 9) for
      % beval(belse(bexpr), vs, n)
  beval_TCC22: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Env, nat] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 bool],
            vs: Env, n: nat):
           NOT v(bif(bexpr), vs, n) AND NOT bletin?(bexpr)
       AND NOT bincludes?(bexpr) AND NOT brel?(bexpr) AND NOT bimplies?(bexpr)
       AND NOT bor?(bexpr) AND NOT band?(bexpr) AND NOT bnot?(bexpr)
       AND NOT bconst?(bexpr)
       IMPLIES
       restrict[[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
           (<<)(belse(bexpr), bexpr);

  % Subtype TCC generated (at line 81, column 24) for  bop
      % expected type  (some?[boolean])
  BEval_TCC1: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
      bnot?(bexpr) AND NOT bconst?(bexpr) IMPLIES
       (FORALL (bop: Maybe[bool]):
          NOT none?(bop) AND bop = v(bop(bexpr), box) IMPLIES
           some?[boolean](bop));

  % Subtype TCC generated (at line 85, column 28) for  bop1
      % expected type  (some?[boolean])
  BEval_TCC2: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
      band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr) IMPLIES
       (FORALL (bop1: Maybe[bool]):
          NOT none?(bop1) AND bop1 = v(bop1(bexpr), box) IMPLIES
           some?[boolean](bop1));

  % Termination TCC generated (at line 86, column 19) for
      % BEval(bop2(bexpr), box)
  BEval_TCC3: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
      band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr) IMPLIES
       (FORALL (bop1: Maybe[bool]):
          (none?(bop1) OR val(bop1)) AND bop1 = v(bop1(bexpr), box) IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
               (<<)(bop2(bexpr), bexpr));

  % Subtype TCC generated (at line 94, column 32) for  bop1
      % expected type  (some?[boolean])
  BEval_TCC4: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
      bor?(bexpr) AND
       NOT band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (bop1: Maybe[bool]):
          NOT none?(bop1) AND bop1 = v(bop1(bexpr), box) IMPLIES
           some?[boolean](bop1));

  % Termination TCC generated (at line 95, column 19) for
      % BEval(bop2(bexpr), box)
  BEval_TCC5: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
      bor?(bexpr) AND
       NOT band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (bop1: Maybe[bool]):
          (none?(bop1) OR NOT val(bop1)) AND bop1 = v(bop1(bexpr), box)
           IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
               (<<)(bop2(bexpr), bexpr));

  % Subtype TCC generated (at line 103, column 28) for  bop1
      % expected type  (some?[boolean])
  BEval_TCC6: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
           bimplies?(bexpr) AND NOT bor?(bexpr) AND NOT band?(bexpr)
       AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (bop1: Maybe[bool]):
          NOT none?(bop1) AND bop1 = v(bop1(bexpr), box) IMPLIES
           some?[boolean](bop1));

  % Termination TCC generated (at line 104, column 19) for
      % BEval(bop2(bexpr), box)
  BEval_TCC7: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
           bimplies?(bexpr) AND NOT bor?(bexpr) AND NOT band?(bexpr)
       AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (bop1: Maybe[bool]):
          (none?(bop1) OR val(bop1)) AND bop1 = v(bop1(bexpr), box) IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
               (<<)(bop2(bexpr), bexpr));

  % Termination TCC generated (at line 147, column 10) for
      % BEval(bin(bexpr), append(box, (: blet :)))
  BEval_TCC8: OBLIGATION
    FORALL (bexpr: BoolExpr, box: Box):
           realexpr?(blet(bexpr)) AND bletin?(bexpr) AND NOT bincludes?(bexpr)
       AND NOT brel?(bexpr) AND NOT bimplies?(bexpr) AND NOT bor?(bexpr)
       AND NOT band?(bexpr) AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (blet: Interval):
          Proper?(blet) AND blet = Eval(blet(bexpr), box) IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
               (<<)(bin(bexpr), bexpr));

  % Subtype TCC generated (at line 154, column 38) for  blet
      % expected type  (some?[boolean])
  BEval_TCC9: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
           NOT realexpr?(blet(bexpr)) AND bletin?(bexpr)
       AND NOT bincludes?(bexpr) AND NOT brel?(bexpr) AND NOT bimplies?(bexpr)
       AND NOT bor?(bexpr) AND NOT band?(bexpr) AND NOT bnot?(bexpr)
       AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (blet: Maybe[bool]):
          NOT none?(blet) AND blet = v(blet(bexpr), box) IMPLIES
           some?[boolean](blet));

  % Termination TCC generated (at line 152, column 8) for
      % BEval(bin(bexpr),
      %       append(box,
      %              (: IF none?(blet) THEN [|-1, 1|]
      %                 ELSIF val(blet) THEN [|1 / 2, 1|]
      %                 ELSE [|-1, -1 / 2|]
      %                 ENDIF :)))
  BEval_TCC10: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
           NOT realexpr?(blet(bexpr)) AND bletin?(bexpr)
       AND NOT bincludes?(bexpr) AND NOT brel?(bexpr) AND NOT bimplies?(bexpr)
       AND NOT bor?(bexpr) AND NOT band?(bexpr) AND NOT bnot?(bexpr)
       AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (blet: Maybe[bool]):
          blet = v(blet(bexpr), box) IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
               (<<)(bin(bexpr), bexpr));

  % Termination TCC generated (at line 160, column 8) for
      % BEval(bthen(bexpr), box)
  BEval_TCC11: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
           NOT bletin?(bexpr) AND NOT bincludes?(bexpr) AND NOT brel?(bexpr)
       AND NOT bimplies?(bexpr) AND NOT bor?(bexpr) AND NOT band?(bexpr)
       AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (bif: Maybe[bool]):
          some?(bif) AND val(bif) AND bif = v(bif(bexpr), box) IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
               (<<)(bthen(bexpr), bexpr));

  % Termination TCC generated (at line 162, column 8) for
      % BEval(belse(bexpr), box)
  BEval_TCC12: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
           NOT bletin?(bexpr) AND NOT bincludes?(bexpr) AND NOT brel?(bexpr)
       AND NOT bimplies?(bexpr) AND NOT bor?(bexpr) AND NOT band?(bexpr)
       AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (bif: Maybe[bool]):
          some?(bif) AND
           NOT val(bif) AND
            NOT (some?(bif) AND val(bif)) AND bif = v(bif(bexpr), box)
           IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
               (<<)(belse(bexpr), bexpr));

  % Termination TCC generated (at line 164, column 17) for
      % BEval(bthen(bexpr), box)
  BEval_TCC13: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
           NOT bletin?(bexpr) AND NOT bincludes?(bexpr) AND NOT brel?(bexpr)
       AND NOT bimplies?(bexpr) AND NOT bor?(bexpr) AND NOT band?(bexpr)
       AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (bif: Maybe[bool]):
          NOT (some?(bif) AND NOT val(bif)) AND
           NOT (some?(bif) AND val(bif)) AND bif = v(bif(bexpr), box)
           IMPLIES
           restrict
               [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr], boolean]
               (<<)(bthen(bexpr), bexpr));

  % Termination TCC generated (at line 166, column 19) for
      % BEval(belse(bexpr), box)
  BEval_TCC14: OBLIGATION
    FORALL (bexpr: BoolExpr,
            v:
              [{z: [BoolExpr, Box] |
                        restrict
                            [[IntervalExpr, IntervalExpr],
                             [BoolExpr, BoolExpr], boolean]
                            (<<)(z`1, bexpr)} ->
                 Maybe[bool]],
            box: Box):
           NOT bletin?(bexpr) AND NOT bincludes?(bexpr) AND NOT brel?(bexpr)
       AND NOT bimplies?(bexpr) AND NOT bor?(bexpr) AND NOT band?(bexpr)
       AND NOT bnot?(bexpr) AND NOT bconst?(bexpr)
       IMPLIES
       (FORALL (bif: Maybe[bool]):
          NOT (some?(bif) AND NOT val(bif)) AND
           NOT (some?(bif) AND val(bif)) AND bif = v(bif(bexpr), box)
           IMPLIES
           (FORALL (bt: Maybe[bool]):
              some?(bt) AND bt = v(bthen(bexpr), box) IMPLIES
               restrict
                   [[IntervalExpr, IntervalExpr], [BoolExpr, BoolExpr],
                    boolean]
                   (<<)(belse(bexpr), bexpr)));


body:
  interval_bandb : THEORY
  BEGIN

    IMPORTING interval_bexpr,
              structures@array2list[real],
              structures@Maybe,
              reals@real_orders

    IntervalOutput : TYPE = [#
      answer    : Maybe[bool],
      counterex : {l:list[real] | cons?(l) IMPLIES some?(answer) AND NOT(val(answer)) }
    #]

    IMPORTING structures@branch_and_bound[BoolExpr,IntervalOutput,ProperBox,nat]

    v         : VAR nat
    maxdepth  : VAR nat
    dir,
    eamd      : VAR bool
    expr      : VAR BoolExpr
    box       : VAR ProperBox
    dirvar    : VAR DirVar
    dirvars   : VAR DirVarStack
    M,M1,M2   : VAR IntervalOutput
    out       : VAR Output
    select    : VAR DirVarSelector
    acc       : VAR IntervalOutput

    evaluate(box,expr) : IntervalOutput = 
      LET bet  = BEval(expr,box),
          bef  = IF none?(bet) THEN
                   LET bm = BEval(expr,Midbox(box)) IN
                   IF some?(bm) AND NOT val(bm) THEN bm
                   ELSE bet
                   ENDIF
                 ELSE bet
                 ENDIF IN
      (#
        answer    := bef,
        counterex := IF some?(bef) AND NOT val(bef) THEN 
                       map(LAMBDA(i:Interval):midpoint(i))(box) 
                     ELSE null ENDIF
       #)

    branch(v,expr) : [BoolExpr,BoolExpr] = (expr,expr)

    denorm(dirvar,M) : IntervalOutput = M

    combine(v,M1,M2) : IntervalOutput = (#
      answer    := IF (some?(M1`answer) AND NOT val(M1`answer)) OR
                      (some?(M2`answer) AND NOT val(M2`answer)) THEN
  		   Some(FALSE)
                   ELSIF some?(M1`answer) AND some?(M2`answer) THEN
                     Some(TRUE)
                   ELSE None
                   ENDIF,
      counterex := IF cons?(M1`counterex) THEN M1`counterex ELSE M2`counterex ENDIF
    #)

    prune_chk(dirvars,acc,M) : bool = FALSE

    % Exit when true or false
    le_chk(M) : bool = some?(M`answer) 

    %% eamd (exit at maxdepth) must be set to false when looking for a countexample
    ge_chk(eamd,maxdepth)(dirvars,acc,M) : bool = 
      (eamd AND length(dirvars) >= maxdepth) OR
      some?(M`answer) AND NOT val(M`answer)

    accumulate(acc,M) : IntervalOutput = 
      combine(0,acc,M)

    subdivide(v,box) : [ProperBox,ProperBox] = split(v,box)

    max_rec(n:posnat,m:real,v:below(n),
                   i:subrange(1,n),b:Box | n = length(b)+i) : RECURSIVE below(n) =
      IF null?(b) THEN v
      ELSE LET mm = size(car(b)) IN
             IF mm > m THEN max_rec(n,mm,i,i+1,cdr(b)) 
             ELSE max_rec(n,m,v,i+1,cdr(b))
             ENDIF
      ENDIF
    MEASURE b BY <<

    max_aux(box) : nat =
      IF length(box) <= 1 THEN 0
      ELSE max_rec(length(box),size(car(box)),0,1,cdr(box))
      ENDIF

    dir_max(dir)(dirvars,acc,box,expr) : DirVar = 
      (dir,max_aux(box))

    alt_max(dirvars,acc,box,expr) : DirVar = 
      (even?(length(dirvars)),max_aux(box))

    altvar(dirvars,box) : nat =
      IF length(box) <= 1 THEN 0
      ELSE mod(length(dirvars),length(box))
      ENDIF

    dir_alt(dir)(dirvars,acc,box,expr) : DirVar = 
      (dir,altvar(dirvars,box))

    alt_alt(dirvars,acc,box,expr) : DirVar = 
      (even?(length(dirvars)),altvar(dirvars,box))

    interval(maxdepth,select,eamd)(expr,box) : Output =
      b_and_b_id(evaluate,branch,subdivide,denorm,combine,prune_chk,le_chk,ge_chk(eamd,maxdepth),
                 select,accumulate,maxdepth,expr,box)

    sound?(box,expr,M) : bool = 
      some?(M`answer)  IMPLIES
        ((val(M`answer) = FORALL (vs:(vars_in_box?(box))): beval(expr,vs,length(box))) AND
         (cons?(counterex(M)) IMPLIES 
            LET vs = list2array(0)(counterex(M)) IN
             vars_in_box?(box)(vs) AND NOT beval(expr,vs,length(box))))

    interval_soundness : THEOREM
      sound?(box,expr,interval(maxdepth,select,eamd)(expr,box)`ans)

  END interval_bandb

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

  % Subtype TCC generated (at line 40, column 19) for
      % IF some?(bef) AND NOT val(bef)
      %   THEN map(LAMBDA (i: Interval): midpoint(i))(box)
      % ELSE null
      % ENDIF
      % expected type  {l: list[real] |
                     %          cons?(l) IMPLIES
                     %           some?(bef) AND NOT (val(bef))}
  evaluate_TCC1: OBLIGATION
    FORALL (box: ProperBox, expr: BoolExpr, bet: Maybe[bool]):
      bet = BEval(expr, box) IMPLIES
       (FORALL (bef: Maybe[boolean]):
          bef =
           IF none?(bet)
             THEN LET bm = BEval(expr, Midbox(box)) IN
                    IF some?(bm) AND NOT val(bm) THEN bm ELSE bet ENDIF
           ELSE bet
           ENDIF
           IMPLIES
           cons?[real]
               (IF some?[boolean](bef) AND NOT val[boolean](bef)
                  THEN map[Interval, real]
                           (LAMBDA (i: Interval): midpoint(i))(box)
                ELSE null[real]
                ENDIF)
            IMPLIES some?[boolean](bef) AND NOT (val[boolean](bef)));

  % Subtype TCC generated (at line 57, column 17) for
      % IF cons?(M1`counterex) THEN M1`counterex ELSE M2`counterex ENDIF
      % expected type  {l: list[real] |
                     %          cons?(l) IMPLIES
                     %           some?(IF (some?(M1`answer)
                     %                     AND
                     %                     NOT val(M1`answer))
                     %                    OR
                     %                    (some?(M2`answer)
                     %                     AND
                     %                     NOT val(M2`answer))
                     %                 THEN Some(FALSE)
                     %                 ELSIF some?(M1`answer)
                     %                       AND
                     %                       some?(M2`answer)
                     %                 THEN Some(TRUE)
                     %                 ELSE None
                     %                 ENDIF)
                     %            AND
                     %            NOT IF (some?(M1`answer)
                     %                    AND
                     %                    NOT val(M1`answer))
                     %                   OR
                     %                   (some?(M2`answer)
                     %                    AND
                     %                    NOT val(M2`answer))
                     %                THEN FALSE
                     %                ELSE IF some?(M1`answer)
                     %                        AND
                     %                        some?(M2`answer)
                     %                     THEN TRUE
                     %                     ELSE val(None)
                     %                     ENDIF
                     %                ENDIF}
  combine_TCC1: OBLIGATION
    FORALL (M1: IntervalOutput, M2: IntervalOutput):
      cons?[real]
          (IF cons?[real](M1`counterex) THEN M1`counterex
           ELSE M2`counterex
           ENDIF)
       IMPLIES
       some?[boolean]
           (IF (some?[boolean](M1`answer) AND NOT val[boolean](M1`answer)) OR
                (some?[boolean](M2`answer) AND NOT val[boolean](M2`answer))
              THEN Some[boolean](FALSE)
            ELSIF some?[boolean](M1`answer) AND some?[boolean](M2`answer)
              THEN Some[boolean](TRUE)
            ELSE None[boolean]
            ENDIF)
        AND
        NOT IF (some?[boolean](M1`answer) AND NOT val[boolean](M1`answer)) OR
                (some?[boolean](M2`answer) AND NOT val[boolean](M2`answer))
              THEN FALSE
            ELSE IF some?[boolean](M1`answer) AND some?[boolean](M2`answer)
                   THEN TRUE
                 ELSE val[boolean](None[boolean])
                 ENDIF
            ENDIF;

  % Subtype TCC generated (at line 83, column 10) for  b
      % expected type  {b_1: Box | n = i + length(b_1)}
  max_rec_TCC1: OBLIGATION
    FORALL (n: posnat, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      n = i + length[Interval](b);

  % Subtype TCC generated (at line 79, column 39) for  i
      % expected type  below(n)
  max_rec_TCC2: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real): mm > m AND mm = size(car(b)) IMPLIES i < n);

  % Subtype TCC generated (at line 79, column 41) for  i + 1
      % expected type  subrange(1, n)
  max_rec_TCC3: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          mm > m AND mm = size(car(b)) IMPLIES 1 <= i + 1 AND i + 1 <= n);

  % Subtype TCC generated (at line 79, column 49) for  b
      % expected type  (cons?[Interval])
  max_rec_TCC4: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          mm > m AND mm = size(car(b)) IMPLIES cons?[Interval](b));

  % Subtype TCC generated (at line 79, column 45) for  cdr(b)
      % expected type  {b: Box | n = 1 + i + length(b)}
  max_rec_TCC5: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          mm > m AND mm = size(car(b)) IMPLIES
           n = 1 + i + length[Interval](cdr[Interval](b)));

  % Termination TCC generated (at line 79, column 26) for
      % max_rec(n, mm, i, i + 1, cdr(b))
  max_rec_TCC6: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          mm > m AND mm = size(car(b)) IMPLIES
           <<[Interval](cdr[Interval](b), b));

  % Subtype TCC generated (at line 80, column 30) for  i + 1
      % expected type  subrange(1, n)
  max_rec_TCC7: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          NOT mm > m AND mm = size(car(b)) IMPLIES 1 <= i + 1 AND i + 1 <= n);

  % Subtype TCC generated (at line 80, column 38) for  b
      % expected type  (cons?[Interval])
  max_rec_TCC8: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          NOT mm > m AND mm = size(car(b)) IMPLIES cons?[Interval](b));

  % Subtype TCC generated (at line 80, column 34) for  cdr(b)
      % expected type  {b: Box | n = 1 + i + length(b)}
  max_rec_TCC9: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          NOT mm > m AND mm = size(car(b)) IMPLIES
           n = 1 + i + length[Interval](cdr[Interval](b)));

  % Termination TCC generated (at line 80, column 16) for
      % max_rec(n, m, v, i + 1, cdr(b))
  max_rec_TCC10: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          NOT mm > m AND mm = size(car(b)) IMPLIES
           <<[Interval](cdr[Interval](b), b));

  % Subtype TCC generated (at line 78, column 27) for  b
      % expected type  (cons?[Interval])
  max_rec_TCC11: OBLIGATION
    FORALL (n: posnat, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES cons?[Interval](b);

  % Subtype TCC generated (at line 87, column 17) for  length(box)
      % expected type  posnat
  max_aux_TCC1: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES length[Interval](box) > 0;

  % Subtype TCC generated (at line 87, column 38) for  box
      % expected type  (cons?[Interval])
  max_aux_TCC2: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES cons?[Interval](box);

  % Subtype TCC generated (at line 87, column 44) for  0
      % expected type  below(length(box))
  max_aux_TCC3: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES 0 < length[Interval](box);

  % Subtype TCC generated (at line 87, column 46) for  1
      % expected type  subrange(1, length(box))
  max_aux_TCC4: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES 1 <= 1 AND 1 <= length[Interval](box);

  % Subtype TCC generated (at line 87, column 48) for  cdr(box)
      % expected type  {b: Box | length(box) = 1 + length(b)}
  max_aux_TCC5: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES
       length[Interval](box) = 1 + length[Interval](cdr[Interval](box));

  % Subtype TCC generated (at line 98, column 29) for  length(box)
      % expected type  nonzero_integer
  altvar_TCC1: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES length[Interval](box) /= 0;

  % Subtype TCC generated (at line 98, column 9) for
      % mod(length(dirvars), length(box))
      % expected type  nat
  altvar_TCC2: OBLIGATION
    FORALL (dirvars: DirVarStack[BoolExpr, IntervalOutput, ProperBox, nat],
            box: ProperBox):
      NOT length(box) <= 1 IMPLIES
       mod(length(dirvars), length[Interval](box)) >= 0;


body:
  numerical_bandb : THEORY
  BEGIN

    IMPORTING safe_arith,
              interval_expr,
              structures@array2list[real],
              structures@Maybe,
              reals@real_orders

    IntervalMinMax : TYPE = [#
      mm     : Interval,
      lb_max : real,
      lb_box : ProperBox,
      ub_min : real,
      ub_box : ProperBox
    #]

    IMPORTING structures@branch_and_bound[RealExpr,IntervalMinMax,ProperBox,nat]

    v         : VAR nat
    maxdepth  : VAR nat
    expr      : VAR RealExpr
    box       : VAR ProperBox
    dirvar    : VAR DirVar
    dirvars   : VAR DirVarStack
    M,M1,M2   : VAR IntervalMinMax
    out       : VAR Output
    precision : VAR posreal
    prune,ge  : VAR ExitPred
    le        : VAR LocalExitPred
    select    : VAR DirVarSelector
    acc       : VAR IntervalMinMax

    evaluate(box,expr) : IntervalMinMax = 
      LET X   = Eval(expr,box),
          Lb  = Lbbox(box),
          Ub  = Ubbox(box),   
          P1  = Eval(expr,Lb),
          P2  = Eval(expr,Ub),
          (lb_max,lb_box) = IF ub(P1) < ub(P2) THEN (ub(P1),Lb) ELSE (ub(P2),Ub) ENDIF,
          (ub_min,ub_box) = IF lb(P1) > lb(P2) THEN (lb(P1),Lb) ELSE (lb(P2),Ub) ENDIF IN
      (# mm     := X,
         lb_max := lb_max, 
         lb_box := lb_box,
         ub_min := ub_min,
         ub_box := ub_box 
      #)

    branch(v,expr) : [RealExpr,RealExpr] = (expr,expr)
    denorm(dirvar,M) : IntervalMinMax = M

    combine(v,M1,M2) : IntervalMinMax = 
      LET M_lb = IF M1`lb_max < M2`lb_max THEN M1 ELSE M2 ENDIF,
          M_ub = IF M1`ub_min > M2`ub_min THEN M1 ELSE M2 ENDIF IN
      (# mm     := Safe2(Union)(mm(M1),mm(M2)),
         lb_max := M_lb`lb_max,
         lb_box := M_lb`lb_box,
         ub_min := M_ub`ub_min,
         ub_box := M_ub`ub_box #)

    % <= 0 : min
    % >= 0 : max
    min_or_max: VAR int

    prune_mm(min_or_max)(dirvars,acc,M) : bool = 
      (min_or_max <= 0 IMPLIES acc`lb_max <= lb(M`mm)) AND
      (min_or_max >= 0 IMPLIES ub(M`mm) <= acc`ub_min)
   
    le_mm(min_or_max,precision)(M) : bool =  
      (min_or_max <= 0 IMPLIES LET lb = M`lb_max - lb(M`mm) IN lb <= precision) AND
      (min_or_max >= 0 IMPLIES LET ub = ub(M`mm) - M`ub_min IN ub <= precision) 

    ge_mm(dirvars,acc,M) : bool = EmptyInterval?(M`mm)

    accumulate(acc,M) : IntervalMinMax = 
      combine(0,acc,M)

    subdivide(v,box) : [ProperBox,ProperBox] = split(v,box)

    VarSel : TYPE = [# thisvar: nat, lb: real, ub: real, lbub: Interval #]

    var_varsel(expr:RealExpr,box:ProperBox,both:bool,
               Mb:listn[Interval](length(box)))
              (v:below(length(box))) : VarSel =
      LET X    = nth(box,v),
      	lb   = IF both THEN lb(Eval(expr,setnth(Mb,v,LAMBDA(x:Interval): [| lb(X) |]))) ELSE 0 ENDIF,
      	ub   = IF both THEN ub(Eval(expr,setnth(Mb,v,LAMBDA(x:Interval): [| ub(X) |]))) ELSE 0 ENDIF,
  	lbub = Eval(expr,setnth(Mb,v,LAMBDA(x:Interval):X)) IN
      (# thisvar  := v,
         lb       := lb,
         ub       := ub,
         lbub     := lbub
       #)

    max_varsel(vs1,vs2:VarSel) : VarSel =
      IF size(vs1`lbub) > size(vs2`lbub) THEN vs1
      ELSE vs2
      ENDIF

    IMPORTING structures@for_iterate

    both, dir : VAR bool

    mindir_maxvar_aux(both:bool)(dirvars,acc,box,expr) : DirVar =
      IF length(box) <= 1 THEN left(0)
      ELSE 
        LET Mb = Midbox(box), 
            vs = iterate_left(0,length(box)-1,var_varsel(expr,box,both,Mb),max_varsel) IN
        (vs`lb < vs`ub,vs`thisvar)
      ENDIF

    mindir_maxvar(dirvars,acc,box,expr) : DirVar =
      mindir_maxvar_aux(TRUE)(dirvars,acc,box,expr)  
      
    maxdir_maxvar(dirvars,acc,box,expr) : DirVar =
      LET (dir,v) = mindir_maxvar(dirvars,acc,box,expr) IN
      (NOT dir,v)    

    altdir_maxvar(dirvars,acc,box,expr) : DirVar =
      LET (dir,v) = mindir_maxvar_aux(FALSE)(dirvars,acc,box,expr) IN
        (even?(length(dirvars)),v)

    dir_maxvar(dir)(dirvars,acc,box,expr) : DirVar =
      LET v = mindir_maxvar_aux(FALSE)(dirvars,acc,box,expr)`2 IN
        (dir,v)

    max_rec(n:posnat,m:real,v:below(n),
                   i:subrange(1,n),b:Box | n = length(b)+i) : RECURSIVE below(n) =
      IF null?(b) THEN v
      ELSE LET mm = size(car(b)) IN
             IF mm > m THEN max_rec(n,mm,i,i+1,cdr(b)) 
             ELSE max_rec(n,m,v,i+1,cdr(b))
             ENDIF
      ENDIF
    MEASURE b BY <<

    max_aux(box) : nat =
      IF length(box) <= 1 THEN 0
      ELSE max_rec(length(box),size(car(box)),0,1,cdr(box))
      ENDIF

    dir_max(dir)(dirvars,acc,box,expr) : DirVar = 
      (dir,max_aux(box))

    alt_max(dirvars,acc,box,expr) : DirVar = 
      (even?(length(dirvars)),max_aux(box))

    altvar(dirvars,box) : nat =
      IF length(box) <= 1 THEN 0
      ELSE mod(length(dirvars),length(box))
      ENDIF

    dir_alt(dir)(dirvars,acc,box,expr) : DirVar = 
      (dir,altvar(dirvars,box))

    alt_alt(dirvars,acc,box,expr) : DirVar = 
      (even?(length(dirvars)),altvar(dirvars,box))

    interval_minmax(maxdepth,select,le,ge,prune)(expr,box) : Output =
      b_and_b_id(evaluate,branch,subdivide,denorm,combine,prune,le,ge,
                 select,accumulate,maxdepth,expr,box)

    VVars(dirvars,box) : nat =
      IF length(box) <= 1 THEN 0
      ELSE mod(length(dirvars),4)
      ENDIF

    VMZ(dirvars,acc,box,expr) : DirVar = 
      (True,VVars(dirvars,box))

    sound?(box,expr,M) : bool = 
      Proper?(M`mm) IMPLIES
        (FORALL (vs:(vars_in_box?(box))): eval(expr,vs,length(box)) ## M`mm) AND
        Inclusion?(M`lb_box,box) AND
        Inclusion?(M`ub_box,box) AND
        (FORALL (vs:(vars_in_box?(M`lb_box))): eval(expr,vs,length(box)) <= M`lb_max) AND
        (FORALL (vs:(vars_in_box?(M`ub_box))): eval(expr,vs,length(box)) >= M`ub_min) 

    interval_minmax_soundness : THEOREM
      sound?(box,expr,interval_minmax(maxdepth,select,le,ge,prune)(expr,box)`ans)

    numerical(maxdepth,precision,select,min_or_max)(expr,box) : Output =
      interval_minmax(maxdepth,select,le_mm(min_or_max,precision),ge_mm,prune_mm(min_or_max))(expr,box)

    numerical_soundness : THEOREM
      sound?(box,expr,numerical(maxdepth,precision,select,min_or_max)(expr,box)`ans)

  END numerical_bandb

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

  % Subtype TCC generated (at line 44, column 17) for  lb_box
      % expected type  ProperBox
  evaluate_TCC1: OBLIGATION
    FORALL (box: ProperBox, expr: RealExpr, X: Interval):
      X = Eval(expr, box) IMPLIES
       (FORALL (Lb: listn[Interval](length[Interval](box))):
          Lb = Lbbox(box) IMPLIES
           (FORALL (Ub: listn[Interval](length[Interval](box))):
              Ub = Ubbox(box) IMPLIES
               (FORALL (P1: Interval):
                  P1 = Eval(expr, Lb) IMPLIES
                   (FORALL (P2: Interval):
                      P2 = Eval(expr, Ub) IMPLIES
                       (FORALL (lb_max: real,
                                lb_box:
                                  listn[Interval](length[Interval](box))):
                          lb_box =
                           IF ub(P1) < ub(P2) THEN (ub(P1), Lb)
                           ELSE (ub(P2), Ub)
                           ENDIF`2
                           AND
                           lb_max =
                            IF ub(P1) < ub(P2) THEN (ub(P1), Lb)
                            ELSE (ub(P2), Ub)
                            ENDIF`1
                           IMPLIES
                           (FORALL (ub_min: real,
                                    ub_box:
                                      listn
                                      [Interval](length[Interval](box))):
                              ub_box =
                               IF lb(P1) > lb(P2) THEN (lb(P1), Lb)
                               ELSE (lb(P2), Ub)
                               ENDIF`2
                               AND
                               ub_min =
                                IF lb(P1) > lb(P2) THEN (lb(P1), Lb)
                                ELSE (lb(P2), Ub)
                                ENDIF`1
                               IMPLIES ProperBox?(lb_box)))))));

  % Subtype TCC generated (at line 46, column 17) for  ub_box
      % expected type  ProperBox
  evaluate_TCC2: OBLIGATION
    FORALL (box: ProperBox, expr: RealExpr, X: Interval):
      X = Eval(expr, box) IMPLIES
       (FORALL (Lb: listn[Interval](length[Interval](box))):
          Lb = Lbbox(box) IMPLIES
           (FORALL (Ub: listn[Interval](length[Interval](box))):
              Ub = Ubbox(box) IMPLIES
               (FORALL (P1: Interval):
                  P1 = Eval(expr, Lb) IMPLIES
                   (FORALL (P2: Interval):
                      P2 = Eval(expr, Ub) IMPLIES
                       (FORALL (lb_max: real,
                                lb_box:
                                  listn[Interval](length[Interval](box))):
                          lb_box =
                           IF ub(P1) < ub(P2) THEN (ub(P1), Lb)
                           ELSE (ub(P2), Ub)
                           ENDIF`2
                           AND
                           lb_max =
                            IF ub(P1) < ub(P2) THEN (ub(P1), Lb)
                            ELSE (ub(P2), Ub)
                            ENDIF`1
                           IMPLIES
                           (FORALL (ub_min: real,
                                    ub_box:
                                      listn
                                      [Interval](length[Interval](box))):
                              ub_box =
                               IF lb(P1) > lb(P2) THEN (lb(P1), Lb)
                               ELSE (lb(P2), Ub)
                               ENDIF`2
                               AND
                               ub_min =
                                IF lb(P1) > lb(P2) THEN (lb(P1), Lb)
                                ELSE (lb(P2), Ub)
                                ENDIF`1
                               IMPLIES ProperBox?(ub_box)))))));

  % Subtype TCC generated (at line 108, column 30) for  length(box) - 1
      % expected type  upfrom(0)
  mindir_maxvar_aux_TCC1: OBLIGATION
    FORALL (acc: IntervalMinMax, box: ProperBox, expr: RealExpr):
      NOT length(box) <= 1 IMPLIES
       (FORALL (Mb: listn[Interval](length[Interval](box))):
          Mb = Midbox(box) IMPLIES length[Interval](box) - 1 >= 0);

  % Subtype TCC generated (at line 108, column 44) for
      % var_varsel(expr, box, both, Mb)
      % expected type  IterateBody[VarSel](0, length(box) - 1)
  mindir_maxvar_aux_TCC2: OBLIGATION
    FORALL (acc: IntervalMinMax, box: ProperBox, expr: RealExpr):
      NOT length(box) <= 1 IMPLIES
       (FORALL (Mb: listn[Interval](length[Interval](box))):
          Mb = Midbox(box) IMPLIES
           (FORALL (x: int):
              x >= 0 AND x < length[Interval](box) IFF
               0 <= x AND x <= length[Interval](box) - 1));

  % Subtype TCC generated (at line 135, column 10) for  b
      % expected type  {b_1: Box | n = i + length(b_1)}
  max_rec_TCC1: OBLIGATION
    FORALL (n: posnat, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      n = i + length[Interval](b);

  % Subtype TCC generated (at line 131, column 39) for  i
      % expected type  below(n)
  max_rec_TCC2: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real): mm > m AND mm = size(car(b)) IMPLIES i < n);

  % Subtype TCC generated (at line 131, column 41) for  i + 1
      % expected type  subrange(1, n)
  max_rec_TCC3: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          mm > m AND mm = size(car(b)) IMPLIES 1 <= i + 1 AND i + 1 <= n);

  % Subtype TCC generated (at line 131, column 49) for  b
      % expected type  (cons?[Interval])
  max_rec_TCC4: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          mm > m AND mm = size(car(b)) IMPLIES cons?[Interval](b));

  % Subtype TCC generated (at line 131, column 45) for  cdr(b)
      % expected type  {b: Box | n = 1 + i + length(b)}
  max_rec_TCC5: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          mm > m AND mm = size(car(b)) IMPLIES
           n = 1 + i + length[Interval](cdr[Interval](b)));

  % Termination TCC generated (at line 131, column 26) for
      % max_rec(n, mm, i, i + 1, cdr(b))
  max_rec_TCC6: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          mm > m AND mm = size(car(b)) IMPLIES
           <<[Interval](cdr[Interval](b), b));

  % Subtype TCC generated (at line 132, column 30) for  i + 1
      % expected type  subrange(1, n)
  max_rec_TCC7: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          NOT mm > m AND mm = size(car(b)) IMPLIES 1 <= i + 1 AND i + 1 <= n);

  % Subtype TCC generated (at line 132, column 38) for  b
      % expected type  (cons?[Interval])
  max_rec_TCC8: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          NOT mm > m AND mm = size(car(b)) IMPLIES cons?[Interval](b));

  % Subtype TCC generated (at line 132, column 34) for  cdr(b)
      % expected type  {b: Box | n = 1 + i + length(b)}
  max_rec_TCC9: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          NOT mm > m AND mm = size(car(b)) IMPLIES
           n = 1 + i + length[Interval](cdr[Interval](b)));

  % Termination TCC generated (at line 132, column 16) for
      % max_rec(n, m, v, i + 1, cdr(b))
  max_rec_TCC10: OBLIGATION
    FORALL (n: posnat, m: real, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES
       (FORALL (mm: real):
          NOT mm > m AND mm = size(car(b)) IMPLIES
           <<[Interval](cdr[Interval](b), b));

  % Subtype TCC generated (at line 130, column 27) for  b
      % expected type  (cons?[Interval])
  max_rec_TCC11: OBLIGATION
    FORALL (n: posnat, v: below(n), i: subrange(1, n),
            b: Box | n = length[Interval](b) + i):
      NOT null?(b) IMPLIES cons?[Interval](b);

  % Subtype TCC generated (at line 139, column 17) for  length(box)
      % expected type  posnat
  max_aux_TCC1: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES length[Interval](box) > 0;

  % Subtype TCC generated (at line 139, column 38) for  box
      % expected type  (cons?[Interval])
  max_aux_TCC2: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES cons?[Interval](box);

  % Subtype TCC generated (at line 139, column 44) for  0
      % expected type  below(length(box))
  max_aux_TCC3: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES 0 < length[Interval](box);

  % Subtype TCC generated (at line 139, column 46) for  1
      % expected type  subrange(1, length(box))
  max_aux_TCC4: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES 1 <= 1 AND 1 <= length[Interval](box);

  % Subtype TCC generated (at line 139, column 48) for  cdr(box)
      % expected type  {b: Box | length(box) = 1 + length(b)}
  max_aux_TCC5: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES
       length[Interval](box) = 1 + length[Interval](cdr[Interval](box));

  % Subtype TCC generated (at line 150, column 29) for  length(box)
      % expected type  nonzero_integer
  altvar_TCC1: OBLIGATION
    FORALL (box: ProperBox):
      NOT length(box) <= 1 IMPLIES length[Interval](box) /= 0;

  % Subtype TCC generated (at line 150, column 9) for
      % mod(length(dirvars), length(box))
      % expected type  nat
  altvar_TCC2: OBLIGATION
    FORALL (dirvars: DirVarStack[RealExpr, IntervalMinMax, ProperBox, nat],
            box: ProperBox):
      NOT length(box) <= 1 IMPLIES
       mod(length(dirvars), length[Interval](box)) >= 0;


body:
  simple_bandb : THEORY
  BEGIN

    IMPORTING safe_arith,
              interval_expr,
              structures@array2list[real],
              structures@Maybe

    IMPORTING structures@branch_and_bound[RealExpr,Interval,ProperBox,nat]

    v         : VAR nat
    maxdepth  : VAR nat
    expr      : VAR RealExpr
    box       : VAR ProperBox
    dirvar    : VAR DirVar
    dirvars   : VAR DirVarStack
    ans,
    ans1,ans2 : VAR Interval
    acc       : VAR Interval

    evaluate(box,expr) : Interval = Eval(expr,box)
    branch(v,expr) : [RealExpr,RealExpr] = (expr,expr)
    subdivide(v,box) : [ProperBox,ProperBox] = split(v,box)
    denorm(dirvar,ans) : Interval = ans
    combine(v,ans1,ans2) : Interval = Safe2(Union)(ans1,ans2)
    accumulate(acc,ans) : Interval = combine(0,acc,ans)

    prune(dirvars,acc,ans) : bool = false
    le(ans) : bool = false
    ge(dirvars,acc,ans) : bool = EmptyInterval?(ans)

    altvar(dirvars,acc,box,expr) : DirVar =
      IF null?(box) THEN 
        (FALSE,0)
      ELSE
        (FALSE,mod(length(dirvars),length(box)))
      ENDIF

    simple_interval(maxdepth,expr,box) : Output =
      b_and_b_id(evaluate,branch,subdivide,denorm,combine,prune,
                 le,ge,altvar,accumulate,maxdepth,expr,box)

    sound?(box,expr,ans) : bool = 
      Proper?(ans) IMPLIES
        FORALL (vs:(vars_in_box?(box))): eval(expr,vs,length(box)) ## ans

    simple_interval_soundness : THEOREM
      sound?(box,expr,simple_interval(maxdepth,expr,box)`ans)

    %% As its name implies, the strategy simple-numerical used in the example 
    %% below is a highly simplified version of the strategy called numerical.
    %% This simpler version is included in this development for pedagogical reasons.

    x : VAR real

    simple_test : LEMMA
      x ## [|0,1|] IMPLIES
      x*(1-x) ## [| 0,0.251 |]

  %|- simple_test : PROOF
  %|- (then (skeep) (simple-numerical (! 1 1) :maxdepth 9))
  %|- QED


  END simple_bandb

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

  % Subtype TCC generated (at line 36, column 33) for  length(box)
      % expected type  nonzero_integer
  altvar_TCC1: OBLIGATION
    FORALL (box: ProperBox, expr: RealExpr):
      NOT null?(box) IMPLIES length[Interval](box) /= 0;

  % Subtype TCC generated (at line 36, column 13) for
      % mod(length(dirvars), length(box))
      % expected type  nat
  altvar_TCC2: OBLIGATION
    FORALL (dirvars: DirVarStack[RealExpr, Interval, ProperBox, nat],
            box: ProperBox, expr: RealExpr):
      NOT null?(box) IMPLIES mod(length(dirvars), length[Interval](box)) >= 0;


body:
  % Interval strategies for rational expressions

  strategies4Q : THEORY
  BEGIN

    IMPORTING simple_bandb,
              numerical_bandb,
              interval_bandb,
              interval_io,
  	    interval_expr_sqrt,
   	    reals@abs_lems

    %% This constant is used by the strategies to check if all the required theories 
    %% have been imported in the current context

    IntervalStrategies4Q__ : Unit

  END strategies4Q


body:
  % Interval strategies for all expression
  strategies : THEORY
  BEGIN

    IMPORTING strategies4Q,
              interval_expr_trig,
  	    interval_expr_lnexp

    %% This constant is used by the strategies to check if all the required theories 
    %% have been imported in the current context

    IntervalStrategies__ : Unit 

  END strategies


body:
  %% examples.pvs
  %% 
  %% These examples deal with arbitrary real-valued expressions, for that reason the theory 
  %% imports strategies instead of strategies4Q.
  %%  

  examples : theory
  BEGIN

    IMPORTING strategies

    x,y : var real

    %%%% Examples of numerical

    sqrt23 : LEMMA
      sqrt(2)+sqrt(3)-pi ## [|0.002, 0.007|]
  %% The expression (! 1 1) refers to formula 1, 1st term: sqrt(2)+sqrt(3)-pi
  %|- sqrt23 : PROOF
  %|- (numerical (! 1 1) :verbose? t)
  %|- QED

    sin6sqrt2 : LEMMA
      sin(6*pi/180)+sqrt(2) ## [|1.517, 1.520|]
  %% The expression (! 1 1) refers to formula 1, 1st term: sin(6*pi/180)+sqrt(2)
  %|- sin6sqrt2 : PROOF (numerical (! 1 1)) QED

    %%%% Examples of interval

    sqrtx3 : LEMMA
      x ## [|1,2|] IMPLIES
      sqrt(x)+sqrt(3) <  pi + 0.01
  %|- sqrtx3 : PROOF (interval) QED

    g : posreal = 9.8 % Gravitational acceleration [m/s^2]
    
    v     : VAR posreal % Ground speed [knots]
    phi   : VAR {deg:real| Tan?(pi*deg/180)} % Bank angle [deg]

    %% Turn rate [deg/sec]
    tr(v,phi) : MACRO real =
      LET PI = pi IN
        ((180*g)/(PI*v*0.514) )*tan((PI*phi)/180)

    tr_250_35 : LEMMA
      LET tr = tr(250,35) IN
        3 <= tr AND tr <= 3.1
  %|- tr_250_35 : PROOF (interval) QED

    tr_200_250_abs_35 : LEMMA
      abs(phi) <= 35 AND 
      v   ## [| 200, 250 |] IMPLIES
      abs(tr(v,phi)) <= 3.825
  %|- tr_200_250_abs_35 : PROOF
  %|- (then (skeep) (interval))
  %|- QED

    G(x|x < 1): MACRO real = 3*x/2 - ln(1-x)

    X : posreal = 0.5828
    
    A_and_S : LEMMA
      G(X) > 0
  %|- A_and_S : PROOF
  %|- (interval)
  %|- QED

    common_point: LEMMA EXISTS (x,y,theta,r:real): 
      abs(x) <= 1 AND abs(y) <= 1 AND abs(theta) <= 3 AND r ## [|0,1|] AND
      x^2 + y^2 < 3-2*sqrt(2)+0.1 AND (x-(1+r*cos(theta)))^2 + (y-(1+r*sin(theta)))^2 < 0.1
  %|- common_point : PROOF (interval :verbose? t) QED

    r(x) : MACRO real = x - (11184811/33554432) * x^3 
                          - (13421773/67108864) * x^5

    ex(x) : MACRO real = atan(x) - r(x)

    atan_implementation : LEMMA
      abs(x) <= 0.33 IMPLIES
      abs(ex(x)) <= 2^-9
  %|- atan_implementation : PROOF (interval) QED

  % The following problems were suggested by Behzad Akbarpour

    epsilon : real = 0.1

    ex1_ba : LEMMA
      x ## [|0,1|] IMPLIES
      x - x^2  - epsilon <= ln (1 + x)
  %|- ex1_ba : PROOF (interval) QED

    ex2_ba : LEMMA
      x ## [|0,0.9|] IMPLIES
      ln(1-x) - epsilon <= -x 
  %|- ex2_ba : PROOF (interval) QED

    ex3_ba : LEMMA
      x ## [|0,1/2|] IMPLIES
      -x - 2*sq(x) - epsilon <= ln(1 - x)
  %|- ex3_ba : PROOF (interval) QED

    ex4_ba : LEMMA
      x ## [|0,1|] IMPLIES
      abs(ln(1+x) - x) - epsilon <= sq(x)
  %|- ex4_ba : PROOF (interval) QED

    ex5_ba : LEMMA
      x ## [|-1/2,0|] IMPLIES
      abs(ln(1+x) - x) - epsilon <= 2*sq(x)
  %|- ex5_ba : PROOF (interval) QED

    ex6_ba : LEMMA
      x ## [|0,1|] IMPLIES
      exp(x) - epsilon <= 1 + x + sq(x)
  %|- ex6_ba : PROOF (interval) QED

    ex7_ba : LEMMA
      x ## [|0,1|] IMPLIES
      exp(x-x^2) - epsilon <= 1 + x
  %|- ex7_ba : PROOF (interval) QED

  %% The following examples are taken from
  %% Formal verification of analog designs using MetiTarski
  %% William Denman, Behzad Akbarpour, Sofiene Tahar, Mohamed H. Zaki, and Lawrence C. Paulson,
  %% FMCAD 2009

    Tunnel_3_IL : LEMMA
      FORALL (x:real | x ## [| 0, 2.39*10^(-9) |]):
      -0.0059 - 0.000016*exp(-2.55*10^8*x) + 0.031*exp(-5.49*10^7*x) <= 0.03
  %|- Tunnel_3_IL : PROOF (interval) QED

    Tunnel_3_IL_LU : LEMMA
      FORALL (x:real | x ## [| 0, 8.17*10^(-8) |]):
      -0.0006427443996*exp(-2.559889987*(10^8*x)) - 0.07600397043 + 
       0.1443470449*exp(-4.211001275*(10^6*x)) 
        ## [| 0, 0.08 |]
  %|- Tunnel_3_IL_LU : PROOF (interval) QED

  END examples

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

  % Subtype TCC generated (at line 32, column 9) for  x
      % expected type  nnx: nonneg_real
  sqrtx3_TCC1: OBLIGATION FORALL (x: real): x ## [|1, 2|] IMPLIES x >= 0;

  % Subtype TCC generated (at line 43, column 34) for  (PI * phi) / 180
      % expected type  (Tan?)
  tr_TCC1: OBLIGATION
    FORALL (phi: {deg: real | Tan?(pi * deg / 180)},
            PI: {r: posreal | pi_lb < r AND r < pi_ub}):
      PI = pi IMPLIES Tan?((PI * phi) / 180);

  % Subtype TCC generated (at line 43, column 34) for  (PI * 35) / 180
      % expected type  (Tan?)
  tr_250_35_TCC1: OBLIGATION
    FORALL (PI: {r: posreal | pi_lb < r AND r < pi_ub}):
      PI = pi IMPLIES Tan?((PI * 35) / 180);

  % Subtype TCC generated (at line 58, column 38) for  1 - x
      % expected type  posreal
  G_TCC1: OBLIGATION FORALL (x: real | x < 1): 1 - x >= 0 AND 1 - x > 0;

  % Subtype TCC generated (at line 63, column 6) for  X
      % expected type  {x | x < 1}
  A_and_S_TCC1: OBLIGATION X < 1;

  % Subtype TCC generated (at line 58, column 38) for  1 - X
      % expected type  posreal
  A_and_S_TCC2: OBLIGATION 1 - X >= 0 AND 1 - X > 0;

  % Subtype TCC generated (at line 70, column 6) for  2
      % expected type  {i: int | x /= 0 OR i >= 0}
  common_point_TCC1: OBLIGATION
    FORALL (x, y, theta, r: real):
      r ## [|0, 1|] AND abs(theta) <= 3 AND abs(y) <= 1 AND abs(x) <= 1
       IMPLIES x /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 70, column 12) for  2
      % expected type  {i: int | y /= 0 OR i >= 0}
  common_point_TCC2: OBLIGATION
    FORALL (x, y, theta, r: real):
      r ## [|0, 1|] AND abs(theta) <= 3 AND abs(y) <= 1 AND abs(x) <= 1
       IMPLIES y /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 70, column 57) for  2
      % expected type  {i: int | NOT x - 1 - r * cos(theta) = 0 OR i >= 0}
  common_point_TCC3: OBLIGATION
    FORALL (x, y, theta, r: real):
           x ^ 2 + y ^ 2 < 3 - 2 * sqrt(2) + 0.1 AND r ## [|0, 1|]
       AND abs(theta) <= 3 AND abs(y) <= 1 AND abs(x) <= 1
       IMPLIES NOT x - 1 - r * cos(theta) = 0 OR 2 >= 0;

  % Subtype TCC generated (at line 70, column 82) for  2
      % expected type  {i: int | NOT y - 1 - r * sin(theta) = 0 OR i >= 0}
  common_point_TCC4: OBLIGATION
    FORALL (x, y, theta, r: real):
           x ^ 2 + y ^ 2 < 3 - 2 * sqrt(2) + 0.1 AND r ## [|0, 1|]
       AND abs(theta) <= 3 AND abs(y) <= 1 AND abs(x) <= 1
       IMPLIES NOT y - 1 - r * sin(theta) = 0 OR 2 >= 0;

  % Subtype TCC generated (at line 73, column 50) for  3
      % expected type  {i: int | x /= 0 OR i >= 0}
  r_TCC1: OBLIGATION FORALL (x: real): x /= 0 OR 3 >= 0;

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

  % Subtype TCC generated (at line 89, column 10) for  2
      % expected type  {i: int | x /= 0 OR i >= 0}
  ex1_ba_TCC1: OBLIGATION
    FORALL (x: real): x ## [|0, 1|] IMPLIES x /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 89, column 30) for  1 + x
      % expected type  posreal
  ex1_ba_TCC2: OBLIGATION
    FORALL (x: real): x ## [|0, 1|] IMPLIES 1 + x >= 0 AND 1 + x > 0;

  % Subtype TCC generated (at line 94, column 7) for  1 - x
      % expected type  posreal
  ex2_ba_TCC1: OBLIGATION
    FORALL (x: real): x ## [|0, 0.9|] IMPLIES 1 - x >= 0 AND 1 - x > 0;

  % Subtype TCC generated (at line 99, column 33) for  1 - x
      % expected type  posreal
  ex3_ba_TCC1: OBLIGATION
    FORALL (x: real): x ## [|0, 1 / 2|] IMPLIES 1 - x >= 0 AND 1 - x > 0;

  % Subtype TCC generated (at line 109, column 11) for  1 + x
      % expected type  posreal
  ex5_ba_TCC1: OBLIGATION
    FORALL (x: real): x ## [|-1 / 2, 0|] IMPLIES 1 + x >= 0 AND 1 + x > 0;


body:
  %% examples4Q.pvs
  %% 
  %% These examples only deal with rational expressions, for that reason the theory 
  %% just imports strategies4Q. 
  %%  

  examples4Q : theory
  BEGIN

    IMPORTING strategies4Q

    x,y : var real

    %%%% Examples of numerical

    zero_to_one_quarter : LEMMA
      x ## [|0,1|] IMPLIES
      x*(1-x) ## [|0.0000, 0.2501|]
  %% The expression (! 1 1) refers to formula 1, 1st term, i.e., x*(1-x)
  %|- zero_to_one_quarter : PROOF
  %|- (then (skeep) (numerical (! 1 1) :precision 4 :maxdepth 20 :verbose? t))
  %|- QED

    x0,x1,x2,x3,x4,x5,x6,x7 : VAR real

    Heart(x0,x1,x2,x3,x4,x5,x6,x7): MACRO real = 
      -x0*x5^3+3*x0*x5*x6^2-x2*x6^3+3*x2*x6*x5^2-x1*x4^3+3*x1*x4*x7^2-x3*x7^3+3*x3*x7*x4^2-0.9563453

    hdp_mm: LEMMA 
      -0.1 <= x0 AND x0 <= 0.4 AND 
       0.4 <= x1  AND x1 <= 1 AND 
      -0.7 <= x2 AND x2 <= -0.4 AND 
      -0.7 <= x3 AND x3 <= 0.4 AND 
       0.1 <= x4  AND x4 <= 0.2 AND
      -0.1 <= x5 AND x5 <= 0.2 AND 
      -0.3 <= x6 AND x6 <= 1.1 AND 
      -1.1 <= x7 AND x7 <= -0.3 IMPLIES 
       Heart(x0,x1,x2,x3,x4,x5,x6,x7) ## [|-1.852, 1.518|]

  %% The expression (! 1 1) refers to formula 1, 1st term, i.e., polynomial Heart
  %|- hdp_mm : PROOF
  %|- (then (skeep) (numerical (! 1 1) :verbose? t))
  %|- QED

    %%%% Examples of interval

    hdp_minmax: LEMMA 
      -0.1 <= x0 AND x0 <= 0.4 AND 
       0.4 <= x1  AND x1 <= 1 AND 
      -0.7 <= x2 AND x2 <= -0.4 AND 
      -0.7 <= x3 AND x3 <= 0.4 AND 
       0.1 <= x4  AND x4 <= 0.2 AND
      -0.1 <= x5 AND x5 <= 0.2 AND 
      -0.3 <= x6 AND x6 <= 1.1 AND 
      -1.1 <= x7 AND x7 <= -0.3 IMPLIES 
       Heart(x0,x1,x2,x3,x4,x5,x6,x7) ## [| -1.76, 1.46 |]

  %|- hdp_minmax : PROOF
  %|- (then (skeep) (interval))
  %|- QED

    common_point: LEMMA 
      EXISTS (x,y,z:real): abs(x) <= 10 AND abs(y) <= 10 AND z ## [|0,1/2|] AND 
        LET x2 = x^2,
            y2 = y^2 IN
          x2-2*x+1+y2-2*y+1<1 AND x2 + y2 < 3-2*y+0.01

  %|- common_point : PROOF (interval :verbose? t) QED

     Eps : posreal = 0.0001

     simple_ite : LEMMA
       FORALL (x:real | x ## [| 0, 10 |]) :
         IF x <= 1 THEN sq(x) <= x+Eps
         ELSE sq(x) >= x-Eps
         ENDIF

  %|- simple_ite : PROOF
  %|- (interval)
  %|- QED


  END examples4Q

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

  % Subtype TCC generated (at line 27, column 11) for  3
      % expected type  {i: int | x5 /= 0 OR i >= 0}
  Heart_TCC1: OBLIGATION FORALL (x5: real): x5 /= 0 OR 3 >= 0;

  % Subtype TCC generated (at line 27, column 24) for  2
      % expected type  {i: int | x6 /= 0 OR i >= 0}
  Heart_TCC2: OBLIGATION FORALL (x6: real): x6 /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 27, column 32) for  3
      % expected type  {i: int | x6 /= 0 OR i >= 0}
  hdp_mm_TCC1: OBLIGATION
    FORALL (x0, x1, x2, x3, x4, x5, x6, x7: real):
           x7 <= -0.3 AND -1.1 <= x7 AND x6 <= 1.1 AND -0.3 <= x6
       AND x5 <= 0.2 AND -0.1 <= x5 AND x4 <= 0.2 AND 0.1 <= x4 AND x3 <= 0.4
       AND -0.7 <= x3 AND x2 <= -0.4 AND -0.7 <= x2 AND x1 <= 1 AND 0.4 <= x1
       AND x0 <= 0.4 AND -0.1 <= x0
       IMPLIES x6 /= 0 OR 3 >= 0;

  % Subtype TCC generated (at line 27, column 45) for  2
      % expected type  {i: int | x5 /= 0 OR i >= 0}
  hdp_mm_TCC2: OBLIGATION
    FORALL (x0, x1, x2, x3, x4, x5, x6, x7: real):
           x7 <= -0.3 AND -1.1 <= x7 AND x6 <= 1.1 AND -0.3 <= x6
       AND x5 <= 0.2 AND -0.1 <= x5 AND x4 <= 0.2 AND 0.1 <= x4 AND x3 <= 0.4
       AND -0.7 <= x3 AND x2 <= -0.4 AND -0.7 <= x2 AND x1 <= 1 AND 0.4 <= x1
       AND x0 <= 0.4 AND -0.1 <= x0
       IMPLIES x5 /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 27, column 53) for  3
      % expected type  {i: int | x4 /= 0 OR i >= 0}
  hdp_mm_TCC3: OBLIGATION
    FORALL (x0, x1, x2, x3, x4, x5, x6, x7: real):
           x7 <= -0.3 AND -1.1 <= x7 AND x6 <= 1.1 AND -0.3 <= x6
       AND x5 <= 0.2 AND -0.1 <= x5 AND x4 <= 0.2 AND 0.1 <= x4 AND x3 <= 0.4
       AND -0.7 <= x3 AND x2 <= -0.4 AND -0.7 <= x2 AND x1 <= 1 AND 0.4 <= x1
       AND x0 <= 0.4 AND -0.1 <= x0
       IMPLIES x4 /= 0 OR 3 >= 0;

  % Subtype TCC generated (at line 27, column 66) for  2
      % expected type  {i: int | x7 /= 0 OR i >= 0}
  hdp_mm_TCC4: OBLIGATION
    FORALL (x0, x1, x2, x3, x4, x5, x6, x7: real):
           x7 <= -0.3 AND -1.1 <= x7 AND x6 <= 1.1 AND -0.3 <= x6
       AND x5 <= 0.2 AND -0.1 <= x5 AND x4 <= 0.2 AND 0.1 <= x4 AND x3 <= 0.4
       AND -0.7 <= x3 AND x2 <= -0.4 AND -0.7 <= x2 AND x1 <= 1 AND 0.4 <= x1
       AND x0 <= 0.4 AND -0.1 <= x0
       IMPLIES x7 /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 27, column 74) for  3
      % expected type  {i: int | x7 /= 0 OR i >= 0}
  hdp_mm_TCC5: OBLIGATION
    FORALL (x0, x1, x2, x3, x4, x5, x6, x7: real):
           x7 <= -0.3 AND -1.1 <= x7 AND x6 <= 1.1 AND -0.3 <= x6
       AND x5 <= 0.2 AND -0.1 <= x5 AND x4 <= 0.2 AND 0.1 <= x4 AND x3 <= 0.4
       AND -0.7 <= x3 AND x2 <= -0.4 AND -0.7 <= x2 AND x1 <= 1 AND 0.4 <= x1
       AND x0 <= 0.4 AND -0.1 <= x0
       IMPLIES x7 /= 0 OR 3 >= 0;

  % Subtype TCC generated (at line 27, column 87) for  2
      % expected type  {i: int | x4 /= 0 OR i >= 0}
  hdp_mm_TCC6: OBLIGATION
    FORALL (x0, x1, x2, x3, x4, x5, x6, x7: real):
           x7 <= -0.3 AND -1.1 <= x7 AND x6 <= 1.1 AND -0.3 <= x6
       AND x5 <= 0.2 AND -0.1 <= x5 AND x4 <= 0.2 AND 0.1 <= x4 AND x3 <= 0.4
       AND -0.7 <= x3 AND x2 <= -0.4 AND -0.7 <= x2 AND x1 <= 1 AND 0.4 <= x1
       AND x0 <= 0.4 AND -0.1 <= x0
       IMPLIES x4 /= 0 OR 2 >= 0;

  % Subtype TCC generated (at line 65, column 17) for  2
      % expected type  {i: int | y /= 0 OR i >= 0}
  common_point_TCC1: OBLIGATION
    FORALL (x, y, z: real):
      z ## [|0, 1 / 2|] AND abs(y) <= 10 AND abs(x) <= 10 IMPLIES
       (FORALL (x2: real): x2 = x ^ 2 IMPLIES y /= 0 OR 2 >= 0);


body:
  %% interval_deriv.pvs

  interval_deriv[(IMPORTING interval) X:StrictInterval]: THEORY
  BEGIN

    IMPORTING interval_sqrt,
              interval_trig,
  	    interval_lnexp

    Xt : TYPE = IntervalType(X)

    IMPORTING analysis@deriv_domain

    deriv_domain_Xt: LEMMA deriv_domain?[Xt[X]]

    IMPORTING interval,analysis@derivatives[Xt],analysis@nth_derivatives[Xt], 
              analysis@sqrt_derivative,trig_fnd@sincos,trig_fnd@atan

    Diff?(f:[Xt->real]) : bool = 
      derivable?(f)

    D(f:(Diff?)) : [Xt->real] =
      deriv(f)

    Diffn?(n:nat)(f:[Xt->real]) : RECURSIVE bool =
      n=0 OR (Diff?(f) AND Diffn?(n-1)(D(f)))
    MEASURE n

    Diffn_derivn : LEMMA
      FORALL (n:nat,f:[Xt->real]):
        Diffn?(n)(f) = derivable_n_times?(f,n)

    Dn(n:nat,f:(Diffn?(n))) : RECURSIVE [Xt->real] =
      if   n=0 then f
      else Dn(n-1,D(f))
      endif
    MEASURE n

    Dn_nderiv : LEMMA
      FORALL (n:nat,f:(Diffn?(n))):
        Dn(n,f) = nderiv(n,f)

    t   : VAR Xt
    a   : VAR real
    b   : VAR nzreal
    n   : VAR nat
    m   : VAR posnat
    f,g : VAR (Diff?)

    Diff_id     : LEMMA Diff?(LAMBDA(t):t)

    D_id        : LEMMA D(LAMBDA(t):t) = LAMBDA(t):1
        
    Diff_const  : LEMMA Diff?(LAMBDA(t):a)
        
    D_const     : LEMMA D(LAMBDA(t):a) = LAMBDA(t):0
        
    Diff_add    : LEMMA Diff?(LAMBDA(t):f(t)+g(t))
         
    D_add       : LEMMA D(LAMBDA(t):f(t)+g(t)) = 
                        LAMBDA(t): D(f)(t) + D(g)(t)
        
    Diff_mult   : LEMMA Diff?(LAMBDA(t):f(t)*g(t))
        
    D_mult      : LEMMA D(LAMBDA(t):f(t)*g(t)) = 
                        LAMBDA(t):D(f)(t)*g(t) + D(g)(t)*f(t)

    Diff_pow    : LEMMA Diff?(LAMBDA(t):t^n)
        
    D_pow       : LEMMA D(LAMBDA(t):t^m) = LAMBDA(t):(m*t^(m-1))

    Diff_scal1  : LEMMA Diff?(LAMBDA(t): a*f(t))

    D_scal1     : LEMMA D(LAMBDA(t): a*f(t)) = LAMBDA(t):a*D(f)(t)

    Diff_scal2  : LEMMA Diff?(LAMBDA(t): f(t)*a)

    D_scal2     : LEMMA D(LAMBDA(t): f(t)*a) = LAMBDA(t):a*D(f)(t)

    Diff_neg    : LEMMA Diff?(LAMBDA(t):-g(t))

    D_neg       : LEMMA D(LAMBDA(t):-g(t)) = LAMBDA(t):-D(g)(t)

    Diff_sub    : LEMMA Diff?(LAMBDA(t):f(t)-g(t))
   
    D_sub       : LEMMA D(LAMBDA(t):f(t)-g(t)) = LAMBDA(t):D(f)(t)-D(g)(t)

    Diff_sq     : LEMMA Diff?(LAMBDA(t):sq(t))

    D_sq        : LEMMA D(LAMBDA(t):sq(t)) = LAMBDA(t):2*t

    Nonzero?(f) : MACRO bool =
      FORALL (t:Xt):f(t) /= 0

    k : VAR (Nonzero?)
    
    Diff_div    : LEMMA Diff?(LAMBDA(t):f(t)/k(t))

    D_div       : LEMMA D(LAMBDA(t):f(t)/k(t)) = 
                        LAMBDA(t):(D(f)(t)*k(t) - D(k)(t)*f(t)) / sq(k(t))

    Diff_scald1 : LEMMA Diff?(LAMBDA(t): a/k(t))

    D_scald1    : LEMMA D(LAMBDA(t): a/k(t)) = 
                        LAMBDA(t):-a*D(k)(t)/sq(k(t))

    Diff_scald2 : LEMMA Diff?(LAMBDA(t): f(t)/b)

    D_scald2    : LEMMA D(LAMBDA(t): f(t)/b) = 
                        LAMBDA(t):(D(f)(t))/b

    Diff_sin    : LEMMA Diff?(LAMBDA(t):sin(t))

    D_sin       : LEMMA D(LAMBDA(t):sin(t)) = LAMBDA(t):cos(t)

    Diff_cos    : LEMMA Diff?(LAMBDA(t):cos(t))

    D_cos       : LEMMA D(LAMBDA(t):cos(t)) = LAMBDA(t):-sin(t)

    Diff_tan : LEMMA 
      X << [| -pi_lbn(n+Cos_pos_n)/2, pi_lbn(n+Cos_pos_n)/2 |]
      IMPLIES 
        Diff?(LAMBDA(t):tan(t))

    D_tan : LEMMA     
      X << [| -pi_lbn(n+Cos_pos_n)/2, pi_lbn(n+Cos_pos_n)/2 |]
      IMPLIES 
        D(LAMBDA(t):tan(t)) = LAMBDA(t):1/sq(cos(t))

    Diff_atan : LEMMA 
      Diff?(LAMBDA(t):atan(t))

    D_atan : LEMMA     
      D(LAMBDA(t):atan(t)) = LAMBDA(t):1/(1+sq(t))

    Diff_sqrt : LEMMA  
      Gt(X,0)
      IMPLIES 
        Diff?(LAMBDA(t):sqrt(t))

    D_sqrt : LEMMA  
      Gt(X,0)
      IMPLIES 
        D(LAMBDA(t):sqrt(t)) = LAMBDA(t):1/(2*sqrt(t))

    Diff_exp : LEMMA
     Diff?(LAMBDA(t):exp(t))

    D_exp : LEMMA
     D(LAMBDA(t):exp(t)) = LAMBDA(t):exp(t)

    Diff_ln : LEMMA
      Gt(X,0) IMPLIES
        Diff?(LAMBDA(t):ln(t))

    D_ln : LEMMA
      Gt(X,0) IMPLIES
        D(LAMBDA(t):ln(t)) = LAMBDA(t):1/t

    Diff_I      : LEMMA Diff?(LAMBDA(t):id[numfield](f(t))) = 
                        Diff?(LAMBDA(t):f(t))

    D_I         : LEMMA D(LAMBDA(t):id[numfield](f(t))) = D(LAMBDA(t):f(t))

  END interval_deriv

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

  % Assuming TCC generated (at line 16, column 21) for
      % analysis@derivatives[Xt]
      % generated from assumption derivatives.deriv_domain
  IMP_derivatives_TCC1: OBLIGATION deriv_domain?[Xt];

  % Assuming TCC generated (at line 16, column 21) for
      % analysis@derivatives[Xt]
      % generated from assumption derivatives.not_one_element
  IMP_derivatives_TCC2: OBLIGATION not_one_element?[Xt];

  % Subtype TCC generated (at line 23, column 10) for  f
      % expected type  deriv_fun[Xt]
  D_TCC1: OBLIGATION FORALL (f: (Diff?)): derivable?[Xt](f);

  % Subtype TCC generated (at line 26, column 32) for  n - 1
      % expected type  nat
  Diffn?_TCC1: OBLIGATION
    FORALL (n: nat, f: [Xt -> real]):
      Diff?(f) AND NOT n = 0 IMPLIES n - 1 >= 0;

  % Termination TCC generated (at line 26, column 25) for  Diffn?(n - 1)
  Diffn?_TCC2: OBLIGATION
    FORALL (n: nat, f: [Xt -> real]):
      Diff?(f) AND NOT n = 0 IMPLIES n - 1 < n;

  % Subtype TCC generated (at line 35, column 12) for  n - 1
      % expected type  nat
  Dn_TCC1: OBLIGATION
    FORALL (n: nat, f: (Diffn?(n))): NOT n = 0 IMPLIES n - 1 >= 0;

  % Subtype TCC generated (at line 35, column 18) for  f
      % expected type  (Diff?)
  Dn_TCC2: OBLIGATION
    FORALL (n: nat, f: (Diffn?(n))): NOT n = 0 IMPLIES Diff?(f);

  % Subtype TCC generated (at line 35, column 16) for  D(f)
      % expected type  (Diffn?(n - 1))
  Dn_TCC3: OBLIGATION
    FORALL (n: nat, f: (Diffn?(n))): NOT n = 0 IMPLIES Diffn?(n - 1)(D(f));

  % Termination TCC generated (at line 35, column 9) for  Dn(n - 1, D(f))
  Dn_TCC4: OBLIGATION
    FORALL (n: nat, f: (Diffn?(n))): NOT n = 0 IMPLIES n - 1 < n;

  % Subtype TCC generated (at line 41, column 25) for  f
      % expected type  nderiv_fun[Xt](n)
  Dn_nderiv_TCC1: OBLIGATION
    FORALL (n: nat, f: (Diffn?(n))): derivable_n_times?[Xt](f, n);

  % Subtype TCC generated (at line 52, column 24) for  LAMBDA (t): t
      % expected type  (Diff?)
  D_id_TCC1: OBLIGATION Diff?(LAMBDA (t): t);

  % Subtype TCC generated (at line 56, column 24) for  LAMBDA (t): a
      % expected type  (Diff?)
  D_const_TCC1: OBLIGATION FORALL (a: real): Diff?(LAMBDA (t): a);

  % Subtype TCC generated (at line 60, column 24) for  LAMBDA (t): f(t) + g(t)
      % expected type  (Diff?)
  D_add_TCC1: OBLIGATION
    FORALL (f, g: (Diff?)): Diff?(LAMBDA (t): f(t) + g(t));

  % Subtype TCC generated (at line 65, column 24) for  LAMBDA (t): f(t) * g(t)
      % expected type  (Diff?)
  D_mult_TCC1: OBLIGATION
    FORALL (f, g: (Diff?)): Diff?(LAMBDA (t): f(t) * g(t));

  % Subtype TCC generated (at line 68, column 40) for  n
      % expected type  {i: int | t /= 0 OR i >= 0}
  Diff_pow_TCC1: OBLIGATION FORALL (n: nat, t: Xt): t /= 0 OR n >= 0;

  % Subtype TCC generated (at line 70, column 36) for  m
      % expected type  {i: int | t /= 0 OR i >= 0}
  D_pow_TCC1: OBLIGATION FORALL (m: posnat, t: Xt): t /= 0 OR m >= 0;

  % Subtype TCC generated (at line 70, column 24) for  LAMBDA (t): t ^ m
      % expected type  (Diff?)
  D_pow_TCC2: OBLIGATION FORALL (m: posnat): Diff?(LAMBDA (t): t ^ m);

  % Subtype TCC generated (at line 70, column 57) for  (m - 1)
      % expected type  {i: int | t /= 0 OR i >= 0}
  D_pow_TCC3: OBLIGATION FORALL (m: posnat, t: Xt): t /= 0 OR (m - 1) >= 0;

  % Subtype TCC generated (at line 74, column 24) for  LAMBDA (t): a * f(t)
      % expected type  (Diff?)
  D_scal1_TCC1: OBLIGATION
    FORALL (a: real, f: (Diff?)): Diff?(LAMBDA (t): a * f(t));

  % Subtype TCC generated (at line 78, column 24) for  LAMBDA (t): f(t) * a
      % expected type  (Diff?)
  D_scal2_TCC1: OBLIGATION
    FORALL (a: real, f: (Diff?)): Diff?(LAMBDA (t): f(t) * a);

  % Subtype TCC generated (at line 82, column 24) for  LAMBDA (t): -g(t)
      % expected type  (Diff?)
  D_neg_TCC1: OBLIGATION FORALL (g: (Diff?)): Diff?(LAMBDA (t): -g(t));

  % Subtype TCC generated (at line 86, column 24) for  LAMBDA (t): f(t) - g(t)
      % expected type  (Diff?)
  D_sub_TCC1: OBLIGATION
    FORALL (f, g: (Diff?)): Diff?(LAMBDA (t): f(t) - g(t));

  % Subtype TCC generated (at line 90, column 24) for  LAMBDA (t): sq(t)
      % expected type  (Diff?)
  D_sq_TCC1: OBLIGATION Diff?(LAMBDA (t): sq(t));

  % Subtype TCC generated (at line 97, column 43) for  k(t)
      % expected type  nznum
  Diff_div_TCC1: OBLIGATION
    FORALL (k: (LAMBDA (f): FORALL (t: Xt): f(t) /= 0), t: Xt): k(t) /= 0;

  % Subtype TCC generated (at line 99, column 24) for  LAMBDA (t): f(t) / k(t)
      % expected type  (Diff?)
  D_div_TCC1: OBLIGATION
    FORALL (f: (Diff?), k: (LAMBDA (f): FORALL (t: Xt): f(t) /= 0)):
      Diff?(LAMBDA (t): f(t) / k(t));

  % Subtype TCC generated (at line 100, column 64) for  sq(k(t))
      % expected type  nznum
  D_div_TCC2: OBLIGATION
    FORALL (k: (LAMBDA (f): FORALL (t: Xt): f(t) /= 0), t: Xt): sq(k(t)) /= 0;

  % Subtype TCC generated (at line 104, column 24) for  LAMBDA (t): a / k(t)
      % expected type  (Diff?)
  D_scald1_TCC1: OBLIGATION
    FORALL (a: real, k: (LAMBDA (f): FORALL (t: Xt): f(t) /= 0)):
      Diff?(LAMBDA (t): a / k(t));

  % Subtype TCC generated (at line 109, column 24) for  LAMBDA (t): f(t) / b
      % expected type  (Diff?)
  D_scald2_TCC1: OBLIGATION
    FORALL (b: nzreal, f: (Diff?)): Diff?(LAMBDA (t): f(t) / b);

  % Subtype TCC generated (at line 114, column 24) for  LAMBDA (t): sin(t)
      % expected type  (Diff?)
  D_sin_TCC1: OBLIGATION Diff?(LAMBDA (t): sin(t));

  % Subtype TCC generated (at line 118, column 24) for  LAMBDA (t): cos(t)
      % expected type  (Diff?)
  D_cos_TCC1: OBLIGATION Diff?(LAMBDA (t): cos(t));

  % Subtype TCC generated (at line 121, column 20) for  n + 5
      % expected type  nat
  Diff_tan_TCC1: OBLIGATION FORALL (n: nat): n + 5 >= 0;

  % Subtype TCC generated (at line 123, column 26) for  t
      % expected type  (Tan?)
  Diff_tan_TCC2: OBLIGATION
    FORALL (n: nat):
      X << [|-pi_lbn(n + 5) / 2, pi_lbn(n + 5) / 2|] IMPLIES
       (FORALL (t: Xt): Tan?(t));

  % Subtype TCC generated (at line 128, column 8) for  LAMBDA (t): tan(t)
      % expected type  (Diff?)
  D_tan_TCC1: OBLIGATION
    FORALL (n: nat):
      X << [|-pi_lbn(n + 5) / 2, pi_lbn(n + 5) / 2|] IMPLIES
       Diff?(LAMBDA (t): tan(t));

  % Subtype TCC generated (at line 128, column 40) for  sq(cos(t))
      % expected type  nznum
  D_tan_TCC2: OBLIGATION
    FORALL (n: nat):
      X << [|-pi_lbn(n + 5) / 2, pi_lbn(n + 5) / 2|] IMPLIES
       (FORALL (t: Xt): sq(cos(t)) /= 0);

  % Subtype TCC generated (at line 134, column 6) for  LAMBDA (t): atan(t)
      % expected type  (Diff?)
  D_atan_TCC1: OBLIGATION Diff?(LAMBDA (t): atan(t));

  % Subtype TCC generated (at line 139, column 27) for  t
      % expected type  nnx: nonneg_real
  Diff_sqrt_TCC1: OBLIGATION Gt(X, 0) IMPLIES (FORALL (t: Xt): t >= 0);

  % Subtype TCC generated (at line 144, column 8) for  LAMBDA (t): sqrt(t)
      % expected type  (Diff?)
  D_sqrt_TCC1: OBLIGATION Gt(X, 0) IMPLIES Diff?(LAMBDA (t): sqrt(t));

  % Subtype TCC generated (at line 144, column 42) for  (2 * sqrt(t))
      % expected type  nznum
  D_sqrt_TCC2: OBLIGATION
    Gt(X, 0) IMPLIES (FORALL (t: Xt): (2 * sqrt(t)) /= 0);

  % Subtype TCC generated (at line 150, column 5) for  LAMBDA (t): exp(t)
      % expected type  (Diff?)
  D_exp_TCC1: OBLIGATION Diff?(LAMBDA (t): exp(t));

  % Subtype TCC generated (at line 154, column 25) for  t
      % expected type  posreal
  Diff_ln_TCC1: OBLIGATION
    Gt(X, 0) IMPLIES (FORALL (t: Xt): t >= 0 AND t > 0);

  % Subtype TCC generated (at line 158, column 8) for  LAMBDA (t): ln(t)
      % expected type  (Diff?)
  D_ln_TCC1: OBLIGATION Gt(X, 0) IMPLIES Diff?(LAMBDA (t): ln(t));

  % Subtype TCC generated (at line 158, column 39) for  t
      % expected type  nznum
  D_ln_TCC2: OBLIGATION Gt(X, 0) IMPLIES (FORALL (t: Xt): t /= 0);

  % Subtype TCC generated (at line 163, column 24) for
      % LAMBDA (t): id[numfield](f(t))
      % expected type  (Diff?)
  D_I_TCC1: OBLIGATION
    FORALL (f: (Diff?)): Diff?(LAMBDA (t): id[numfield](f(t)));

  % Subtype TCC generated (at line 163, column 58) for  LAMBDA (t): f(t)
      % expected type  (Diff?)
  D_I_TCC2: OBLIGATION FORALL (f: (Diff?)): Diff?(LAMBDA (t): f(t));


