Quot/QuotMain.thy
changeset 615 386a6b1a5203
parent 614 51a4208162ed
child 616 20b8585ad1e0
equal deleted inserted replaced
614:51a4208162ed 615:386a6b1a5203
   142 (* the auxiliary data for the quotient types *)
   142 (* the auxiliary data for the quotient types *)
   143 use "quotient_info.ML"
   143 use "quotient_info.ML"
   144 
   144 
   145 declare [[map * = (prod_fun, prod_rel)]]
   145 declare [[map * = (prod_fun, prod_rel)]]
   146 declare [[map "fun" = (fun_map, fun_rel)]]
   146 declare [[map "fun" = (fun_map, fun_rel)]]
       
   147 
   147 (* Throws now an exception:              *)
   148 (* Throws now an exception:              *)
   148 (* declare [[map "option" = (bla, blu)]] *)
   149 (* declare [[map "option" = (bla, blu)]] *)
   149 
   150 
   150 lemmas [quotient_thm] =
   151 lemmas [quotient_thm] =
   151   fun_quotient prod_quotient
   152   fun_quotient prod_quotient
   251 end
   252 end
   252 
   253 
   253 fun NDT ctxt s tac thm = tac thm  
   254 fun NDT ctxt s tac thm = tac thm  
   254 *}
   255 *}
   255 
   256 
   256 section {* Matching of terms and types *}
   257 section {* Matching of Terms and Types *}
   257 
   258 
   258 ML {*
   259 ML {*
   259 fun matches_typ (ty, ty') =
   260 fun matches_typ (ty, ty') =
   260   case (ty, ty') of
   261   case (ty, ty') of
   261     (_, TVar _) => true
   262     (_, TVar _) => true
   264        s = s' andalso 
   265        s = s' andalso 
   265        if (length tys = length tys') 
   266        if (length tys = length tys') 
   266        then (List.all matches_typ (tys ~~ tys')) 
   267        then (List.all matches_typ (tys ~~ tys')) 
   267        else false
   268        else false
   268   | _ => false
   269   | _ => false
   269 *}
   270 
   270 
       
   271 ML {*
       
   272 fun matches_term (trm, trm') = 
   271 fun matches_term (trm, trm') = 
   273    case (trm, trm') of 
   272    case (trm, trm') of 
   274      (_, Var _) => true
   273      (_, Var _) => true
   275    | (Const (s, ty), Const (s', ty')) => s = s' andalso matches_typ (ty, ty')
   274    | (Const (s, ty), Const (s', ty')) => s = s' andalso matches_typ (ty, ty')
   276    | (Free (x, ty), Free (x', ty')) => x = x' andalso matches_typ (ty, ty')
   275    | (Free (x, ty), Free (x', ty')) => x = x' andalso matches_typ (ty, ty')
   451 
   450 
   452 ML {*
   451 ML {*
   453 fun equiv_tac ctxt =
   452 fun equiv_tac ctxt =
   454   (K (print_tac "equiv tac")) THEN'
   453   (K (print_tac "equiv tac")) THEN'
   455   REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt))
   454   REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt))
   456 *}
   455 
   457 
       
   458 ML {*
       
   459 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss)
   456 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss)
   460 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac
   457 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac
   461 *}
   458 *}
   462 
   459 
   463 ML {*
   460 ML {*
   495   val thm2 = Drule.eta_contraction_rule (Drule.instantiate inst thmi)
   492   val thm2 = Drule.eta_contraction_rule (Drule.instantiate inst thmi)
   496 in
   493 in
   497   SOME thm2
   494   SOME thm2
   498 end
   495 end
   499 handle _ => NONE
   496 handle _ => NONE
   500 (* FIXME/TODO: what is the place where the exception can be raised: matching_prs? *)
   497 (* FIXME/TODO: what is the place where the exception is raised: matching_prs? *)
   501 *}
   498 *}
   502 
   499 
   503 ML {*
   500 ML {*
   504 fun ball_bex_range_simproc ss redex =
   501 fun ball_bex_range_simproc ss redex =
   505 let
   502 let
   614         val (y, s) = Term.dest_abs (x, T, t)
   611         val (y, s) = Term.dest_abs (x, T, t)
   615         val (_, s') = Term.dest_abs (x', T', t')
   612         val (_, s') = Term.dest_abs (x', T', t')
   616         val yvar = Free (y, T)
   613         val yvar = Free (y, T)
   617         val result = Term.lambda_name (y, yvar) (inj_repabs_trm lthy (s, s'))
   614         val result = Term.lambda_name (y, yvar) (inj_repabs_trm lthy (s, s'))
   618       in
   615       in
   619         if rty = qty 
   616         if rty = qty then result
   620         then result
       
   621         else mk_repabs lthy (rty, qty) result
   617         else mk_repabs lthy (rty, qty) result
   622       end
   618       end
   623 
   619 
   624   | (t $ s, t' $ s') =>  
   620   | (t $ s, t' $ s') =>  
   625        (inj_repabs_trm lthy (t, t')) $ (inj_repabs_trm lthy (s, s'))
   621        (inj_repabs_trm lthy (t, t')) $ (inj_repabs_trm lthy (s, s'))
   626 
   622 
   627   | (Free (_, T), Free (_, T')) => 
   623   | (Free (_, T), Free (_, T')) => 
   628         if T = T' 
   624         if T = T' then rtrm 
   629         then rtrm 
       
   630         else mk_repabs lthy (T, T') rtrm
   625         else mk_repabs lthy (T, T') rtrm
   631 
   626 
   632   | (_, Const (@{const_name "op ="}, _)) => rtrm
   627   | (_, Const (@{const_name "op ="}, _)) => rtrm
   633 
   628 
   634     (* FIXME: check here that rtrm is the corresponding definition for the const *)
   629     (* FIXME: check here that rtrm is the corresponding definition for the const *)
   635   | (_, Const (_, T')) =>
   630   | (_, Const (_, T')) =>
   636       let
   631       let
   637         val rty = fastype_of rtrm
   632         val rty = fastype_of rtrm
   638       in 
   633       in 
   639         if rty = T'                    
   634         if rty = T' then rtrm
   640         then rtrm
       
   641         else mk_repabs lthy (rty, T') rtrm
   635         else mk_repabs lthy (rty, T') rtrm
   642       end   
   636       end   
   643   
   637   
   644   | _ => raise (LIFT_MATCH "injection")
   638   | _ => raise (LIFT_MATCH "injection")
   645 *}
   639 *}
   649 ML {*
   643 ML {*
   650 fun quotient_tac ctxt =
   644 fun quotient_tac ctxt =
   651   REPEAT_ALL_NEW (FIRST'
   645   REPEAT_ALL_NEW (FIRST'
   652     [rtac @{thm identity_quotient},
   646     [rtac @{thm identity_quotient},
   653      resolve_tac (quotient_rules_get ctxt)])
   647      resolve_tac (quotient_rules_get ctxt)])
   654 *}
   648 
   655 
       
   656 (* solver for the simplifier *)
       
   657 ML {*
       
   658 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss)
   649 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss)
   659 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac
   650 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac
   660 *}
   651 *}
   661 
   652 
   662 ML {*
   653 ML {*
   938   val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt)
   929   val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt)
   939   val trans2 = map (OF1 @{thm equals_rsp}) (quotient_rules_get ctxt)
   930   val trans2 = map (OF1 @{thm equals_rsp}) (quotient_rules_get ctxt)
   940 in
   931 in
   941   inj_repabs_step_tac ctxt rel_refl trans2
   932   inj_repabs_step_tac ctxt rel_refl trans2
   942 end
   933 end
   943 *}
   934 
   944 
       
   945 ML {*
       
   946 fun all_inj_repabs_tac ctxt =
   935 fun all_inj_repabs_tac ctxt =
   947   REPEAT_ALL_NEW (inj_repabs_tac ctxt)
   936   REPEAT_ALL_NEW (inj_repabs_tac ctxt)
   948 (* if this is too slow we can inline the code above *)
   937 *}
   949 *}
   938 
   950 
   939 section {* Cleaning of the Theorem *}
   951 section {* Cleaning of the theorem *}
       
   952 
   940 
   953 ML {*
   941 ML {*
   954 fun make_inst lhs t =
   942 fun make_inst lhs t =
   955   let
   943   let
   956     val _ $ (Abs (_, _, (f as Var (_, Type ("fun", [T, _]))) $ u)) = lhs;
   944     val _ $ (Abs (_, _, (f as Var (_, Type ("fun", [T, _]))) $ u)) = lhs;
  1032 (* 1. conversion (is not a pattern) *)
  1020 (* 1. conversion (is not a pattern) *)
  1033 thm lambda_prs
  1021 thm lambda_prs
  1034 (* 2. folding of definitions: (rep ---> abs) oldConst == newconst *)
  1022 (* 2. folding of definitions: (rep ---> abs) oldConst == newconst *)
  1035 (*    and simplification with                                     *)
  1023 (*    and simplification with                                     *)
  1036 thm all_prs ex_prs 
  1024 thm all_prs ex_prs 
  1037 (* 3. simplification with id_simps and *)
  1025 (* 3. simplification with *)
  1038 thm fun_map.simps Quotient_abs_rep Quotient_rel_rep
  1026 thm fun_map.simps Quotient_abs_rep Quotient_rel_rep id_simps
  1039 (* 4. Test for refl *)
  1027 (* 4. Test for refl *)
  1040 
  1028 
  1041 ML {*
  1029 ML {*
  1042 fun clean_tac lthy =
  1030 fun clean_tac lthy =
  1043   let
  1031   let
  1044     val thy = ProofContext.theory_of lthy;
  1032     val thy = ProofContext.theory_of lthy;
  1045     val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
  1033     val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
  1046       (* FIXME: shouldn't the definitions already be varified? *)
  1034       (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *)
  1047     val thms1 = @{thms all_prs ex_prs} @ defs
  1035     val thms1 = @{thms all_prs ex_prs} @ defs
  1048     val thms2 = @{thms eq_reflection[OF fun_map.simps]} @ (id_simps_get lthy)
  1036     val thms2 = @{thms eq_reflection[OF fun_map.simps]} @ (id_simps_get lthy)
  1049                 @ @{thms Quotient_abs_rep Quotient_rel_rep} 
  1037                 @ @{thms Quotient_abs_rep Quotient_rel_rep} 
  1050     fun simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver
  1038     fun simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver
  1051   in
  1039   in
  1153       (rtac rule THEN' RANGE [rtac rthm', K all_tac, rtac quot_weak]) i
  1141       (rtac rule THEN' RANGE [rtac rthm', K all_tac, rtac quot_weak]) i
  1154     end)
  1142     end)
  1155 *}
  1143 *}
  1156 
  1144 
  1157 ML {*
  1145 ML {*
  1158 (* automated tactics *)
  1146 fun SOLVES' tac = tac THEN_ALL_NEW (fn _ => no_tac)
       
  1147 
       
  1148 fun WARN (tac, msg) i st =
       
  1149  case Seq.pull ((SOLVES' tac) i st) of
       
  1150      NONE    => (warning msg; Seq.single st)
       
  1151    | seqcell => Seq.make (fn () => seqcell)
       
  1152 
       
  1153 fun RANGE_WARN xs = RANGE (map WARN xs)
       
  1154 *}
       
  1155 
       
  1156 ML {*
  1159 fun lift_tac ctxt rthm =
  1157 fun lift_tac ctxt rthm =
  1160   procedure_tac ctxt rthm
  1158   procedure_tac ctxt rthm
  1161   THEN' RANGE [regularize_tac ctxt,
  1159   THEN' RANGE_WARN [(regularize_tac ctxt,     "Regularize proof failed."),
  1162                all_inj_repabs_tac ctxt,
  1160                     (all_inj_repabs_tac ctxt, "Injection proof failed."),
  1163                clean_tac ctxt]
  1161                     (clean_tac ctxt,          "Cleaning proof failed.")]
  1164 *}
  1162 *}
  1165 
  1163 
  1166 end
  1164 end
  1167 
  1165