src/HOL/Statespace/distinct_tree_prover.ML
changeset 59582 0fbed69ff081
parent 55972 51b342baecda
child 59586 ddf6deaadfe8
equal deleted inserted replaced
59580:cbc38731d42f 59582:0fbed69ff081
    88 (* Wrapper around Thm.instantiate. The type instiations of instTs are applied to
    88 (* Wrapper around Thm.instantiate. The type instiations of instTs are applied to
    89  * the right hand sides of insts
    89  * the right hand sides of insts
    90  *)
    90  *)
    91 fun instantiate instTs insts =
    91 fun instantiate instTs insts =
    92   let
    92   let
    93     val instTs' = map (fn (T, U) => (dest_TVar (typ_of T), typ_of U)) instTs;
    93     val instTs' = map (fn (T, U) => (dest_TVar (Thm.typ_of T), Thm.typ_of U)) instTs;
    94     fun substT x = (case AList.lookup (op =) instTs' x of NONE => TVar x | SOME T' => T');
    94     fun substT x = (case AList.lookup (op =) instTs' x of NONE => TVar x | SOME T' => T');
    95     fun mapT_and_recertify ct =
    95     fun mapT_and_recertify ct =
    96       let
    96       let
    97         val thy = theory_of_cterm ct;
    97         val thy = Thm.theory_of_cterm ct;
    98       in (cterm_of thy (Term.map_types (Term.map_type_tvar substT) (term_of ct))) end;
    98       in (Thm.cterm_of thy (Term.map_types (Term.map_type_tvar substT) (Thm.term_of ct))) end;
    99     val insts' = map (apfst mapT_and_recertify) insts;
    99     val insts' = map (apfst mapT_and_recertify) insts;
   100   in Thm.instantiate (instTs, insts') end;
   100   in Thm.instantiate (instTs, insts') end;
   101 
   101 
   102 fun tvar_clash ixn S S' =
   102 fun tvar_clash ixn S S' =
   103   raise TYPE ("Type variable has two distinct sorts", [TVar (ixn, S), TVar (ixn, S')], []);
   103   raise TYPE ("Type variable has two distinct sorts", [TVar (ixn, S), TVar (ixn, S')], []);
   131 fun naive_cterm_first_order_match (t, ct) env =
   131 fun naive_cterm_first_order_match (t, ct) env =
   132   let
   132   let
   133     fun mtch (env as (tyinsts, insts)) =
   133     fun mtch (env as (tyinsts, insts)) =
   134       fn (Var (ixn, T), ct) =>
   134       fn (Var (ixn, T), ct) =>
   135           (case AList.lookup (op =) insts ixn of
   135           (case AList.lookup (op =) insts ixn of
   136             NONE => (naive_typ_match (T, typ_of (ctyp_of_term ct)) tyinsts, (ixn, ct) :: insts)
   136             NONE =>
       
   137               (naive_typ_match (T, Thm.typ_of (Thm.ctyp_of_term ct)) tyinsts, (ixn, ct) :: insts)
   137           | SOME _ => env)
   138           | SOME _ => env)
   138        | (f $ t, ct) =>
   139        | (f $ t, ct) =>
   139           let val (cf, ct') = Thm.dest_comb ct;
   140           let val (cf, ct') = Thm.dest_comb ct;
   140           in mtch (mtch env (f, cf)) (t, ct') end
   141           in mtch (mtch env (f, cf)) (t, ct') end
   141        | _ => env;
   142        | _ => env;
   142   in mtch env (t, ct) end;
   143   in mtch env (t, ct) end;
   143 
   144 
   144 
   145 
   145 fun discharge prems rule =
   146 fun discharge prems rule =
   146   let
   147   let
   147     val thy = theory_of_thm (hd prems);
   148     val thy = Thm.theory_of_thm (hd prems);
   148     val (tyinsts,insts) =
   149     val (tyinsts,insts) =
   149       fold naive_cterm_first_order_match (prems_of rule ~~ map cprop_of prems) ([], []);
   150       fold naive_cterm_first_order_match (Thm.prems_of rule ~~ map Thm.cprop_of prems) ([], []);
   150 
   151 
   151     val tyinsts' =
   152     val tyinsts' =
   152       map (fn (v, (S, U)) => (ctyp_of thy (TVar (v, S)), ctyp_of thy U)) tyinsts;
   153       map (fn (v, (S, U)) =>
       
   154         (Thm.ctyp_of thy (TVar (v, S)), Thm.ctyp_of thy U)) tyinsts;
   153     val insts' =
   155     val insts' =
   154       map (fn (idxn, ct) => (cterm_of thy (Var (idxn, typ_of (ctyp_of_term ct))), ct)) insts;
   156       map (fn (idxn, ct) =>
       
   157         (Thm.cterm_of thy (Var (idxn, Thm.typ_of (Thm.ctyp_of_term ct))), ct)) insts;
   155     val rule' = Thm.instantiate (tyinsts', insts') rule;
   158     val rule' = Thm.instantiate (tyinsts', insts') rule;
   156   in fold Thm.elim_implies prems rule' end;
   159   in fold Thm.elim_implies prems rule' end;
   157 
   160 
   158 local
   161 local
   159 
   162 
   160 val (l_in_set_root, x_in_set_root, r_in_set_root) =
   163 val (l_in_set_root, x_in_set_root, r_in_set_root) =
   161   let
   164   let
   162     val (Node_l_x_d, r) =
   165     val (Node_l_x_d, r) =
   163       cprop_of @{thm in_set_root}
   166       Thm.cprop_of @{thm in_set_root}
   164       |> Thm.dest_comb |> #2
   167       |> Thm.dest_comb |> #2
   165       |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |> Thm.dest_comb;
   168       |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |> Thm.dest_comb;
   166     val (Node_l, x) = Node_l_x_d |> Thm.dest_comb |> #1 |> Thm.dest_comb;
   169     val (Node_l, x) = Node_l_x_d |> Thm.dest_comb |> #1 |> Thm.dest_comb;
   167     val l = Node_l |> Thm.dest_comb |> #2;
   170     val l = Node_l |> Thm.dest_comb |> #2;
   168   in (l,x,r) end;
   171   in (l,x,r) end;
   169 
   172 
   170 val (x_in_set_left, r_in_set_left) =
   173 val (x_in_set_left, r_in_set_left) =
   171   let
   174   let
   172     val (Node_l_x_d, r) =
   175     val (Node_l_x_d, r) =
   173       cprop_of @{thm in_set_left}
   176       Thm.cprop_of @{thm in_set_left}
   174       |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2
   177       |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2
   175       |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |> Thm.dest_comb;
   178       |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |> Thm.dest_comb;
   176     val x = Node_l_x_d |> Thm.dest_comb |> #1 |> Thm.dest_comb |> #2;
   179     val x = Node_l_x_d |> Thm.dest_comb |> #1 |> Thm.dest_comb |> #2;
   177   in (x, r) end;
   180   in (x, r) end;
   178 
   181 
   179 val (x_in_set_right, l_in_set_right) =
   182 val (x_in_set_right, l_in_set_right) =
   180   let
   183   let
   181     val (Node_l, x) =
   184     val (Node_l, x) =
   182       cprop_of @{thm in_set_right}
   185       Thm.cprop_of @{thm in_set_right}
   183       |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2
   186       |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2
   184       |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2
   187       |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2
   185       |> Thm.dest_comb |> #1 |> Thm.dest_comb |> #1
   188       |> Thm.dest_comb |> #1 |> Thm.dest_comb |> #1
   186       |> Thm.dest_comb;
   189       |> Thm.dest_comb;
   187     val l = Node_l |> Thm.dest_comb |> #2;
   190     val l = Node_l |> Thm.dest_comb |> #2;
   205             (case p of Left => @{thm all_distinct_left} | Right => @{thm all_distinct_right})
   208             (case p of Left => @{thm all_distinct_left} | Right => @{thm all_distinct_right})
   206          in dist_subtree ps (discharge [thm] rule) end;
   209          in dist_subtree ps (discharge [thm] rule) end;
   207 
   210 
   208     val (ps, x_rest, y_rest) = split_common_prefix x_path y_path;
   211     val (ps, x_rest, y_rest) = split_common_prefix x_path y_path;
   209     val dist_subtree_thm = dist_subtree ps dist_thm;
   212     val dist_subtree_thm = dist_subtree ps dist_thm;
   210     val subtree = cprop_of dist_subtree_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   213     val subtree = Thm.cprop_of dist_subtree_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   211     val (_, [l, _, _, r]) = Drule.strip_comb subtree;
   214     val (_, [l, _, _, r]) = Drule.strip_comb subtree;
   212 
   215 
   213     fun in_set ps tree =
   216     fun in_set ps tree =
   214       let
   217       let
   215         val (_, [l, x, _, r]) = Drule.strip_comb tree;
   218         val (_, [l, x, _, r]) = Drule.strip_comb tree;
   216         val xT = ctyp_of_term x;
   219         val xT = Thm.ctyp_of_term x;
   217       in
   220       in
   218         (case ps of
   221         (case ps of
   219           [] =>
   222           [] =>
   220             instantiate
   223             instantiate
   221               [(ctyp_of_term x_in_set_root, xT)]
   224               [(Thm.ctyp_of_term x_in_set_root, xT)]
   222               [(l_in_set_root, l), (x_in_set_root, x), (r_in_set_root, r)] @{thm in_set_root}
   225               [(l_in_set_root, l), (x_in_set_root, x), (r_in_set_root, r)] @{thm in_set_root}
   223         | Left :: ps' =>
   226         | Left :: ps' =>
   224             let
   227             let
   225               val in_set_l = in_set ps' l;
   228               val in_set_l = in_set ps' l;
   226               val in_set_left' =
   229               val in_set_left' =
   227                 instantiate
   230                 instantiate
   228                   [(ctyp_of_term x_in_set_left, xT)]
   231                   [(Thm.ctyp_of_term x_in_set_left, xT)]
   229                   [(x_in_set_left, x), (r_in_set_left, r)] @{thm in_set_left};
   232                   [(x_in_set_left, x), (r_in_set_left, r)] @{thm in_set_left};
   230             in discharge [in_set_l] in_set_left' end
   233             in discharge [in_set_l] in_set_left' end
   231         | Right :: ps' =>
   234         | Right :: ps' =>
   232             let
   235             let
   233               val in_set_r = in_set ps' r;
   236               val in_set_r = in_set ps' r;
   234               val in_set_right' =
   237               val in_set_right' =
   235                 instantiate
   238                 instantiate
   236                   [(ctyp_of_term x_in_set_right, xT)]
   239                   [(Thm.ctyp_of_term x_in_set_right, xT)]
   237                   [(x_in_set_right, x), (l_in_set_right, l)] @{thm in_set_right};
   240                   [(x_in_set_right, x), (l_in_set_right, l)] @{thm in_set_right};
   238             in discharge [in_set_r] in_set_right' end)
   241             in discharge [in_set_r] in_set_right' end)
   239       end;
   242       end;
   240 
   243 
   241   fun in_set' [] = raise TERM ("distinctTreeProver", [])
   244   fun in_set' [] = raise TERM ("distinctTreeProver", [])
   284     let
   287     let
   285       val ct =
   288       val ct =
   286         @{thm subtract_Tip} |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2
   289         @{thm subtract_Tip} |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2
   287         |> Thm.dest_comb |> #2;
   290         |> Thm.dest_comb |> #2;
   288       val [alpha] = ct |> Thm.ctyp_of_term |> Thm.dest_ctyp;
   291       val [alpha] = ct |> Thm.ctyp_of_term |> Thm.dest_ctyp;
   289     in (alpha, #1 (dest_Var (term_of ct))) end;
   292     in (alpha, #1 (dest_Var (Thm.term_of ct))) end;
   290 in
   293 in
   291 
   294 
   292 fun subtractProver (Const (@{const_name Tip}, T)) ct dist_thm =
   295 fun subtractProver (Const (@{const_name Tip}, T)) ct dist_thm =
   293       let
   296       let
   294         val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   297         val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   295         val thy = theory_of_cterm ct;
   298         val thy = Thm.theory_of_cterm ct;
   296         val [alphaI] = #2 (dest_Type T);
   299         val [alphaI] = #2 (dest_Type T);
   297       in
   300       in
   298         Thm.instantiate
   301         Thm.instantiate
   299           ([(alpha, ctyp_of thy alphaI)],
   302           ([(alpha, Thm.ctyp_of thy alphaI)],
   300            [(cterm_of thy (Var (v, treeT alphaI)), ct')]) @{thm subtract_Tip}
   303            [(Thm.cterm_of thy (Var (v, treeT alphaI)), ct')]) @{thm subtract_Tip}
   301       end
   304       end
   302   | subtractProver (Const (@{const_name Node}, nT) $ l $ x $ d $ r) ct dist_thm =
   305   | subtractProver (Const (@{const_name Node}, nT) $ l $ x $ d $ r) ct dist_thm =
   303       let
   306       let
   304         val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   307         val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   305         val (_, [cl, _, _, cr]) = Drule.strip_comb ct;
   308         val (_, [cl, _, _, cr]) = Drule.strip_comb ct;
   306         val ps = the (find_tree x (term_of ct'));
   309         val ps = the (find_tree x (Thm.term_of ct'));
   307         val del_tree = deleteProver dist_thm ps;
   310         val del_tree = deleteProver dist_thm ps;
   308         val dist_thm' = discharge [del_tree, dist_thm] @{thm delete_Some_all_distinct};
   311         val dist_thm' = discharge [del_tree, dist_thm] @{thm delete_Some_all_distinct};
   309         val sub_l = subtractProver (term_of cl) cl (dist_thm');
   312         val sub_l = subtractProver (Thm.term_of cl) cl (dist_thm');
   310         val sub_r =
   313         val sub_r =
   311           subtractProver (term_of cr) cr
   314           subtractProver (Thm.term_of cr) cr
   312             (discharge [sub_l, dist_thm'] @{thm subtract_Some_all_distinct_res});
   315             (discharge [sub_l, dist_thm'] @{thm subtract_Some_all_distinct_res});
   313       in discharge [del_tree, sub_l, sub_r] @{thm subtract_Node} end;
   316       in discharge [del_tree, sub_l, sub_r] @{thm subtract_Node} end;
   314 
   317 
   315 end;
   318 end;
   316 
   319 
   317 fun distinct_implProver dist_thm ct =
   320 fun distinct_implProver dist_thm ct =
   318   let
   321   let
   319     val ctree = ct |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   322     val ctree = ct |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   320     val sub = subtractProver (term_of ctree) ctree dist_thm;
   323     val sub = subtractProver (Thm.term_of ctree) ctree dist_thm;
   321   in @{thm subtract_Some_all_distinct} OF [sub, dist_thm] end;
   324   in @{thm subtract_Some_all_distinct} OF [sub, dist_thm] end;
   322 
   325 
   323 fun get_fst_success f [] = NONE
   326 fun get_fst_success f [] = NONE
   324   | get_fst_success f (x :: xs) =
   327   | get_fst_success f (x :: xs) =
   325       (case f x of
   328       (case f x of
   327       | SOME v => SOME v);
   330       | SOME v => SOME v);
   328 
   331 
   329 fun neq_x_y ctxt x y name =
   332 fun neq_x_y ctxt x y name =
   330   (let
   333   (let
   331     val dist_thm = the (try (Proof_Context.get_thm ctxt) name);
   334     val dist_thm = the (try (Proof_Context.get_thm ctxt) name);
   332     val ctree = cprop_of dist_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   335     val ctree = Thm.cprop_of dist_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   333     val tree = term_of ctree;
   336     val tree = Thm.term_of ctree;
   334     val x_path = the (find_tree x tree);
   337     val x_path = the (find_tree x tree);
   335     val y_path = the (find_tree y tree);
   338     val y_path = the (find_tree y tree);
   336     val thm = distinctTreeProver dist_thm x_path y_path;
   339     val thm = distinctTreeProver dist_thm x_path y_path;
   337   in SOME thm
   340   in SOME thm
   338   end handle Option.Option => NONE);
   341   end handle Option.Option => NONE);