Quot/quotient_tacs.ML
changeset 802 27a643e00675
parent 789 8237786171f1
child 804 ba7e81531c6d
equal deleted inserted replaced
801:282fe9cc278e 802:27a643e00675
    12 struct
    12 struct
    13 
    13 
    14 open Quotient_Info;
    14 open Quotient_Info;
    15 open Quotient_Term;
    15 open Quotient_Term;
    16 
    16 
       
    17 (* various helper fuctions *)
       
    18 
    17 (* Since HOL_basic_ss is too "big" for us, we *)
    19 (* Since HOL_basic_ss is too "big" for us, we *)
    18 (* need to set up our own minimal simpset.    *)
    20 (* need to set up our own minimal simpset.    *)
    19 fun  mk_minimal_ss ctxt =
    21 fun  mk_minimal_ss ctxt =
    20   Simplifier.context ctxt empty_ss
    22   Simplifier.context ctxt empty_ss
    21     setsubgoaler asm_simp_tac
    23     setsubgoaler asm_simp_tac
    22     setmksimps (mksimps [])
    24     setmksimps (mksimps [])
    23 
    25 
    24 (* various helper fuctions *)
       
    25 
       
    26 (* composition of two theorems, used in maps *)
    26 (* composition of two theorems, used in maps *)
    27 fun OF1 thm1 thm2 = thm2 RS thm1
    27 fun OF1 thm1 thm2 = thm2 RS thm1
    28 
    28 
    29 (* makes sure a subgoal is solved *)
    29 (* makes sure a subgoal is solved *)
    30 fun SOLVES' tac = tac THEN_ALL_NEW (K no_tac)
    30 fun SOLVES' tac = tac THEN_ALL_NEW (K no_tac)
    31 
    31 
    32 (* prints warning, if the subgoal is unsolved *)
    32 (* prints a warning, if the subgoal is not solved *)
    33 fun WARN (tac, msg) i st =
    33 fun WARN (tac, msg) i st =
    34  case Seq.pull ((SOLVES' tac) i st) of
    34  case Seq.pull ((SOLVES' tac) i st) of
    35      NONE    => (warning msg; Seq.single st)
    35      NONE    => (warning msg; Seq.single st)
    36    | seqcell => Seq.make (fn () => seqcell)
    36    | seqcell => Seq.make (fn () => seqcell)
    37 
    37 
    38 fun RANGE_WARN xs = RANGE (map WARN xs)
    38 fun RANGE_WARN tacs = RANGE (map WARN tacs)
    39 
    39 
    40 fun atomize_thm thm =
    40 fun atomize_thm thm =
    41 let
    41 let
    42   val thm' = Thm.freezeT (forall_intr_vars thm)
    42   val thm' = Thm.freezeT (forall_intr_vars thm) (* TODO: is this proper Isar-technology? *)
    43   val thm'' = ObjectLogic.atomize (cprop_of thm')
    43   val thm'' = ObjectLogic.atomize (cprop_of thm')
    44 in
    44 in
    45   @{thm equal_elim_rule1} OF [thm'', thm']
    45   @{thm equal_elim_rule1} OF [thm'', thm']
    46 end
    46 end
    47 
    47 
    49 (*********************)
    49 (*********************)
    50 (* Regularize Tactic *)
    50 (* Regularize Tactic *)
    51 (*********************)
    51 (*********************)
    52 
    52 
    53 (* solvers for equivp and quotient assumptions *)
    53 (* solvers for equivp and quotient assumptions *)
    54 fun equiv_tac ctxt =
    54 (* FIXME / TODO: should this SOLVES' the goal, like with quotient_tac? *)
       
    55 (* FIXME / TODO: none of te examples break if added                    *)
       
    56 fun equiv_tac ctxt = 
    55   REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt))
    57   REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt))
    56 
    58 
    57 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss)
    59 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss)
    58 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac
    60 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac
    59 
    61 
    60 (* test whether DETERM makes any difference *)
    62 (* FIXME / TODO: test whether DETERM makes any runtime-difference *)
       
    63 (* FIXME / TODO: reason: it might back-track over the two alternatives in FIRST' *)
    61 fun quotient_tac ctxt = SOLVES'  
    64 fun quotient_tac ctxt = SOLVES'  
    62   (REPEAT_ALL_NEW (FIRST'
    65   (REPEAT_ALL_NEW (FIRST'
    63     [rtac @{thm identity_quotient},
    66     [rtac @{thm identity_quotient},
    64      resolve_tac (quotient_rules_get ctxt)]))
    67      resolve_tac (quotient_rules_get ctxt)]))
    65 
    68 
    67 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac
    70 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac
    68 
    71 
    69 fun solve_quotient_assm ctxt thm =
    72 fun solve_quotient_assm ctxt thm =
    70   case Seq.pull (quotient_tac ctxt 1 thm) of
    73   case Seq.pull (quotient_tac ctxt 1 thm) of
    71     SOME (t, _) => t
    74     SOME (t, _) => t
    72   | _ => error "solve_quotient_assm failed. Maybe a quotient_thm is missing"
    75   | _ => error "Solve_quotient_assm failed. Possibly a quotient theorem is missing."
    73 
    76 
    74 
    77 
    75 fun prep_trm thy (x, (T, t)) =
    78 fun prep_trm thy (x, (T, t)) =
    76   (cterm_of thy (Var (x, T)), cterm_of thy t)
    79   (cterm_of thy (Var (x, T)), cterm_of thy t)
    77 
    80 
   264   val thm = Drule.instantiate' 
   267   val thm = Drule.instantiate' 
   265                [SOME (ctyp_of thy ty)] [SOME (cterm_of thy R)] @{thm equals_rsp}
   268                [SOME (ctyp_of thy ty)] [SOME (cterm_of thy R)] @{thm equals_rsp}
   266 in
   269 in
   267   rtac thm THEN' quotient_tac ctxt
   270   rtac thm THEN' quotient_tac ctxt
   268 end
   271 end
   269 (* Are they raised by instantiate'? *)
   272 (* TODO: Are they raised by instantiate'? *)
       
   273 (* TODO: Again, can one specify more concretely when no_tac should be returned? *)
   270 handle THM _  => K no_tac  
   274 handle THM _  => K no_tac  
   271      | TYPE _ => K no_tac    
   275      | TYPE _ => K no_tac    
   272      | TERM _ => K no_tac
   276      | TERM _ => K no_tac
   273 
   277 
   274 
   278 
   283            val t_inst = map (SOME o (cterm_of thy)) [rel, abs, rep];
   287            val t_inst = map (SOME o (cterm_of thy)) [rel, abs, rep];
   284            val inst_thm = Drule.instantiate' ty_inst t_inst @{thm rep_abs_rsp}
   288            val inst_thm = Drule.instantiate' ty_inst t_inst @{thm rep_abs_rsp}
   285          in
   289          in
   286            (rtac inst_thm THEN' quotient_tac ctxt) i
   290            (rtac inst_thm THEN' quotient_tac ctxt) i
   287          end
   291          end
   288          handle THM _ => no_tac | TYPE _ => no_tac)
   292          handle THM _ => no_tac | TYPE _ => no_tac) (* TODO: same here *)
   289     | _ => no_tac)
   293     | _ => no_tac)
   290 
   294 
   291 
   295 
   292 (* FIXME /TODO needs to be adapted *)
   296 (* FIXME / TODO needs to be adapted *)
   293 (*
   297 (*
   294 To prove that the regularised theorem implies the abs/rep injected, 
   298 To prove that the regularised theorem implies the abs/rep injected, 
   295 we try:
   299 we try:
   296 
   300 
   297  1) theorems 'trans2' from the appropriate Quot_Type
   301  1) theorems 'trans2' from the appropriate Quot_Type
   406 
   410 
   407 (***************************)
   411 (***************************)
   408 (* Cleaning of the Theorem *)
   412 (* Cleaning of the Theorem *)
   409 (***************************)
   413 (***************************)
   410 
   414 
   411 (* expands all fun_maps, except in front of bound variables *)
   415 (* expands all fun_maps, except in front of the bound *)
       
   416 (* variables listed in xs                             *)
   412 fun fun_map_simple_conv xs ctrm =
   417 fun fun_map_simple_conv xs ctrm =
   413   case (term_of ctrm) of
   418   case (term_of ctrm) of
   414     ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) =>
   419     ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) =>
   415         if (member (op=) xs h) 
   420         if (member (op=) xs h) 
   416         then Conv.all_conv ctrm
   421         then Conv.all_conv ctrm
   475               else make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm)
   480               else make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm)
   476        val ti = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts
   481        val ti = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts
   477      in
   482      in
   478        Conv.rewr_conv ti ctrm
   483        Conv.rewr_conv ti ctrm
   479      end
   484      end
   480      handle _ => Conv.all_conv ctrm)
   485      handle _ => Conv.all_conv ctrm) (* TODO: another catch all - can this be improved? *)
   481   | _ => Conv.all_conv ctrm
   486   | _ => Conv.all_conv ctrm
   482 
   487 
   483 
   488 
   484 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt
   489 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt
   485 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt)
   490 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt)
   502 (*                                                     *)
   507 (*                                                     *)
   503 (* 5. test for refl                                    *)
   508 (* 5. test for refl                                    *)
   504 
   509 
   505 fun clean_tac_aux lthy =
   510 fun clean_tac_aux lthy =
   506 let
   511 let
   507   (*FIXME produce defs with lthy, like prs and ids *)
   512   (* FIXME/TODO produce defs with lthy, like prs and ids *)
   508   val thy = ProofContext.theory_of lthy;
   513   val thy = ProofContext.theory_of lthy;
   509   val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
   514   val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
   510    (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *)
   515   (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *)
   511   val prs = prs_rules_get lthy
   516   val prs = prs_rules_get lthy
   512   val ids = id_simps_get lthy
   517   val ids = id_simps_get lthy
   513   
   518   
   514   fun mk_simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver
   519   fun mk_simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver
   515   val ss1 = mk_simps (defs @ prs @ @{thms babs_prs all_prs ex_prs})
   520   val ss1 = mk_simps (defs @ prs @ @{thms babs_prs all_prs ex_prs})
   568 (* - 2nd prem is the rep/abs injection step              *)
   573 (* - 2nd prem is the rep/abs injection step              *)
   569 (* - 3rd prem is the cleaning part                       *)
   574 (* - 3rd prem is the cleaning part                       *)
   570 (*                                                       *)
   575 (*                                                       *)
   571 (* the Quot_True premise in 2 records the lifted theorem *)
   576 (* the Quot_True premise in 2 records the lifted theorem *)
   572 
   577 
   573 val lifting_procedure = 
   578 val lifting_procedure_thm = 
   574    @{lemma  "[|A; 
   579    @{lemma  "[|A; 
   575                A --> B; 
   580                A --> B; 
   576                Quot_True D ==> B = C; 
   581                Quot_True D ==> B = C; 
   577                C = D|] ==> D" 
   582                C = D|] ==> D" 
   578       by (simp add: Quot_True_def)}
   583       by (simp add: Quot_True_def)}
   599 in
   604 in
   600   Drule.instantiate' []
   605   Drule.instantiate' []
   601     [SOME (cterm_of thy rtrm'),
   606     [SOME (cterm_of thy rtrm'),
   602      SOME (cterm_of thy reg_goal),
   607      SOME (cterm_of thy reg_goal),
   603      NONE,
   608      NONE,
   604      SOME (cterm_of thy inj_goal)] lifting_procedure
   609      SOME (cterm_of thy inj_goal)] lifting_procedure_thm
   605 end
   610 end
   606 
       
   607 
   611 
   608 (* the tactic leaves three subgoals to be proved *)
   612 (* the tactic leaves three subgoals to be proved *)
   609 fun procedure_tac ctxt rthm =
   613 fun procedure_tac ctxt rthm =
   610   ObjectLogic.full_atomize_tac
   614   ObjectLogic.full_atomize_tac
   611   THEN' gen_frees_tac ctxt
   615   THEN' gen_frees_tac ctxt