Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Archive-of-Formal-Proofs/thys/Auto2_HOL/HOL/   (Sammlung formaler Beweise Version 2026-5©)  Datei vom 31.4.2026 mit Größe 22 kB image not shown  

Quelle  nat_sub.ML

  Sprache: SML
 

(*
  File: nat_sub.ML
  Author: Bohua Zhan

  Normalization of expressions involving subtraction on natural numbers.
*)


signature NAT_SUB =
sig
  val fheads: term list
  val norm_plus1: wfconv
  val norm_plus: wfconv
  val norm_minus': wfconv
  val move_outmost: term -> wfconv
  val cancel_terms: wfconv
  val norm_minus: wfconv
  type monomial = cterm list * int
  val reduce_monomial_list: monomial list -> monomial list
  val add_polynomial_list: monomial list * monomial list -> monomial list
  val norm_minus_ct: cterm -> monomial list
  val norm_ring_term: cterm -> term

  val get_sub_head_equiv:
      Proof.context -> box_id * cterm -> (box_id * (wfterm * thm)) list
  val nat_sub_expand_once:
      Proof.context -> box_id * wfterm -> (box_id * (wfterm * thm)) list
  val nat_sub_expand:
      Proof.context -> box_id * cterm -> (box_id * (wfterm * thm)) list

  val nat_sub_expand_equiv: proofstep
  val nat_sub_expand_unit: proofstep

  val add_nat_sub_proofsteps: theory -> theory
end;

structure NatSub : NAT_SUB =
struct

structure WfTerm = Auto2_Setup.WfTerm

val fheads = [@{term "(+) :: (nat => nat => nat)"},
              @{term "(-) :: (nat => nat => nat)"},
              @{term "(*) :: (nat => nat => nat)"}]

val plus_info = Nat_Util.plus_ac_on_typ @{theory} natT
val is_numc = UtilArith.is_numc
val dest_numc = UtilArith.dest_numc
val is_plus = UtilArith.is_plus
val is_minus = UtilArith.is_minus
val is_times = UtilArith.is_times
val is_zero = UtilArith.is_zero
val is_one = UtilArith.is_one
val wf_rewr_obj_eq = WfTerm.rewr_obj_eq fheads
val nat0 = Nat_Util.nat0

val mult_1 = @{thm mult_1}  (* 1 * a = a *)
val mult_1_right = @{thm mult_1_right}  (* a * 1 = a *)
val mult_0 = @{thm mult_0}  (* 0 * a = 0 *)
val mult_0_right = @{thm mult_0_right}  (* a * 0 = 0 *)
val add_0 = @{thm add_0}  (* 0 + a = a *)
val add_0_right = @{thm add_0_right}  (* a + 0 = a *)

val add_assoc = wf_rewr_obj_eq @{thm add_ac(1)}
val add_assoc_sym = wf_rewr_obj_eq (obj_sym @{thm add_ac(1)})
val add_comm = wf_rewr_obj_eq @{thm add_ac(2)}
val swap_add = WfTerm.every_conv [add_assoc, WfTerm.arg_conv add_comm,
                                  add_assoc_sym]
val times_assoc = wf_rewr_obj_eq @{thm mult_ac(1)}
val times_assoc_sym = wf_rewr_obj_eq (obj_sym @{thm mult_ac(1)})
val times_comm = wf_rewr_obj_eq @{thm mult_ac(2)}
val swap_times = WfTerm.every_conv [times_assoc, WfTerm.arg_conv times_comm,
                                    times_assoc_sym]

val distrib_r_th = @{thm nat_distrib(1)}
val distrib_l_th = @{thm nat_distrib(2)}

val nat_fold_wfconv = WfTerm.conv_of Nat_Util.nat_fold_conv
val cancel_0_left = WfTerm.try_conv (wf_rewr_obj_eq @{thm add_0_left})
val append_0_left = wf_rewr_obj_eq (obj_sym @{thm add_0_left})

(* When comparing atoms, constants are greater than non-constants. *)
fun compare_atom (t1, t2) =
    if is_numc t1 andalso is_numc t2 then EQUAL
    else if is_numc t1 then GREATER
    else if is_numc t2 then LESS
    else Term_Ord.term_ord (t1, t2)

