TFL/tfl.sml
changeset 7262 a05dc63ca29b
parent 7052 4c201f27c74e
child 7286 fcbf147e7b4c
equal deleted inserted replaced
7261:a141985d660b 7262:a05dc63ca29b
    14 (* Abbreviations *)
    14 (* Abbreviations *)
    15 structure R = Rules;
    15 structure R = Rules;
    16 structure S = USyntax;
    16 structure S = USyntax;
    17 structure U = S.Utils;
    17 structure U = S.Utils;
    18 
    18 
       
    19 fun TFL_ERR{func,mesg} = U.ERR{module = "Tfl", func = func, mesg = mesg};
       
    20 
    19 val concl = #2 o R.dest_thm;
    21 val concl = #2 o R.dest_thm;
    20 val hyp = #1 o R.dest_thm;
    22 val hyp = #1 o R.dest_thm;
    21 
    23 
    22 val list_mk_type = U.end_itlist (curry(op -->));
    24 val list_mk_type = U.end_itlist (curry(op -->));
    23 
    25 
    26 
    28 
    27 fun stringize [] = ""
    29 fun stringize [] = ""
    28   | stringize [i] = Int.toString i
    30   | stringize [i] = Int.toString i
    29   | stringize (h::t) = (Int.toString h^", "^stringize t);
    31   | stringize (h::t) = (Int.toString h^", "^stringize t);
    30 
    32 
    31 
    33 fun front_last [] = raise TFL_ERR {func="front_last", mesg="empty list"}
    32 fun TFL_ERR{func,mesg} = U.ERR{module = "Tfl", func = func, mesg = mesg};
    34   | front_last [x] = ([],x)
       
    35   | front_last (h::t) =
       
    36      let val (pref,x) = front_last t 
       
    37      in 
       
    38         (h::pref,x) 
       
    39      end;
       
    40 
    33 
    41 
    34 
    42 
    35 (*---------------------------------------------------------------------------
    43 (*---------------------------------------------------------------------------
    36           handling of user-supplied congruence rules: lcp*)
    44           handling of user-supplied congruence rules: lcp*)
    37 
    45 
    43 
    51 
    44 fun congs ths = default_congs @ eq_reflect_list ths;
    52 fun congs ths = default_congs @ eq_reflect_list ths;
    45 
    53 
    46 val default_simps = 
    54 val default_simps = 
    47     [less_Suc_eq RS iffD2, lex_prod_def, measure_def, inv_image_def];
    55     [less_Suc_eq RS iffD2, lex_prod_def, measure_def, inv_image_def];
    48 
       
    49 
    56 
    50 
    57 
    51 
    58 
    52 (*---------------------------------------------------------------------------
    59 (*---------------------------------------------------------------------------
    53  * The next function is common to pattern-match translation and 
    60  * The next function is common to pattern-match translation and 
   286 			  quote (string_of_cterm (Thry.typecheck thy pat))}
   293 			  quote (string_of_cterm (Thry.typecheck thy pat))}
   287          else check rst
   294          else check rst
   288  in check (FV_multiset pat)
   295  in check (FV_multiset pat)
   289  end;
   296  end;
   290 
   297 
       
   298 fun dest_atom (Free p) = p
       
   299   | dest_atom (Const p) = p
       
   300   | dest_atom  _ = raise TFL_ERR {func="dest_atom", 
       
   301 				  mesg="function name not an identifier"};
       
   302 
       
   303 
   291 local fun mk_functional_err s = raise TFL_ERR{func = "mk_functional", mesg=s}
   304 local fun mk_functional_err s = raise TFL_ERR{func = "mk_functional", mesg=s}
   292       fun single [Free(a,_)] = 
   305       fun single [_$_] = 
   293 	      mk_functional_err (a ^ " has not been declared as a constant")
       
   294         | single [_$_] = 
       
   295 	      mk_functional_err "recdef does not allow currying"
   306 	      mk_functional_err "recdef does not allow currying"
   296         | single [Const arg] = arg
   307         | single [f] = f
   297 	| single [_] = mk_functional_err "recdef: bad function name"
       
   298         | single fs  = mk_functional_err (Int.toString (length fs) ^ 
   308         | single fs  = mk_functional_err (Int.toString (length fs) ^ 
   299                                           " distinct function names!")
   309                                           " distinct function names!")
   300 in
   310 in
   301 fun mk_functional thy clauses =
   311 fun mk_functional thy clauses =
   302  let val (L,R) = ListPair.unzip (map HOLogic.dest_eq clauses)
   312  let val (L,R) = ListPair.unzip (map HOLogic.dest_eq clauses)
   303                    handle _ => raise TFL_ERR
   313                    handle _ => raise TFL_ERR
   304 		       {func = "mk_functional", 
   314 		       {func = "mk_functional", 
   305 			mesg = "recursion equations must use the = relation"}
   315 			mesg = "recursion equations must use the = relation"}
   306      val (funcs,pats) = ListPair.unzip (map (fn (t$u) =>(t,u)) L)
   316      val (funcs,pats) = ListPair.unzip (map (fn (t$u) =>(t,u)) L)
   307      val (fname, ftype) = single (gen_distinct (op aconv) funcs)
   317      val atom = single (gen_distinct (op aconv) funcs)
       
   318      val (fname,ftype) = dest_atom atom
   308      val dummy = map (no_repeat_vars thy) pats
   319      val dummy = map (no_repeat_vars thy) pats
   309      val rows = ListPair.zip (map (fn x => ([],[x])) pats,
   320      val rows = ListPair.zip (map (fn x => ([]:term list,[x])) pats,
   310                               map GIVEN (enumerate R))
   321                               map GIVEN (enumerate R))
   311      val names = foldr add_term_names (R,[])
   322      val names = foldr add_term_names (R,[])
   312      val atype = type_of(hd pats)
   323      val atype = type_of(hd pats)
   313      and aname = variant names "a"
   324      and aname = variant names "a"
   314      val a = Free(aname,atype)
   325      val a = Free(aname,atype)
   325      val dummy = case (originals\\finals)
   336      val dummy = case (originals\\finals)
   326              of [] => ()
   337              of [] => ()
   327           | L => mk_functional_err("The following rows (counting from zero)\
   338           | L => mk_functional_err("The following rows (counting from zero)\
   328                                    \ are inaccessible: "^stringize L)
   339                                    \ are inaccessible: "^stringize L)
   329  in {functional = Abs(Sign.base_name fname, ftype,
   340  in {functional = Abs(Sign.base_name fname, ftype,
   330 		      abstract_over (Const(fname,ftype), 
   341 		      abstract_over (atom, 
   331 				     absfree(aname, atype, case_tm))),
   342 				     absfree(aname,atype, case_tm))),
   332      pats = patts2}
   343      pats = patts2}
   333 end end;
   344 end end;
   334 
   345 
   335 
   346 
   336 (*----------------------------------------------------------------------------
   347 (*----------------------------------------------------------------------------
   437 
   448 
   438 
   449 
   439 (*---------------------------------------------------------------------------
   450 (*---------------------------------------------------------------------------
   440  * Perform the extraction without making the definition. Definition and
   451  * Perform the extraction without making the definition. Definition and
   441  * extraction commute for the non-nested case.  (Deferred recdefs)
   452  * extraction commute for the non-nested case.  (Deferred recdefs)
   442  *---------------------------------------------------------------------------*)
   453  *
       
   454  * The purpose of wfrec_eqns is merely to instantiate the recursion theorem
       
   455  * and extract termination conditions: no definition is made.
       
   456  *---------------------------------------------------------------------------*)
       
   457 
   443 fun wfrec_eqns thy fid tflCongs eqns =
   458 fun wfrec_eqns thy fid tflCongs eqns =
   444  let val {functional as Abs(Name, Ty, _),  pats} = mk_functional thy eqns
   459  let val {lhs,rhs} = S.dest_eq (hd eqns)
       
   460      val (f,args) = S.strip_comb lhs
       
   461      val (fname,fty) = dest_atom f
       
   462      val (SV,a) = front_last args    (* SV = schematic variables *)
       
   463      val g = list_comb(f,SV)
       
   464      val h = Free(fname,type_of g)
       
   465      val eqns1 = map (subst_free[(g,h)]) eqns
       
   466      val {functional as Abs(Name, Ty, _),  pats} = mk_functional thy eqns1
   445      val given_pats = givens pats
   467      val given_pats = givens pats
   446      val f = #1 (S.strip_comb(#lhs(S.dest_eq (hd eqns))))
       
   447      (* val f = Free(Name,Ty) *)
   468      (* val f = Free(Name,Ty) *)
   448      val Type("fun", [f_dty, f_rty]) = Ty
   469      val Type("fun", [f_dty, f_rty]) = Ty
   449      val dummy = if Name<>fid then 
   470      val dummy = if Name<>fid then 
   450 			raise TFL_ERR{func = "lazyR_def",
   471 			raise TFL_ERR{func = "wfrec_eqns",
   451 				      mesg = "Expected a definition of " ^ 
   472 				      mesg = "Expected a definition of " ^ 
   452 				      quote fid ^ " but found one of " ^
   473 				      quote fid ^ " but found one of " ^
   453 				      quote Name}
   474 				      quote Name}
   454 		 else ()
   475 		 else ()
   455      val SV = S.free_vars_lr functional  (* schema variables *)
       
   456      val (case_rewrites,context_congs) = extraction_thms thy
   476      val (case_rewrites,context_congs) = extraction_thms thy
   457      val tych = Thry.typecheck thy
   477      val tych = Thry.typecheck thy
   458      val WFREC_THM0 = R.ISPEC (tych functional) Thms.WFREC_COROLLARY
   478      val WFREC_THM0 = R.ISPEC (tych functional) Thms.WFREC_COROLLARY
   459      val Const("All",_) $ Abs(Rname,Rtype,_) = concl WFREC_THM0
   479      val Const("All",_) $ Abs(Rname,Rtype,_) = concl WFREC_THM0
   460      val R = Free (variant (foldr add_term_names (eqns,[])) Rname,
   480      val R = Free (variant (foldr add_term_names (eqns,[])) Rname,
   461 		   Rtype)
   481 		   Rtype)
   462      val WFREC_THM = R.ISPECL [tych R, tych f] WFREC_THM0
   482      val WFREC_THM = R.ISPECL [tych R, tych g] WFREC_THM0
   463      val ([proto_def, WFR],_) = S.strip_imp(concl WFREC_THM)
   483      val ([proto_def, WFR],_) = S.strip_imp(concl WFREC_THM)
   464      val dummy = 
   484      val dummy = 
   465 	   if !trace then
   485 	   if !trace then
   466 	       writeln ("ORIGINAL PROTO_DEF: " ^ 
   486 	       writeln ("ORIGINAL PROTO_DEF: " ^ 
   467 			  Sign.string_of_term (Theory.sign_of thy) proto_def)
   487 			  Sign.string_of_term (Theory.sign_of thy) proto_def)
   470      val corollary' = R.UNDISCH(R.UNDISCH WFREC_THM)
   490      val corollary' = R.UNDISCH(R.UNDISCH WFREC_THM)
   471      val corollaries = map (fn pat => R.SPEC (tych pat) corollary') given_pats
   491      val corollaries = map (fn pat => R.SPEC (tych pat) corollary') given_pats
   472      val corollaries' = map (rewrite_rule case_rewrites) corollaries
   492      val corollaries' = map (rewrite_rule case_rewrites) corollaries
   473      fun extract X = R.CONTEXT_REWRITE_RULE 
   493      fun extract X = R.CONTEXT_REWRITE_RULE 
   474 	               (f, R1::SV, cut_apply, tflCongs@context_congs) X
   494 	               (f, R1::SV, cut_apply, tflCongs@context_congs) X
   475  in {proto_def =   (*Use == rather than = for definitions*)
   495  in {proto_def = proto_def,
       
   496      (*LCP: want this??
       
   497   (*Use == rather than = for definitions*)
   476 	 mk_const_def (Theory.sign_of thy) 
   498 	 mk_const_def (Theory.sign_of thy) 
   477 	              (Name, Ty, S.rhs proto_def), 
   499 	              (Name, Ty, S.rhs proto_def), *)
   478      SV=SV,
   500      SV=SV,
   479      WFR=WFR, 
   501      WFR=WFR, 
   480      pats=pats,
   502      pats=pats,
   481      extracta = map extract corollaries'}
   503      extracta = map extract corollaries'}
   482  end;
   504  end;
   486  * Define the constant after extracting the termination conditions. The 
   508  * Define the constant after extracting the termination conditions. The 
   487  * wellfounded relation used in the definition is computed by using the
   509  * wellfounded relation used in the definition is computed by using the
   488  * choice operator on the extracted conditions (plus the condition that
   510  * choice operator on the extracted conditions (plus the condition that
   489  * such a relation must be wellfounded).
   511  * such a relation must be wellfounded).
   490  *---------------------------------------------------------------------------*)
   512  *---------------------------------------------------------------------------*)
       
   513 
   491 fun lazyR_def thy fid tflCongs eqns =
   514 fun lazyR_def thy fid tflCongs eqns =
   492  let val {proto_def,WFR,pats,extracta,SV} = 
   515  let val {proto_def,WFR,pats,extracta,SV} = 
   493 	   wfrec_eqns thy fid (congs tflCongs) eqns
   516 	   wfrec_eqns thy fid (congs tflCongs) eqns
   494      val R1 = S.rand WFR
   517      val R1 = S.rand WFR
   495      val f = #1 (Logic.dest_equals proto_def)
   518      val f = #lhs(S.dest_eq proto_def)
       
   519 (*LCP: want this?     val f = #1 (Logic.dest_equals proto_def) *)
   496      val (extractants,TCl) = ListPair.unzip extracta
   520      val (extractants,TCl) = ListPair.unzip extracta
   497      val dummy = if !trace 
   521      val dummy = if !trace 
   498 		 then (writeln "Extractants = ";
   522 		 then (writeln "Extractants = ";
   499 		       prths extractants;
   523 		       prths extractants;
   500 		       ())
   524 		       ())
   506      val proto_def' = subst_free[(R1,R')] proto_def
   530      val proto_def' = subst_free[(R1,R')] proto_def
   507      val dummy = if !trace then writeln ("proto_def' = " ^
   531      val dummy = if !trace then writeln ("proto_def' = " ^
   508 					 Sign.string_of_term
   532 					 Sign.string_of_term
   509 					 (Theory.sign_of thy) proto_def')
   533 					 (Theory.sign_of thy) proto_def')
   510 	                   else ()
   534 	                   else ()
       
   535      val {lhs,rhs} = S.dest_eq proto_def'
       
   536      val (c,args) = S.strip_comb lhs
       
   537      val (Name,Ty) = dest_atom c
       
   538      val defn = mk_const_def (Theory.sign_of thy) 
       
   539                  (Name, Ty, S.list_mk_abs (args,rhs)) 
       
   540      (*LCP: want this??
   511      val theory =
   541      val theory =
   512        thy
   542        thy
   513        |> PureThy.add_defs_i 
   543        |> PureThy.add_defs_i 
   514             [Thm.no_attributes (fid ^ "_def", proto_def')];
   544             [Thm.no_attributes (fid ^ "_def", proto_def')];
   515      val def = get_axiom theory (fid ^ "_def") RS meta_eq_to_obj_eq
   545      val def = get_axiom theory (fid ^ "_def") RS meta_eq_to_obj_eq
       
   546      *)
       
   547      val theory =
       
   548        thy
       
   549        |> PureThy.add_defs_i 
       
   550             [Thm.no_attributes (fid ^ "_def", defn)]
       
   551      val def = freezeT (get_axiom theory (fid ^ "_def"))
   516      val dummy = if !trace then writeln ("DEF = " ^ string_of_thm def)
   552      val dummy = if !trace then writeln ("DEF = " ^ string_of_thm def)
   517 	                   else ()
   553 	                   else ()
   518      val fconst = #lhs(S.dest_eq(concl def)) 
   554      (* val fconst = #lhs(S.dest_eq(concl def))  *)
   519      val tych = Thry.typecheck theory
   555      val tych = Thry.typecheck theory
   520      val full_rqt_prop = map (Dcterm.mk_prop o tych) full_rqt
   556      val full_rqt_prop = map (Dcterm.mk_prop o tych) full_rqt
   521 	 (*lcp: a lot of object-logic inference to remove*)
   557 	 (*lcp: a lot of object-logic inference to remove*)
   522      val baz = R.DISCH_ALL
   558      val baz = R.DISCH_ALL
   523                  (U.itlist R.DISCH full_rqt_prop 
   559                  (U.itlist R.DISCH full_rqt_prop 
   524 		  (R.LIST_CONJ extractants))
   560 		  (R.LIST_CONJ extractants))
   525      val dum = if !trace then writeln ("baz = " ^ string_of_thm baz)
   561      val dum = if !trace then writeln ("baz = " ^ string_of_thm baz)
   526 	                   else ()
   562 	                   else ()
   527      val f_free = Free (fid, fastype_of f)  (*'cos f is a Const*)
   563      val f_free = Free (fid, fastype_of f)  (*'cos f is a Const*)
   528      val def' = R.MP (R.SPEC (tych fconst) 
   564      val SV' = map tych SV;
   529                              (R.SPEC (tych R')
   565      val SVrefls = map reflexive SV'
   530 			      (R.GENL[tych R1, tych f_free] baz)))
   566      val def0 = (U.rev_itlist (fn x => fn th => R.rbeta(combination th x))
   531                      def
   567                    SVrefls def) 
       
   568                 RS meta_eq_to_obj_eq 
       
   569      val def' = R.MP (R.SPEC (tych R') (R.GEN (tych R1) baz)) def0
   532      val body_th = R.LIST_CONJ (map R.ASSUME full_rqt_prop)
   570      val body_th = R.LIST_CONJ (map R.ASSUME full_rqt_prop)
   533      val bar = R.MP (R.ISPECL[tych R'abs, tych R1] Thms.SELECT_AX)
   571      val bar = R.MP (R.ISPECL[tych R'abs, tych R1] Thms.SELECT_AX)
   534                     body_th
   572                     body_th
   535  in {theory = theory, R=R1, SV=SV,
   573  in {theory = theory, R=R1, SV=SV,
   536      rules = U.rev_itlist (U.C R.MP) (R.CONJUNCTS bar) def',
   574      rules = U.rev_itlist (U.C R.MP) (R.CONJUNCTS bar) def',
   886     *   1. if |- tc = T, then eliminate it with eqT; otherwise,
   924     *   1. if |- tc = T, then eliminate it with eqT; otherwise,
   887     *   2. apply the terminator to tc'. If |- tc' = T then eliminate; else
   925     *   2. apply the terminator to tc'. If |- tc' = T then eliminate; else
   888     *   3. replace tc by tc' in both the rules and the induction theorem.
   926     *   3. replace tc by tc' in both the rules and the induction theorem.
   889     *---------------------------------------------------------------------*)
   927     *---------------------------------------------------------------------*)
   890 
   928 
   891 fun print_thms s L = 
   929    fun print_thms s L = 
   892   if !trace then writeln (cat_lines (s :: map string_of_thm L))
   930      if !trace then writeln (cat_lines (s :: map string_of_thm L))
   893   else ();
   931      else ();
   894 
   932 
   895 fun print_cterms s L = 
   933    fun print_cterms s L = 
   896   if !trace then writeln (cat_lines (s :: map string_of_cterm L))
   934      if !trace then writeln (cat_lines (s :: map string_of_cterm L))
   897   else ();;
   935      else ();;
   898 
   936 
   899    fun simplify_tc tc (r,ind) =
   937    fun simplify_tc tc (r,ind) =
   900        let val tc1 = tych tc
   938        let val tc1 = tych tc
   901            val _ = print_cterms "TC before simplification: " [tc1]
   939            val _ = print_cterms "TC before simplification: " [tc1]
   902            val tc_eq = simplifier tc1
   940            val tc_eq = simplifier tc1