src/HOL/Statespace/distinct_tree_prover.ML
changeset 74587 ebb0b15c66e1
parent 74282 c2ee8d993d6a
child 74588 3cc363e8bfb2
equal deleted inserted replaced
74586:5ac762b53119 74587:ebb0b15c66e1
     7   datatype direction = Left | Right
     7   datatype direction = Left | Right
     8   val mk_tree : ('a -> term) -> typ -> 'a list -> term
     8   val mk_tree : ('a -> term) -> typ -> 'a list -> term
     9   val dest_tree : term -> term list
     9   val dest_tree : term -> term list
    10   val find_tree : term -> term -> direction list option
    10   val find_tree : term -> term -> direction list option
    11 
    11 
       
    12   val in_set: Proof.context -> direction list -> cterm -> thm
       
    13   val find_in_set: Proof.context -> term -> cterm -> thm
    12   val neq_to_eq_False : thm
    14   val neq_to_eq_False : thm
    13   val distinctTreeProver : Proof.context -> thm -> direction list -> direction list -> thm
    15   val distinctTreeProver : Proof.context -> thm -> direction list -> direction list -> thm
    14   val neq_x_y : Proof.context -> term -> term -> string -> thm option
    16   val neq_x_y : Proof.context -> term -> term -> string -> thm option
    15   val distinctFieldSolver : string list -> solver
    17   val distinctFieldSolver : string list -> solver
    16   val distinctTree_tac : string list -> Proof.context -> int -> tactic
    18   val distinctTree_tac : string list -> Proof.context -> int -> tactic
   186       |> Thm.dest_comb;
   188       |> Thm.dest_comb;
   187     val l = Node_l |> Thm.dest_comb |> #2;
   189     val l = Node_l |> Thm.dest_comb |> #2;
   188   in (x, l) end;
   190   in (x, l) end;
   189 
   191 
   190 in
   192 in
       
   193 
       
   194 fun in_set ctxt ps tree =
       
   195   let
       
   196     val in_set = in_set ctxt
       
   197     val (_, [l, x, _, r]) = Drule.strip_comb tree;
       
   198     val xT = Thm.ctyp_of_cterm x;
       
   199   in
       
   200     (case ps of
       
   201       [] =>
       
   202         instantiate ctxt
       
   203           [(Thm.ctyp_of_cterm x_in_set_root, xT)]
       
   204           [(l_in_set_root, l), (x_in_set_root, x), (r_in_set_root, r)] @{thm in_set_root}
       
   205     | Left :: ps' =>
       
   206         let
       
   207           val in_set_l = in_set ps' l;
       
   208           val in_set_left' =
       
   209             instantiate ctxt
       
   210               [(Thm.ctyp_of_cterm x_in_set_left, xT)]
       
   211               [(x_in_set_left, x), (r_in_set_left, r)] @{thm in_set_left};
       
   212         in discharge ctxt [in_set_l] in_set_left' end
       
   213     | Right :: ps' =>
       
   214         let
       
   215           val in_set_r = in_set ps' r;
       
   216           val in_set_right' =
       
   217             instantiate ctxt
       
   218               [(Thm.ctyp_of_cterm x_in_set_right, xT)]
       
   219               [(x_in_set_right, x), (l_in_set_right, l)] @{thm in_set_right};
       
   220         in discharge ctxt [in_set_r] in_set_right' end)
       
   221   end;
       
   222 
       
   223 fun find_in_set ctxt t ct =
       
   224   case find_tree t (Thm.term_of ct) of
       
   225     SOME ps => in_set ctxt ps ct
       
   226   | NONE => raise TERM ("find_in_set", [t, Thm.term_of ct])
       
   227  
   191 (*
   228 (*
   192 1. First get paths x_path y_path of x and y in the tree.
   229 1. First get paths x_path y_path of x and y in the tree.
   193 2. For the common prefix descend into the tree according to the path
   230 2. For the common prefix descend into the tree according to the path
   194    and lemmas all_distinct_left/right
   231    and lemmas all_distinct_left/right
   195 3. If one restpath is empty use distinct_left/right,
   232 3. If one restpath is empty use distinct_left/right,
   208     val (ps, x_rest, y_rest) = split_common_prefix x_path y_path;
   245     val (ps, x_rest, y_rest) = split_common_prefix x_path y_path;
   209     val dist_subtree_thm = dist_subtree ps dist_thm;
   246     val dist_subtree_thm = dist_subtree ps dist_thm;
   210     val subtree = Thm.cprop_of dist_subtree_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   247     val subtree = Thm.cprop_of dist_subtree_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   211     val (_, [l, _, _, r]) = Drule.strip_comb subtree;
   248     val (_, [l, _, _, r]) = Drule.strip_comb subtree;
   212 
   249 
   213     fun in_set ps tree =
   250   val in_set = in_set ctxt
   214       let
       
   215         val (_, [l, x, _, r]) = Drule.strip_comb tree;
       
   216         val xT = Thm.ctyp_of_cterm x;
       
   217       in
       
   218         (case ps of
       
   219           [] =>
       
   220             instantiate ctxt
       
   221               [(Thm.ctyp_of_cterm 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}
       
   223         | Left :: ps' =>
       
   224             let
       
   225               val in_set_l = in_set ps' l;
       
   226               val in_set_left' =
       
   227                 instantiate ctxt
       
   228                   [(Thm.ctyp_of_cterm x_in_set_left, xT)]
       
   229                   [(x_in_set_left, x), (r_in_set_left, r)] @{thm in_set_left};
       
   230             in discharge ctxt [in_set_l] in_set_left' end
       
   231         | Right :: ps' =>
       
   232             let
       
   233               val in_set_r = in_set ps' r;
       
   234               val in_set_right' =
       
   235                 instantiate ctxt
       
   236                   [(Thm.ctyp_of_cterm x_in_set_right, xT)]
       
   237                   [(x_in_set_right, x), (l_in_set_right, l)] @{thm in_set_right};
       
   238             in discharge ctxt [in_set_r] in_set_right' end)
       
   239       end;
       
   240 
       
   241   fun in_set' [] = raise TERM ("distinctTreeProver", [])
   251   fun in_set' [] = raise TERM ("distinctTreeProver", [])
   242     | in_set' (Left :: ps) = in_set ps l
   252     | in_set' (Left :: ps) = in_set ps l
   243     | in_set' (Right :: ps) = in_set ps r;
   253     | in_set' (Right :: ps) = in_set ps r;
   244 
   254 
   245   fun distinct_lr node_in_set Left =
   255   fun distinct_lr node_in_set Left =