(* Multiply a monomial with an atom. *)
fun norm_mult_atom wft =
    let
      val t = WfTerm.term_of wft
      val (arg1, arg2) = Util.dest_binop_args t
    in
      if is_one arg1 then wf_rewr_obj_eq mult_1 wft
      else if is_one arg2 then wf_rewr_obj_eq mult_1_right wft
      else if is_zero arg1 then wf_rewr_obj_eq mult_0 wft
      else if is_zero arg2 then wf_rewr_obj_eq mult_0_right wft
      else if is_times arg1 then
        case compare_atom (dest_arg arg1, arg2) of
            GREATER =>
            WfTerm.every_conv [swap_times,
                               WfTerm.arg1_conv norm_mult_atom] wft
          | EQUAL =>
            if is_numc (dest_arg arg1) andalso is_numc arg2 then
              WfTerm.every_conv [times_assoc,
                                 WfTerm.arg_conv nat_fold_wfconv] wft
            else
              WfTerm.all_conv wft
          | _ => WfTerm.all_conv wft
      else
        case compare_atom (arg1, arg2) of
            GREATER => times_comm wft
          | EQUAL =>
            if is_numc arg1 andalso is_numc arg2 then
              nat_fold_wfconv wft
            else
              WfTerm.all_conv wft
          | _ => WfTerm.all_conv wft
    end

(* Multiply two monomials. *)
fun norm_mult_monomial wft =
    let
      val t = WfTerm.term_of wft
      val (_, arg2) = Util.dest_binop_args t
    in
      if is_times arg2 then
        WfTerm.every_conv [times_assoc_sym,
                           WfTerm.arg1_conv norm_mult_monomial,
                           norm_mult_atom] wft
      else
        norm_mult_atom wft
    end

(* Destruct t into the form arg * coeff, where coeff is a constant. *)
fun dest_monomial t =
    if is_times t andalso is_numc (dest_arg t) then
      (dest_arg1 t, UtilArith.dest_numc (dest_arg t))
    else if is_numc t then
      (Nat_Util.mk_nat 1, UtilArith.dest_numc t)
    else
      (t, 1)

(* Normalize ct into the form arg * coeff.

   Example: a * 4 == a * 4, a == a * 1, 4 == 1 * 4.
 *)

fun norm_monomial wft =
    let
      val t = WfTerm.term_of wft
    in
      if is_times t andalso is_numc (dest_arg t) then
        WfTerm.all_conv wft
      else if is_numc t then
        wf_rewr_obj_eq (obj_sym @{thm mult_1}) wft
      else
        wf_rewr_obj_eq (obj_sym @{thm mult_1_right}) wft
    end

(* Compare two monomials by removing coefficient. *)
fun compare_monomial (t1, t2) =
    let
      val (arg1, _) = dest_monomial t1
      val (arg2, _) = dest_monomial t2
    in
      if is_one arg1 andalso is_one arg2 then EQUAL
      else if is_one arg1 then GREATER
      else if is_one arg2 then LESS
      else Term_Ord.term_ord (arg1, arg2)
    end

(* Combine two monomials. *)
fun combine_monomial wft =
    WfTerm.every_conv [WfTerm.binop_conv norm_monomial,
                       wf_rewr_obj_eq (obj_sym distrib_l_th),
                       WfTerm.arg_conv nat_fold_wfconv] wft

(* Normalize a + b, where a is a sum and b is an atom. If b is a
   constant, add it to the end of a. Otherwise, insert b into sorted
   position.
 *)

fun norm_plus1 wft =
    let
      val (a, b) = wft |> WfTerm.term_of |> Util.dest_binop_args
    in
      if is_zero a then wf_rewr_obj_eq add_0 wft
      else if is_zero b then wf_rewr_obj_eq add_0_right wft
      else if is_plus a then
        case compare_monomial (dest_arg a, b) of
            LESS => WfTerm.all_conv wft
          | EQUAL =>
            if is_numc (dest_arg a) andalso is_numc b then
              WfTerm.every_conv [add_assoc,
                                 WfTerm.arg_conv nat_fold_wfconv] wft
            else
              WfTerm.every_conv [add_assoc,
                                 WfTerm.arg_conv combine_monomial] wft
          | GREATER =>
            WfTerm.every_conv [swap_add, WfTerm.arg1_conv norm_plus1] wft
      else
        case compare_monomial (a, b) of
            LESS => WfTerm.all_conv wft
          | EQUAL => if is_numc a andalso is_numc b then
                       nat_fold_wfconv wft
                     else
                       combine_monomial wft
          | GREATER => wf_rewr_obj_eq @{thm add_ac(2)} wft
    end

