TFL/tfl.sml
changeset 3191 14bd6e5985f1
parent 2112 3902e9af752f
child 3245 241838c01caf
equal deleted inserted replaced
3190:5aa3756a4bf2 3191:14bd6e5985f1
   304  end;
   304  end;
   305 
   305 
   306 local fun paired1{lhs,rhs} = (lhs,rhs) 
   306 local fun paired1{lhs,rhs} = (lhs,rhs) 
   307       and paired2{Rator,Rand} = (Rator,Rand)
   307       and paired2{Rator,Rand} = (Rator,Rand)
   308       fun mk_functional_err s = raise TFL_ERR{func = "mk_functional", mesg=s}
   308       fun mk_functional_err s = raise TFL_ERR{func = "mk_functional", mesg=s}
       
   309       fun single [f] = f
       
   310 	| single fs  = mk_functional_err (Int.toString (length fs) ^ 
       
   311 					  " distinct function names!")
   309 in
   312 in
   310 fun mk_functional thy eqs =
   313 fun mk_functional thy eqs =
   311  let val clauses = S.strip_conj eqs
   314  let val clauses = S.strip_conj eqs
   312      val (L,R) = U.unzip (map (paired1 o S.dest_eq o U.snd o S.strip_forall)
   315      val (L,R) = U.unzip (map (paired1 o S.dest_eq o U.snd o S.strip_forall)
   313                               clauses)
   316                               clauses)
   314      val (funcs,pats) = U.unzip(map (paired2 o S.dest_comb) L)
   317      val (funcs,pats) = U.unzip(map (paired2 o S.dest_comb) L)
   315      val [f] = U.mk_set (S.aconv) funcs 
   318      val f = single (U.mk_set (S.aconv) funcs)
   316                handle _ => mk_functional_err "function name not unique"
   319      val fvar = if (S.is_var f) then f else S.mk_var(S.dest_const f)
   317      val _ = map (no_repeat_vars thy) pats
   320      val _ = map (no_repeat_vars thy) pats
   318      val rows = U.zip (map (fn x => ([],[x])) pats) (map GIVEN (enumerate R))
   321      val rows = U.zip (map (fn x => ([],[x])) pats) (map GIVEN (enumerate R))
   319      val fvs = S.free_varsl R
   322      val fvs = S.free_varsl R
   320      val a = S.variant fvs (S.mk_var{Name="a", Ty = S.type_of(hd pats)})
   323      val a = S.variant fvs (S.mk_var{Name="a", Ty = S.type_of(hd pats)})
   321      val FV = a::fvs
   324      val FV = a::fvs
   332      fun int_eq i1 (i2:int) =  (i1=i2)
   335      fun int_eq i1 (i2:int) =  (i1=i2)
   333      val _ = case (U.set_diff int_eq originals finals)
   336      val _ = case (U.set_diff int_eq originals finals)
   334              of [] => ()
   337              of [] => ()
   335           | L => mk_functional_err("The following rows (counting from zero)\
   338           | L => mk_functional_err("The following rows (counting from zero)\
   336                                    \ are inaccessible: "^stringize L)
   339                                    \ are inaccessible: "^stringize L)
   337  in {functional = S.list_mk_abs ([f,a], case_tm),
   340      val case_tm' = S.subst [f |-> fvar] case_tm
       
   341  in {functional = S.list_mk_abs ([fvar,a], case_tm'),
   338      pats = patts2}
   342      pats = patts2}
   339 end end;
   343 end end;
   340 
   344 
   341 
   345 
   342 (*----------------------------------------------------------------------------
   346 (*----------------------------------------------------------------------------
   344  *                    PRINCIPLES OF DEFINITION
   348  *                    PRINCIPLES OF DEFINITION
   345  *
   349  *
   346  *---------------------------------------------------------------------------*)
   350  *---------------------------------------------------------------------------*)
   347 
   351 
   348 
   352 
   349 (*----------------------------------------------------------------------------
   353 (*---------------------------------------------------------------------------
   350  * This basic principle of definition takes a functional M and a relation R
   354  * R is already assumed to be type-copacetic with M
   351  * and specializes the following theorem
   355  *---------------------------------------------------------------------------*)
   352  *
   356 local val f_eq_wfrec_R_M = 
   353  *    |- !M R f. (f = WFREC R M) ==> WF R ==> !x. f x = M (f%R,x) x
   357            #ant(S.dest_imp(#2(S.strip_forall (concl Thms.WFREC_COROLLARY))))
   354  *
   358       val {lhs=f, rhs} = S.dest_eq f_eq_wfrec_R_M
   355  * to them (getting "th1", say). Then we make the definition "f = WFREC R M" 
   359       val fname = #Name(S.dest_var f)
   356  * and instantiate "th1" to the constant "f" (getting th2). Then we use the
   360       val (wfrec,_) = S.strip_comb rhs
   357  * definition to delete the first antecedent to th2. Hence the result in
   361 in
   358  * the "corollary" field is 
   362 fun wfrec_definition0 thy R functional =
   359  *
   363  let val {Bvar,...} = S.dest_abs functional
   360  *    |-  WF R ==> !x. f x = M (f%R,x) x
   364      val {Name, Ty} = S.dest_var Bvar  
   361  *
   365      val def_name = U.concat Name "_def"
   362  *---------------------------------------------------------------------------*)
   366      val (_,ty_theta) = Thry.match_term thy f (S.mk_var{Name=fname,Ty=Ty})
   363 
   367      val wfrec' = S.inst ty_theta wfrec
   364 fun prim_wfrec_definition thy {R, functional} =
   368      val wfrec_R_M' = S.list_mk_comb(wfrec',[R,functional])
   365  let val tych = Thry.typecheck thy
   369      val def_term = S.mk_eq{lhs=Bvar, rhs=wfrec_R_M'}
   366      val {Bvar,...} = S.dest_abs functional
   370   in 
   367      val {Name,...} = S.dest_var Bvar  (* Intended name of definition *)
   371   Thry.make_definition thy def_name def_term
   368      val cor1 = R.ISPEC (tych functional) Thms.WFREC_COROLLARY
   372   end
   369      val cor2 = R.ISPEC (tych R) cor1
   373 end;
   370      val f_eq_WFREC_R_M = (#ant o S.dest_imp o #Body 
   374 
   371                            o S.dest_forall o concl) cor2
       
   372      val {lhs,rhs} = S.dest_eq f_eq_WFREC_R_M
       
   373      val {Ty, ...} = S.dest_var lhs
       
   374      val def_term = S.mk_eq{lhs = S.mk_var{Name=Name,Ty=Ty}, rhs=rhs}
       
   375      val (def_thm,thy1) = Thry.make_definition thy 
       
   376                                   (U.concat Name "_def") def_term
       
   377      val (_,[f,_]) = (S.strip_comb o concl) def_thm
       
   378      val cor3 = R.ISPEC (Thry.typecheck thy1 f) cor2
       
   379  in 
       
   380  {theory = thy1, def=def_thm, corollary=R.MP cor3 def_thm}
       
   381  end;
       
   382 
   375 
   383 
   376 
   384 (*---------------------------------------------------------------------------
   377 (*---------------------------------------------------------------------------
   385  * This structure keeps track of congruence rules that aren't derived
   378  * This structure keeps track of congruence rules that aren't derived
   386  * from a datatype definition.
   379  * from a datatype definition.
   420 fun not_omitted (GIVEN(tm,_)) = tm
   413 fun not_omitted (GIVEN(tm,_)) = tm
   421   | not_omitted (OMITTED _) = raise TFL_ERR{func="not_omitted",mesg=""}
   414   | not_omitted (OMITTED _) = raise TFL_ERR{func="not_omitted",mesg=""}
   422 val givens = U.mapfilter not_omitted;
   415 val givens = U.mapfilter not_omitted;
   423 
   416 
   424 
   417 
   425 (*--------------------------------------------------------------------------
   418 fun post_definition (theory, (def, pats)) =
   426  * This is a wrapper for "prim_wfrec_definition": it builds a functional,
   419  let val tych = Thry.typecheck theory 
   427  * calls "prim_wfrec_definition", then specializes the result. This gives a
   420      val f = #lhs(S.dest_eq(concl def))
   428  * list of rewrite rules where the right hand sides are quite ugly, so we 
   421      val corollary = R.MATCH_MP Thms.WFREC_COROLLARY def
   429  * simplify to get rid of the case statements. In essence, this function
       
   430  * performs pre- and post-processing for patterns. As well, after
       
   431  * simplification, termination conditions are extracted.
       
   432  *-------------------------------------------------------------------------*)
       
   433 
       
   434 fun gen_wfrec_definition thy {R, eqs} =
       
   435  let val {functional,pats}  = mk_functional thy eqs
       
   436      val given_pats = givens pats
   422      val given_pats = givens pats
   437      val {def,corollary,theory} = prim_wfrec_definition thy
       
   438                                         {R=R, functional=functional}
       
   439      val tych = Thry.typecheck theory 
       
   440      val {lhs=f,...} = S.dest_eq(concl def)
       
   441      val WFR = #ant(S.dest_imp(concl corollary))
   423      val WFR = #ant(S.dest_imp(concl corollary))
       
   424      val R = #Rand(S.dest_comb WFR)
   442      val corollary' = R.UNDISCH corollary  (* put WF R on assums *)
   425      val corollary' = R.UNDISCH corollary  (* put WF R on assums *)
   443      val corollaries = map (U.C R.SPEC corollary' o tych) given_pats
   426      val corollaries = map (U.C R.SPEC corollary' o tych) given_pats
   444      val (case_rewrites,context_congs) = extraction_thms thy
   427      val (case_rewrites,context_congs) = extraction_thms theory
   445      val corollaries' = map(R.simplify case_rewrites) corollaries
   428      val corollaries' = map(R.simplify case_rewrites) corollaries
   446      fun xtract th = R.CONTEXT_REWRITE_RULE(f,R)
   429      fun xtract th = R.CONTEXT_REWRITE_RULE(f,R)
   447                          {thms = [(R.ISPECL o map tych)[f,R] Thms.CUT_LEMMA],
   430                          {thms = [(R.ISPECL o map tych)[f,R] Thms.CUT_LEMMA],
   448                          congs = context_congs,
   431                          congs = context_congs,
   449                             th = th}
   432                             th = th}
   456   rules = rules1,
   439   rules = rules1,
   457   full_pats_TCs = merge (map pat_of pats) (U.zip given_pats TCs), 
   440   full_pats_TCs = merge (map pat_of pats) (U.zip given_pats TCs), 
   458   TCs = TCs, 
   441   TCs = TCs, 
   459   patterns = pats}
   442   patterns = pats}
   460  end;
   443  end;
   461 
       
   462 
   444 
   463 (*---------------------------------------------------------------------------
   445 (*---------------------------------------------------------------------------
   464  * Perform the extraction without making the definition. Definition and
   446  * Perform the extraction without making the definition. Definition and
   465  * extraction commute for the non-nested case. For hol90 users, this 
   447  * extraction commute for the non-nested case. For hol90 users, this 
   466  * function can be invoked without being in draft mode.
   448  * function can be invoked without being in draft mode.
   519      val def' = R.MP (R.SPEC (tych fconst) 
   501      val def' = R.MP (R.SPEC (tych fconst) 
   520                              (R.SPEC (tych R') (R.GENL[tych R1, tych f] baz)))
   502                              (R.SPEC (tych R') (R.GENL[tych R1, tych f] baz)))
   521                      def
   503                      def
   522      val body_th = R.LIST_CONJ (map (R.ASSUME o tych) full_rqt)
   504      val body_th = R.LIST_CONJ (map (R.ASSUME o tych) full_rqt)
   523      val bar = R.MP (R.BETA_RULE(R.ISPECL[tych R'abs, tych R1] Thms.SELECT_AX))
   505      val bar = R.MP (R.BETA_RULE(R.ISPECL[tych R'abs, tych R1] Thms.SELECT_AX))
   524                      body_th
   506                     body_th
   525  in {theory = theory, R=R1,
   507  in {theory = theory, R=R1,
   526      rules = U.rev_itlist (U.C R.MP) (R.CONJUNCTS bar) def',
   508      rules = U.rev_itlist (U.C R.MP) (R.CONJUNCTS bar) def',
   527      full_pats_TCs = merge (map pat_of pats) (U.zip (givens pats) TCl),
   509      full_pats_TCs = merge (map pat_of pats) (U.zip (givens pats) TCl),
   528      patterns = pats}
   510      patterns = pats}
   529  end;
   511  end;
   903 in
   885 in
   904   {induction = ind2, rules = R.LIST_CONJ rules2, nested_tcs = extras}
   886   {induction = ind2, rules = R.LIST_CONJ rules2, nested_tcs = extras}
   905 end;
   887 end;
   906 
   888 
   907 
   889 
   908 (*---------------------------------------------------------------------------
       
   909  * Extract termination goals so that they can be put it into a goalstack, or 
       
   910  * have a tactic directly applied to them.
       
   911  *--------------------------------------------------------------------------*)
       
   912 local exception IS_NEG 
       
   913       fun strip_imp tm = if S.is_neg tm then raise IS_NEG else S.strip_imp tm
       
   914 in
       
   915 fun termination_goals rules = 
       
   916     U.itlist (fn th => fn A =>
       
   917         let val tcl = (#1 o S.strip_imp o #2 o S.strip_forall o concl) th
       
   918         in tcl@A
       
   919         end handle _ => A) (R.CONJUNCTS rules) (hyp rules)
       
   920 end;
       
   921 
       
   922 end; (* TFL *)
   890 end; (* TFL *)