Quot/quotient_tacs.ML
changeset 858 bb012513fb39
parent 857 0ce025c02ef3
child 860 e18c691335db
equal deleted inserted replaced
857:0ce025c02ef3 858:bb012513fb39
    95 in
    95 in
    96   (map (prep_ty thy) tyenv, map (prep_trm thy) tenv)
    96   (map (prep_ty thy) tyenv, map (prep_trm thy) tenv)
    97 end
    97 end
    98 
    98 
    99 (* Calculates the instantiations for the lemmas:
    99 (* Calculates the instantiations for the lemmas:
       
   100 
   100       ball_reg_eqv_range and bex_reg_eqv_range
   101       ball_reg_eqv_range and bex_reg_eqv_range
       
   102 
   101    Since the left-hand-side contains a non-pattern '?P (f ?x)'
   103    Since the left-hand-side contains a non-pattern '?P (f ?x)'
   102    we rely on unification/instantiation to check whether the
   104    we rely on unification/instantiation to check whether the
   103    theorem applies and return NONE if it doesn't. *)
   105    theorem applies and return NONE if it doesn't. 
       
   106 *)
   104 fun calculate_inst ctxt ball_bex_thm redex R1 R2 =
   107 fun calculate_inst ctxt ball_bex_thm redex R1 R2 =
   105 let
   108 let
   106   fun get_lhs thm = fst (Logic.dest_equals (Thm.concl_of thm))
   109   fun get_lhs thm = fst (Logic.dest_equals (Thm.concl_of thm))
   107   val thy = ProofContext.theory_of ctxt
   110   val thy = ProofContext.theory_of ctxt
   108   val typ_inst1 = map (SOME o ctyp_of thy) [domain_type (fastype_of R2)]
   111   val typ_inst1 = map (SOME o ctyp_of thy) [domain_type (fastype_of R2)]
   109   val trm_inst1 = map (SOME o cterm_of thy) [R2, R1]
   112   val trm_inst1 = map (SOME o cterm_of thy) [R2, R1]
   110 in
   113 in
   111   (case try (Drule.instantiate' typ_inst1 trm_inst1) ball_bex_thm of
   114   case try (Drule.instantiate' typ_inst1 trm_inst1) ball_bex_thm of
   112     NONE => NONE
   115     NONE => NONE
   113   | SOME thm' =>
   116   | SOME thm' =>
   114       (case try (get_match_inst thy (get_lhs thm')) redex of
   117       (case try (get_match_inst thy (get_lhs thm')) redex of
   115         NONE => NONE
   118         NONE => NONE
   116       | SOME inst2 => try (Drule.instantiate inst2) thm')
   119       | SOME inst2 => try (Drule.instantiate inst2) thm')
   117   )
       
   118 end
   120 end
   119 
   121 
   120 fun ball_bex_range_simproc ss redex =
   122 fun ball_bex_range_simproc ss redex =
   121 let
   123 let
   122   val ctxt = Simplifier.the_context ss
   124   val ctxt = Simplifier.the_context ss
   131         calculate_inst ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2
   133         calculate_inst ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2
   132 
   134 
   133   | _ => NONE
   135   | _ => NONE
   134 end
   136 end
   135 
   137 
   136 (*
   138 (* Regularize works as follows:
   137 0. preliminary simplification step according to
   139 
   138    ball_reg_eqv bex_reg_eqv babs_reg_eqv ball_reg_eqv_range bex_reg_eqv_range
   140   0. preliminary simplification step according to
   139 
   141      ball_reg_eqv bex_reg_eqv babs_reg_eqv ball_reg_eqv_range bex_reg_eqv_range
   140 1. eliminating simple Ball/Bex instances (ball_reg_right bex_reg_left)
   142 
   141 
   143   1. eliminating simple Ball/Bex instances (ball_reg_right bex_reg_left)
   142 2. monos
   144 
   143 
   145   2. monos
   144 3. commutation rules for ball and bex (ball_all_comm bex_ex_comm)
   146 
   145 
   147   3. commutation rules for ball and bex (ball_all_comm bex_ex_comm)
   146 4. then rel-equalities, which need to be instantiated with 'eq_imp_rel'
   148 
   147    to avoid loops
   149   4. then rel-equalities, which need to be instantiated with 'eq_imp_rel'
   148 
   150      to avoid loops
   149 5. then simplification like 0
   151 
   150 
   152   5. then simplification like 0
   151 finally jump back to 1 *)
   153 
       
   154   finally jump back to 1 
       
   155 *)
   152 fun regularize_tac ctxt =
   156 fun regularize_tac ctxt =
   153 let
   157 let
   154   val thy = ProofContext.theory_of ctxt
   158   val thy = ProofContext.theory_of ctxt
   155   val ball_pat = @{term "Ball (Respects (R1 ===> R2)) P"}
   159   val ball_pat = @{term "Ball (Respects (R1 ===> R2)) P"}
   156   val bex_pat  = @{term "Bex (Respects (R1 ===> R2)) P"}
   160   val bex_pat  = @{term "Bex (Respects (R1 ===> R2)) P"}
   173 
   177 
   174 
   178 
   175 (*** Injection Tactic ***)
   179 (*** Injection Tactic ***)
   176 
   180 
   177 (* Looks for Quot_True assumtions, and in case its parameter
   181 (* Looks for Quot_True assumtions, and in case its parameter
   178    is an application, it returns the function and the argument. *)
   182    is an application, it returns the function and the argument. 
       
   183 *)
   179 fun find_qt_asm asms =
   184 fun find_qt_asm asms =
   180 let
   185 let
   181   fun find_fun trm =
   186   fun find_fun trm =
   182     case trm of
   187     case trm of
   183       (Const(@{const_name Trueprop}, _) $ (Const (@{const_name Quot_True}, _) $ _)) => true
   188       (Const(@{const_name Trueprop}, _) $ (Const (@{const_name Quot_True}, _) $ _)) => true
   229 
   234 
   230 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl
   235 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl
   231 
   236 
   232 (* We apply apply_rsp only in case if the type needs lifting.
   237 (* We apply apply_rsp only in case if the type needs lifting.
   233    This is the case if the type of the data in the Quot_True
   238    This is the case if the type of the data in the Quot_True
   234    assumption is different from the corresponding type in the goal. *)
   239    assumption is different from the corresponding type in the goal. 
       
   240 *)
   235 val apply_rsp_tac =
   241 val apply_rsp_tac =
   236   Subgoal.FOCUS (fn {concl, asms, context,...} =>
   242   Subgoal.FOCUS (fn {concl, asms, context,...} =>
   237   let
   243   let
   238     val bare_concl = HOLogic.dest_Trueprop (term_of concl)
   244     val bare_concl = HOLogic.dest_Trueprop (term_of concl)
   239     val qt_asm = find_qt_asm (map term_of asms)
   245     val qt_asm = find_qt_asm (map term_of asms)
   257            end
   263            end
   258     | _ => no_tac
   264     | _ => no_tac
   259   end)
   265   end)
   260 
   266 
   261 (* Instantiates and applies 'equals_rsp'. Since the theorem is
   267 (* Instantiates and applies 'equals_rsp'. Since the theorem is
   262    complex we rely on instantiation to tell us if it applies *)
   268    complex we rely on instantiation to tell us if it applies 
       
   269 *)
   263 fun equals_rsp_tac R ctxt =
   270 fun equals_rsp_tac R ctxt =
   264 let
   271 let
   265   val thy = ProofContext.theory_of ctxt
   272   val thy = ProofContext.theory_of ctxt
   266 in
   273 in
   267   case try (cterm_of thy) R of (* There can be loose bounds in R *)
   274   case try (cterm_of thy) R of (* There can be loose bounds in R *)
   296           | NONE => no_tac
   303           | NONE => no_tac
   297         end
   304         end
   298     | _ => no_tac)
   305     | _ => no_tac)
   299 
   306 
   300 
   307 
   301 (*
   308 
   302 To prove that the regularised theorem implies the abs/rep injected,
   309 (* Injection means to prove that the regularised theorem implies 
   303 we try:
   310    the abs/rep injected one.
   304 
   311 
   305  The deterministic part:
   312    The deterministic part:
   306  -) remove lambdas from both sides
   313     - remove lambdas from both sides
   307  -) prove Ball/Bex/Babs equalities using ball_rsp, bex_rsp, babs_rsp
   314     - prove Ball/Bex/Babs equalities using ball_rsp, bex_rsp, babs_rsp
   308  -) prove Ball/Bex relations unfolding fun_rel_id
   315     - prove Ball/Bex relations unfolding fun_rel_id
   309  -) reflexivity of equality
   316     - reflexivity of equality
   310  -) prove equality of relations using equals_rsp
   317     - prove equality of relations using equals_rsp
   311  -) use user-supplied RSP theorems
   318     - use user-supplied RSP theorems
   312  -) solve 'relation of relations' goals using quot_rel_rsp
   319     - solve 'relation of relations' goals using quot_rel_rsp
   313  -) remove rep_abs from the right side
   320     - remove rep_abs from the right side
   314     (Lambdas under respects may have left us some assumptions)
   321       (Lambdas under respects may have left us some assumptions)
   315  Then in order:
   322  
   316  -) split applications of lifted type (apply_rsp)
   323    Then in order:
   317  -) split applications of non-lifted type (cong_tac)
   324     - split applications of lifted type (apply_rsp)
   318  -) apply extentionality
   325     - split applications of non-lifted type (cong_tac)
   319  -) assumption
   326     - apply extentionality
   320  -) reflexivity of the relation
   327     - assumption
   321 *)
   328     - reflexivity of the relation
   322 
   329 *)
   323 
       
   324 fun injection_match_tac ctxt = SUBGOAL (fn (goal, i) =>
   330 fun injection_match_tac ctxt = SUBGOAL (fn (goal, i) =>
   325 (case (bare_concl goal) of
   331 (case (bare_concl goal) of
   326     (* (R1 ===> R2) (%x...) (%x...) ----> [|R1 x y|] ==> R2 (...x) (...y) *)
   332     (* (R1 ===> R2) (%x...) (%x...) ----> [|R1 x y|] ==> R2 (...x) (...y) *)
   327   (Const (@{const_name fun_rel}, _) $ _ $ _) $ (Abs _) $ (Abs _)
   333   (Const (@{const_name fun_rel}, _) $ _ $ _) $ (Abs _) $ (Abs _)
   328       => rtac @{thm fun_rel_id} THEN' quot_true_tac ctxt unlam
   334       => rtac @{thm fun_rel_id} THEN' quot_true_tac ctxt unlam
   410 fun all_injection_tac ctxt =
   416 fun all_injection_tac ctxt =
   411   REPEAT_ALL_NEW (injection_tac ctxt)
   417   REPEAT_ALL_NEW (injection_tac ctxt)
   412 
   418 
   413 
   419 
   414 
   420 
   415 (** Cleaning of the Theorem **)
   421 (*** Cleaning of the Theorem ***)
   416 
   422 
   417 (* expands all fun_maps, except in front of the bound variables listed in xs *)
   423 (* expands all fun_maps, except in front of the bound variables listed in xs *)
   418 fun fun_map_simple_conv xs ctrm =
   424 fun fun_map_simple_conv xs ctrm =
   419   case (term_of ctrm) of
   425   case (term_of ctrm) of
   420     ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) =>
   426     ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) =>
   460 (* Simplifies a redex using the 'lambda_prs' theorem.
   466 (* Simplifies a redex using the 'lambda_prs' theorem.
   461    First instantiates the types and known subterms.
   467    First instantiates the types and known subterms.
   462    Then solves the quotient assumptions to get Rep2 and Abs1
   468    Then solves the quotient assumptions to get Rep2 and Abs1
   463    Finally instantiates the function f using make_inst
   469    Finally instantiates the function f using make_inst
   464    If Rep2 is an identity then the pattern is simpler and
   470    If Rep2 is an identity then the pattern is simpler and
   465    make_inst_id is used *)
   471    make_inst_id is used 
       
   472 *)
   466 fun lambda_prs_simple_conv ctxt ctrm =
   473 fun lambda_prs_simple_conv ctxt ctrm =
   467   case (term_of ctrm) of
   474   case (term_of ctrm) of
   468     (Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _) =>
   475     (Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _) =>
   469       let
   476       let
   470         val thy = ProofContext.theory_of ctxt
   477         val thy = ProofContext.theory_of ctxt
   488 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt
   495 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt
   489 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt)
   496 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt)
   490 
   497 
   491 
   498 
   492 (* Cleaning consists of:
   499 (* Cleaning consists of:
   493  1. folding of definitions and preservation lemmas;
   500 
   494     and simplification with babs_prs all_prs ex_prs
   501   1. folding of definitions and preservation lemmas;
   495 
   502      and simplification with babs_prs all_prs ex_prs
   496  2. unfolding of ---> in front of everything, except
   503 
   497     bound variables
   504   2. unfolding of ---> in front of everything, except
   498     (this prevents lambda_prs from becoming stuck)
   505      bound variables
   499 
   506      (this prevents lambda_prs from becoming stuck)
   500  3. simplification with lambda_prs
   507 
   501 
   508   3. simplification with lambda_prs
   502  4. simplification with Quotient_abs_rep Quotient_rel_rep id_simps
   509 
   503 
   510   4. simplification with Quotient_abs_rep Quotient_rel_rep id_simps
   504  5. test for refl *)
   511 
       
   512   5. test for refl 
       
   513 *)
   505 fun clean_tac lthy =
   514 fun clean_tac lthy =
   506 let
   515 let
   507   (* FIXME/TODO produce defs with lthy, like prs and ids *)
   516   (* FIXME/TODO produce defs with lthy, like prs and ids *)
   508   val thy = ProofContext.theory_of lthy;
   517   val thy = ProofContext.theory_of lthy;
   509   val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
   518   val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
   523 end
   532 end
   524 
   533 
   525 
   534 
   526 
   535 
   527 (** Tactic for Generalising Free Variables in a Goal **)
   536 (** Tactic for Generalising Free Variables in a Goal **)
   528 
       
   529 
   537 
   530 fun inst_spec ctrm =
   538 fun inst_spec ctrm =
   531    Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}
   539    Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}
   532 
   540 
   533 fun inst_spec_tac ctrms =
   541 fun inst_spec_tac ctrms =
   554     end)
   562     end)
   555 
   563 
   556 
   564 
   557 (** The General Shape of the Lifting Procedure **)
   565 (** The General Shape of the Lifting Procedure **)
   558 
   566 
   559 
       
   560 (* - A is the original raw theorem
   567 (* - A is the original raw theorem
   561  - B is the regularized theorem
   568    - B is the regularized theorem
   562  - C is the rep/abs injected version of B
   569    - C is the rep/abs injected version of B
   563  - D is the lifted theorem
   570    - D is the lifted theorem
   564 
   571 
   565  - 1st prem is the regularization step
   572    - 1st prem is the regularization step
   566  - 2nd prem is the rep/abs injection step
   573    - 2nd prem is the rep/abs injection step
   567  - 3rd prem is the cleaning part
   574    - 3rd prem is the cleaning part
   568 
   575 
   569  the Quot_True premise in 2nd records the lifted theorem *)
   576    the Quot_True premise in 2nd records the lifted theorem 
       
   577 *)
   570 val lifting_procedure_thm =
   578 val lifting_procedure_thm =
   571   @{lemma  "[|A;
   579   @{lemma  "[|A;
   572               A --> B;
   580               A --> B;
   573               Quot_True D ==> B = C;
   581               Quot_True D ==> B = C;
   574               C = D|] ==> D"
   582               C = D|] ==> D"