(* Normalize a + b, where a and b are both sums. *)
fun norm_plus wft =
    let
      val (_, b) = wft |> WfTerm.term_of |> Util.dest_binop_args
    in
      if is_plus b then
        WfTerm.every_conv [
          add_assoc_sym, WfTerm.arg1_conv norm_plus, norm_plus1] wft
      else
        norm_plus1 wft
    end

(* Assume wft is a sum containing u. Move u into the outermost position. *)
fun move_outmost u wft =
    if u aconv (WfTerm.term_of wft) then WfTerm.all_conv wft
    else if not (is_plus (WfTerm.term_of wft)) then
      raise Fail "move_outmost: u not found in wft."
    else let
      val (a, b) = wft |> WfTerm.term_of |> Util.dest_binop_args
    in
      if u aconv b then WfTerm.all_conv wft
      else if is_plus a then
        WfTerm.every_conv [WfTerm.arg1_conv (move_outmost u), swap_add] wft
      else if u aconv a then
        add_comm wft
      else
        raise Fail "move_outmost: u not found in wft."
    end

(* Cancel terms with the same argument from the two sides. *)
fun cancel_terms wft =
    let
      val (a, b) = wft |> WfTerm.term_of |> Util.dest_binop_args
      val (ts1, ts2) = apply2 (Auto2_HOL_Extra_Setup.ACUtil.dest_ac plus_info) (a, b)

      fun find_same_arg (t1, t2) =
          case compare_monomial (t1, t2) of
              EQUAL => if t1 aconv nat0 orelse t2 aconv nat0 then NONE
                       else SOME (t1, t2)
            | _ => NONE

      fun prepare_left t1 =
          if length ts1 = 1 then WfTerm.arg1_conv append_0_left
          else WfTerm.arg1_conv (move_outmost t1)

      fun prepare_right t2 =
          if length ts2 = 1 then WfTerm.arg_conv append_0_left
          else WfTerm.arg_conv (move_outmost t2)

      fun apply_th (t1, t2) wft =
          let
            val (_, n1) = dest_monomial t1
            val (_, n2) = dest_monomial t2
            val fold_cv =
                WfTerm.every_conv [
                  WfTerm.arg_conv nat_fold_wfconv,
                  WfTerm.try_conv (wf_rewr_obj_eq mult_1),
                  WfTerm.try_conv (wf_rewr_obj_eq mult_1_right)]
            val le_th = if n1 >= n2 then Nat_Util.nat_le_th n2 n1
                        else Nat_Util.nat_le_th n1 n2
          in
            if n1 = n2 then
              wf_rewr_obj_eq @{thm nat_sub_combine} wft
            else if n1 > n2 then
              WfTerm.every_conv [
                WfTerm.binop_conv (WfTerm.arg_conv norm_monomial),
                wf_rewr_obj_eq (le_th RS @{thm nat_sub_combine2}),
                WfTerm.arg1_conv (WfTerm.arg_conv fold_cv),
                WfTerm.arg1_conv norm_plus] wft
            else
              WfTerm.every_conv [
                WfTerm.binop_conv (WfTerm.arg_conv norm_monomial),
                wf_rewr_obj_eq (le_th RS @{thm nat_sub_combine3}),
                WfTerm.arg_conv (WfTerm.arg_conv fold_cv),
                WfTerm.arg_conv norm_plus] wft
          end
    in
      case get_first find_same_arg (Util.all_pairs (ts1, ts2)) of
          NONE => WfTerm.all_conv wft
        | SOME (t1, t2) =>
          WfTerm.every_conv [prepare_left t1, prepare_right t2,
                             apply_th (t1, t2),
                             WfTerm.arg1_conv cancel_0_left,
                             WfTerm.arg_conv cancel_0_left,
                             cancel_terms] wft
    end

fun norm_mult_poly_monomial wft =
    let
      val t = WfTerm.term_of wft
      val (arg1, _) = Util.dest_binop_args t
    in
      if is_plus arg1 then
        WfTerm.every_conv [wf_rewr_obj_eq distrib_r_th,
                           WfTerm.arg1_conv norm_mult_poly_monomial,
                           WfTerm.arg_conv norm_mult_monomial,
                           norm_plus] wft
      else
        norm_mult_monomial wft
    end

