How can I easily write simple tactics at the ML level of Isabelle?

前端 未结 3 658
南方客
南方客 2021-02-14 09:26

In an Isabelle theory file, I can write simple one-line tactics such as the following:

apply (clarsimp simp: split_def split: prod.splits)

I fi

3条回答
  •  孤城傲影
    2021-02-14 10:01

    The Method class appear to provide enough of an interface to extract out a tactic, via a cases_tactic as follows:

    (*
     * Generate an ML tactic object of the given Isar string.
     *
     * For example,
     *
     *   mk_tac "auto simp: field_simps intro!: ext" @{context}
     *
     * will generate the corresponding "tactic" object.
     *)
    fun mk_tac str ctxt =
    let
      val parsed_str = Outer_Syntax.scan Position.start str
          |> filter Token.is_proper
          |> Args.name
      val meth = Method.method (Proof_Context.theory_of ctxt)
          (Args.src (parsed_str, Position.start)) ctxt
    in
      Method.apply (K meth) ctxt [] #> Seq.map snd
    end
    

    or alternatively as an anti-quotation:

    (*
     * Setup an antiquotation of the form:
     *
     *    @{tactic "auto simp: foo intro!: bar"}
     *
     * which returns an object of type "context -> tactic".
     *
     * While this doesn't provide any benefits over a direct call to "mk_tac" just
     * yet, in the future it may generate code to avoid parsing the tactic at
     * run-time.
     *)
    val tactic_antiquotation_setup =
    let
      val parse_string =
        ((Args.context -- Scan.lift Args.name) >> snd)
          #>> ML_Syntax.print_string
          #>> (fn s => "mk_tac " ^ s)
          #>> ML_Syntax.atomic
    in
      ML_Antiquote.inline @{binding "tactic"} parse_string
    end
    

    and setup in a theory file as follows:

    setup {*
      tactic_antiquotation_setup
    *}
    

    which can then be used as follows:

    lemma "(a :: nat) * (b + 1) = (a * b) + a"
      by (tactic {* @{tactic "metis Suc_eq_plus1 mult_Suc_right nat_add_commute"} @{context} *})
    

    as desired.

提交回复
热议问题