src/HOL/Statespace/distinct_tree_prover.ML
changeset 69597 ff784d5a5bfb
parent 62913 13252110a6fe
child 74282 c2ee8d993d6a
equal deleted inserted replaced
69596:c8a2755bf220 69597:ff784d5a5bfb
    26 
    26 
    27 val neq_to_eq_False = @{thm neq_to_eq_False};
    27 val neq_to_eq_False = @{thm neq_to_eq_False};
    28 
    28 
    29 datatype direction = Left | Right;
    29 datatype direction = Left | Right;
    30 
    30 
    31 fun treeT T = Type (@{type_name tree}, [T]);
    31 fun treeT T = Type (\<^type_name>\<open>tree\<close>, [T]);
    32 
    32 
    33 fun mk_tree' e T n [] = Const (@{const_name Tip}, treeT T)
    33 fun mk_tree' e T n [] = Const (\<^const_name>\<open>Tip\<close>, treeT T)
    34   | mk_tree' e T n xs =
    34   | mk_tree' e T n xs =
    35      let
    35      let
    36        val m = (n - 1) div 2;
    36        val m = (n - 1) div 2;
    37        val (xsl,x::xsr) = chop m xs;
    37        val (xsl,x::xsr) = chop m xs;
    38        val l = mk_tree' e T m xsl;
    38        val l = mk_tree' e T m xsl;
    39        val r = mk_tree' e T (n-(m+1)) xsr;
    39        val r = mk_tree' e T (n-(m+1)) xsr;
    40      in
    40      in
    41        Const (@{const_name Node}, treeT T --> T --> HOLogic.boolT--> treeT T --> treeT T) $
    41        Const (\<^const_name>\<open>Node\<close>, treeT T --> T --> HOLogic.boolT--> treeT T --> treeT T) $
    42          l $ e x $ @{term False} $ r
    42          l $ e x $ \<^term>\<open>False\<close> $ r
    43      end
    43      end
    44 
    44 
    45 fun mk_tree e T xs = mk_tree' e T (length xs) xs;
    45 fun mk_tree e T xs = mk_tree' e T (length xs) xs;
    46 
    46 
    47 fun dest_tree (Const (@{const_name Tip}, _)) = []
    47 fun dest_tree (Const (\<^const_name>\<open>Tip\<close>, _)) = []
    48   | dest_tree (Const (@{const_name Node}, _) $ l $ e $ _ $ r) = dest_tree l @ e :: dest_tree r
    48   | dest_tree (Const (\<^const_name>\<open>Node\<close>, _) $ l $ e $ _ $ r) = dest_tree l @ e :: dest_tree r
    49   | dest_tree t = raise TERM ("dest_tree", [t]);
    49   | dest_tree t = raise TERM ("dest_tree", [t]);
    50 
    50 
    51 
    51 
    52 
    52 
    53 fun lin_find_tree e (Const (@{const_name Tip}, _)) = NONE
    53 fun lin_find_tree e (Const (\<^const_name>\<open>Tip\<close>, _)) = NONE
    54   | lin_find_tree e (Const (@{const_name Node}, _) $ l $ x $ _ $ r) =
    54   | lin_find_tree e (Const (\<^const_name>\<open>Node\<close>, _) $ l $ x $ _ $ r) =
    55       if e aconv x
    55       if e aconv x
    56       then SOME []
    56       then SOME []
    57       else
    57       else
    58         (case lin_find_tree e l of
    58         (case lin_find_tree e l of
    59           SOME path => SOME (Left :: path)
    59           SOME path => SOME (Left :: path)
    61             (case lin_find_tree e r of
    61             (case lin_find_tree e r of
    62               SOME path => SOME (Right :: path)
    62               SOME path => SOME (Right :: path)
    63             | NONE => NONE))
    63             | NONE => NONE))
    64   | lin_find_tree e t = raise TERM ("find_tree: input not a tree", [t])
    64   | lin_find_tree e t = raise TERM ("find_tree: input not a tree", [t])
    65 
    65 
    66 fun bin_find_tree order e (Const (@{const_name Tip}, _)) = NONE
    66 fun bin_find_tree order e (Const (\<^const_name>\<open>Tip\<close>, _)) = NONE
    67   | bin_find_tree order e (Const (@{const_name Node}, _) $ l $ x $ _ $ r) =
    67   | bin_find_tree order e (Const (\<^const_name>\<open>Node\<close>, _) $ l $ x $ _ $ r) =
    68       (case order (e, x) of
    68       (case order (e, x) of
    69         EQUAL => SOME []
    69         EQUAL => SOME []
    70       | LESS => Option.map (cons Left) (bin_find_tree order e l)
    70       | LESS => Option.map (cons Left) (bin_find_tree order e l)
    71       | GREATER => Option.map (cons Right) (bin_find_tree order e r))
    71       | GREATER => Option.map (cons Right) (bin_find_tree order e r))
    72   | bin_find_tree order e t = raise TERM ("find_tree: input not a tree", [t])
    72   | bin_find_tree order e t = raise TERM ("find_tree: input not a tree", [t])
   291         |> Thm.dest_comb |> #2;
   291         |> Thm.dest_comb |> #2;
   292       val [alpha] = ct |> Thm.ctyp_of_cterm |> Thm.dest_ctyp;
   292       val [alpha] = ct |> Thm.ctyp_of_cterm |> Thm.dest_ctyp;
   293     in (dest_TVar (Thm.typ_of alpha), #1 (dest_Var (Thm.term_of ct))) end;
   293     in (dest_TVar (Thm.typ_of alpha), #1 (dest_Var (Thm.term_of ct))) end;
   294 in
   294 in
   295 
   295 
   296 fun subtractProver ctxt (Const (@{const_name Tip}, T)) ct dist_thm =
   296 fun subtractProver ctxt (Const (\<^const_name>\<open>Tip\<close>, T)) ct dist_thm =
   297       let
   297       let
   298         val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   298         val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
   299         val [alphaI] = #2 (dest_Type T);
   299         val [alphaI] = #2 (dest_Type T);
   300       in
   300       in
   301         Thm.instantiate
   301         Thm.instantiate
   302           ([(alpha, Thm.ctyp_of ctxt alphaI)],
   302           ([(alpha, Thm.ctyp_of ctxt alphaI)],
   303            [((v, treeT alphaI), ct')]) @{thm subtract_Tip}
   303            [((v, treeT alphaI), ct')]) @{thm subtract_Tip}
   304       end
   304       end
   305   | subtractProver ctxt (Const (@{const_name Node}, nT) $ l $ x $ d $ r) ct dist_thm =
   305   | subtractProver ctxt (Const (\<^const_name>\<open>Node\<close>, nT) $ l $ x $ d $ r) ct dist_thm =
   306       let
   306       let
   307         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;
   308         val (_, [cl, _, _, cr]) = Drule.strip_comb ct;
   308         val (_, [cl, _, _, cr]) = Drule.strip_comb ct;
   309         val ps = the (find_tree x (Thm.term_of ct'));
   309         val ps = the (find_tree x (Thm.term_of ct'));
   310         val del_tree = deleteProver ctxt dist_thm ps;
   310         val del_tree = deleteProver ctxt dist_thm ps;
   340   in SOME thm
   340   in SOME thm
   341   end handle Option.Option => NONE);
   341   end handle Option.Option => NONE);
   342 
   342 
   343 fun distinctTree_tac names ctxt = SUBGOAL (fn (goal, i) =>
   343 fun distinctTree_tac names ctxt = SUBGOAL (fn (goal, i) =>
   344     (case goal of
   344     (case goal of
   345       Const (@{const_name Trueprop}, _) $
   345       Const (\<^const_name>\<open>Trueprop\<close>, _) $
   346           (Const (@{const_name Not}, _) $ (Const (@{const_name HOL.eq}, _) $ x $ y)) =>
   346           (Const (\<^const_name>\<open>Not\<close>, _) $ (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ x $ y)) =>
   347         (case get_fst_success (neq_x_y ctxt x y) names of
   347         (case get_fst_success (neq_x_y ctxt x y) names of
   348           SOME neq => resolve_tac ctxt [neq] i
   348           SOME neq => resolve_tac ctxt [neq] i
   349         | NONE => no_tac)
   349         | NONE => no_tac)
   350     | _ => no_tac))
   350     | _ => no_tac))
   351 
   351 
   352 fun distinctFieldSolver names =
   352 fun distinctFieldSolver names =
   353   mk_solver "distinctFieldSolver" (distinctTree_tac names);
   353   mk_solver "distinctFieldSolver" (distinctTree_tac names);
   354 
   354 
   355 fun distinct_simproc names =
   355 fun distinct_simproc names =
   356   Simplifier.make_simproc @{context} "DistinctTreeProver.distinct_simproc"
   356   Simplifier.make_simproc \<^context> "DistinctTreeProver.distinct_simproc"
   357    {lhss = [@{term "x = y"}],
   357    {lhss = [\<^term>\<open>x = y\<close>],
   358     proc = fn _ => fn ctxt => fn ct =>
   358     proc = fn _ => fn ctxt => fn ct =>
   359       (case Thm.term_of ct of
   359       (case Thm.term_of ct of
   360         Const (@{const_name HOL.eq}, _) $ x $ y =>
   360         Const (\<^const_name>\<open>HOL.eq\<close>, _) $ x $ y =>
   361           Option.map (fn neq => @{thm neq_to_eq_False} OF [neq])
   361           Option.map (fn neq => @{thm neq_to_eq_False} OF [neq])
   362             (get_fst_success (neq_x_y ctxt x y) names)
   362             (get_fst_success (neq_x_y ctxt x y) names)
   363       | _ => NONE)};
   363       | _ => NONE)};
   364 
   364 
   365 end;
   365 end;