fun norm_mult_polynomials wft =
    let
      val t = WfTerm.term_of wft
      val (_, arg2) = Util.dest_binop_args t
    in
      if is_plus arg2 then
        WfTerm.every_conv [wf_rewr_obj_eq distrib_l_th,
                           WfTerm.arg1_conv norm_mult_polynomials,
                           WfTerm.arg_conv norm_mult_poly_monomial,
                           norm_plus] wft
      else
        norm_mult_poly_monomial wft
    end

(* First step, put wft into the form a - b, where a and b are
   normalized sums.
 *)

fun norm_minus' wft =
    let
      val t = WfTerm.term_of wft
    in
      if is_plus t then
        (* (a - b) + (c - d) = (a + c) - (b + d) *)
        WfTerm.every_conv [WfTerm.binop_conv norm_minus',
                           wf_rewr_obj_eq @{thm nat_sub1},
                           WfTerm.binop_conv norm_plus,
                           cancel_terms] wft
      else if is_minus t then
        (* (a - b) - (c - d) = (a + d) - (b + c) *)
        WfTerm.every_conv [WfTerm.binop_conv norm_minus',
                           wf_rewr_obj_eq @{thm nat_sub2},
                           WfTerm.binop_conv norm_plus,
                           cancel_terms] wft
      else if is_times t then
        (* (a - b) * (c - d) = (ac + bd) - (ad + bc) *)
        WfTerm.every_conv [
          WfTerm.binop_conv norm_minus',
          wf_rewr_obj_eq @{thm nat_sub3},
          WfTerm.binop_conv (WfTerm.binop_conv norm_mult_polynomials),
          WfTerm.binop_conv norm_plus,
          cancel_terms] wft
      else
        (* Normalize a into a - 0. *)
        wf_rewr_obj_eq @{thm nat_sub_norm} wft
    end

fun norm_minus wft =
    WfTerm.every_conv [
      norm_minus',
      WfTerm.try_conv (wf_rewr_obj_eq @{thm diff_zero})] wft

(* Fast computation of the expected normalization. Return a list of
   monomials.
 *)

type monomial = cterm list * int

fun mk_plus (t1, t2) =
    Const (@{const_name plus}, natT --> natT --> natT) $ t1 $ t2

fun list_plus ts =
    let
      fun list_rev ts =
          case ts of
              [] => Nat_Util.mk_nat 0
            | [t] => t
            | t :: ts' => mk_plus (list_rev ts', t)
    in
      list_rev (rev ts)
    end

fun mk_times (t1, t2) =
    Const (@{const_name times}, natT --> natT --> natT) $ t1 $ t2

fun list_times ts =
    let
      fun list_rev ts =
          case ts of
              [] => Nat_Util.mk_nat 1
            | [t] => t
            | t :: ts' => mk_times (list_rev ts', t)
    in
      list_rev (rev ts)
    end

(* Compare two monomials *)
fun compare_monomial_list ((l1, _), (l2, _)) =
    if null l1 andalso null l2 then EQUAL
    else if null l1 then GREATER
    else if null l2 then LESS
    else Term_Ord.term_ord (list_times (map Thm.term_of l1),
                            list_times (map Thm.term_of l2))

(* Reduce a list of monomials: combine monomials of the same body. *)
fun reduce_monomial_list ls =
    if null ls then []
    else let
      val ((l1, c1), rest) = (hd ls, reduce_monomial_list (tl ls))
    in
      case rest of
          [] => [(l1, c1)]
        | [(_, 0)] => [(l1, c1)]
        | (l2, c2) :: rest' =>
          if eq_list (op aconvc) (l1, l2) then
            if c1 + c2 = 0 then rest'
            else (l1, c1 + c2) :: rest'
          else (l1, c1) :: (l2, c2) :: rest'
    end

(* Multiply two monomials. *)
fun mult_monomial ((l1, c1), (l2, c2)) =
    ((l1 @ l2) |> sort (compare_atom o apply2 Thm.term_of), c1 * c2)

(* Multiply two such lists: take the pairwise product, sort within
   each monomial, then sort the list of monomials.
 *)

fun mult_polynomial_term (ls1, ls2) =
    (Util.all_pairs (ls1, ls2))
        |> map mult_monomial
        |> sort compare_monomial_list
        |> reduce_monomial_list

fun add_polynomial_list (ls1, ls2) =
    (ls1 @ ls2) |> sort compare_monomial_list |> reduce_monomial_list

fun negate_polynomial_list ls =
    map (fn (ls, n) => (ls, ~n)) ls

fun norm_minus_ct ct =
    let
      val t = Thm.term_of ct
    in
      if is_plus t then
        add_polynomial_list (norm_minus_ct (Thm.dest_arg1 ct),
                             norm_minus_ct (Thm.dest_arg ct))
      else if is_minus t then
        add_polynomial_list (
          norm_minus_ct (Thm.dest_arg1 ct),
          negate_polynomial_list (norm_minus_ct (Thm.dest_arg ct)))
      else if is_times t then
        mult_polynomial_term (norm_minus_ct (Thm.dest_arg1 ct),
                              norm_minus_ct (Thm.dest_arg ct))
      else if is_numc t then
        [([], dest_numc t)]
      else
        [([ct], 1)]
    end

fun subterms_of ct =
    ct |> norm_minus_ct |> map fst |> flat

fun to_monomial (l, c) =
    if null l then mk_nat c
    else if c = 1 then list_times (map Thm.term_of l)
    else mk_times (list_times (map Thm.term_of l), mk_nat c)

fun norm_ring_term ct =
    let
      val dest_ring = norm_minus_ct ct
      val (ps, ms) = filter_split (fn (_, n) => n >= 0) dest_ring
    in
      if length ms > 0 then
        Const (@{const_name minus}, natT --> natT --> natT) $
              list_plus (map to_monomial ps) $
              list_plus (map to_monomial (negate_polynomial_list ms))
      else
        list_plus (map to_monomial ps)
    end

(* Obtain head equivalences of cu, normalized to a - b form, and where
   each term is simplified.
 *)

fun get_sub_head_equiv ctxt (id, ct) =
    let
      fun process_wf_head_equiv (id', (wft, eq_th)) =
          let
            val cts = subterms_of (Thm.rhs_of eq_th)
            val simps = Auto2_Setup.WellformData.simplify ctxt fheads cts (id', wft)

            fun process_simp (id'', (wft', eq_th')) =
                (BoxID.merge_boxes ctxt (id', id''),
                 (wft', Util.transitive_list [eq_th, eq_th']))
          in
            map process_simp simps
          end
    in
      (id, ct) |> Auto2_Setup.WellformData.get_head_equiv ctxt fheads
               |> maps process_wf_head_equiv
               |> filter_out (Thm.is_reflexive o snd o snd)
    end

(* Given wft in normalized form a - b, expand one of the subterms
   once. Calls the corresponding function in ac_steps on a and b, then
   combine the results.
 *)

fun nat_sub_expand_once ctxt (id, wft) =
    let
      val ct = WfTerm.cterm_of wft
      val subt = subterms_of ct
      fun get_equiv cu = get_sub_head_equiv ctxt (id, cu)

      fun process_info (id', wf_eq) =
          (id', WfTerm.rewrite_on_eqs fheads [wf_eq] wft)
    in
      map process_info (maps get_equiv subt)
    end

(* Find all ways to write ct, up to a certain limit. *)
fun nat_sub_expand ctxt (id, ct) =
    let
      val max_ac = Config.get ctxt Auto2_HOL_Extra_Setup.AC_ProofSteps.max_ac

      fun ac_equiv_eq_better (id, (_, th)) (id', (_, th')) =
          let
            val seq1 = subterms_of (Thm.rhs_of th)
            val seq2 = subterms_of (Thm.rhs_of th')
          in
            Util.is_subseq (op aconvc) (seq1, seq2) andalso
            BoxID.is_eq_ancestor ctxt id id'
          end

      fun has_ac_equiv_eq_better infos info' =
          exists (fn info => ac_equiv_eq_better info info') infos

      fun helper (old, new) =
          case new of
              [] => old
            | (id', (wft, eq_th)) :: rest =>
              if length old + length new > max_ac then
                old @ take (max_ac - length old) new
              else let
                val old' = ((id', (wft, eq_th)) :: old)

                fun merge_info (id'', (wft', eq_th')) =
                    (BoxID.merge_boxes ctxt (id', id''),
                     (wft', Util.transitive_list [eq_th, eq_th']))

                val rhs_expand =
                    (nat_sub_expand_once ctxt (id', wft))
                        |> Util.max_partial ac_equiv_eq_better
                        |> map merge_info
                        |> filter_out (has_ac_equiv_eq_better (old' @ rest))
              in
                helper (old', rest @ rhs_expand)
              end

      (* Start term *)
      val ts = subterms_of ct
      val start = (Auto2_Setup.WellformData.cterm_to_wfterm ctxt fheads (id, ct))
                      |> maps (Auto2_Setup.WellformData.simplify ctxt fheads ts)
    in
      helper ([], start)
    end

fun is_nat_sub_form t =
    if is_plus t orelse is_minus t orelse is_times t then
      fastype_of (dest_arg t) = natT
    else false

fun nat_sub_expand_equiv_fn ctxt item1 item2 =
    let
      val {id = id1, tname = tname1, ...} = item1
      val {id = id2, tname = tname2, ...} = item2
      val (ct1, ct2) = (the_single tname1, the_single tname2)
      val (t1, t2) = (Thm.term_of ct1, Thm.term_of ct2)
      val id = BoxID.merge_boxes ctxt (id1, id2)
    in
      if not (is_nat_sub_form t1) orelse not (is_nat_sub_form t2) then []
      else if Term_Ord.term_ord (t2, t1) = LESS then []
      else if Auto2_Setup.RewriteTable.is_equiv id ctxt (ct1, ct2) then []
      else let
        val expand1 = nat_sub_expand ctxt (id, ct1)
        val expand2 = nat_sub_expand ctxt (id, ct2)

        fun get_equiv ((id1, (wft1, eq_th1)), (id2, (wft2, eq_th2))) =
            let
              val ct1 = Thm.rhs_of eq_th1
              val ct2 = Thm.rhs_of eq_th2
              val ts1 = norm_minus_ct ct1
              val ts2 = norm_minus_ct ct2
            in
              if eq_list (eq_pair (eq_list (op aconvc)) (op =)) (ts1, ts2) then
                let
                  val (wft1', eq1) = norm_minus wft1
                  val (wft2', eq2) = norm_minus wft2
                  val _ = assert (WfTerm.term_of wft1' aconv WfTerm.term_of wft2')
                                 "nat_sub_expand_equiv_fn"
                  val id' = BoxID.merge_boxes ctxt (id1, id2)
                  val eq = Util.transitive_list [
                        eq_th1, eq1, meta_sym eq2, meta_sym eq_th2]
                in
                  [(id', to_obj_eq eq)]
                end
              else []
            end
      in
        (maps get_equiv (Util.all_pairs (expand1, expand2)))
            |> filter (BoxID.has_incr_id o fst)
            |> Util.max_partial (BoxID.id_is_eq_ancestor ctxt)
            |> map (fn (id, th) => Auto2_Setup.Update.thm_update_sc 1 (id, th))
      end
    end

val nat_sub_expand_equiv =
    {name = "nat_sub_expand_equiv",
     args = [TypedMatch (TY_TERM, @{term_pat "?A::nat"}),
             TypedMatch (TY_TERM, @{term_pat "?B::nat"})],
     func = TwoStep nat_sub_expand_equiv_fn}

fun nat_sub_expand_unit_fn ctxt item =
    let
      val {id, tname, ...} = item
      val ct = the_single tname
      val t = Thm.term_of ct
    in
      if not (is_nat_sub_form t) then []
      else let
        val expand = nat_sub_expand ctxt (id, ct)

        fun process_expand (id', (wft, eq_th)) =
            let
              val ct = Thm.rhs_of eq_th
              val ts = norm_minus_ct ct
            in
              if length ts = 0 orelse
                 (length ts = 1 andalso snd (the_single ts) = 1then
                let
                  val (_, eq') = norm_minus wft
                  val eq = Util.transitive_list [eq_th, eq']
                in
                  [(id', to_obj_eq eq)]
                end
              else []
            end
      in
        (maps process_expand expand)
            |> filter (BoxID.has_incr_id o fst)
            |> map (fn (id, th) => Auto2_Setup.Update.thm_update_sc 1 (id, th))
      end
    end

val nat_sub_expand_unit =
    {name = "nat_sub_expand_unit",
     args = [TypedMatch (TY_TERM, @{term_pat "?A::nat"})],
     func = OneStep nat_sub_expand_unit_fn}

val add_nat_sub_proofsteps =
    fold add_prfstep [
      nat_sub_expand_equiv, nat_sub_expand_unit
    ]

end  (* NatSub *)

val _ = Theory.setup NatSub.add_nat_sub_proofsteps

Messung V0.5 in Prozent
C=94 H=100 G=96

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.