(* * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) * * SPDX-License-Identifier: BSD-2-Clause *) theory ML_Goal_Test imports ML_Goal MLUtils begin experiment begin \\ Basic usage. \ ML_goal test: \ [@{term "(P \ Q) \ P \ Q"}] \ apply clarsimp done thm test \\ A goal that we definitely don't want to write out by hand. In this case, we're going to show that if x is less than 10, we "only" need to consider the cases when x = 0, or x = 1, or... \ ML_goal big_goal: \ let val var_x = Free ("x", @{typ nat}); val var_P = Free ("P", @{typ bool}); val max = 10; \\ @{ML "HOLogic.mk_nat"} produces nested Suc's, which are pretty ugly, so we use this instead. \ val mk_nat = HOLogic.mk_number @{typ nat}; \\ Turns (i: int) into @{term "x = i \ P"}. \ fun mk_case i = let val prem = HOLogic.mk_eq (var_x, mk_nat i) |> HOLogic.mk_Trueprop; val conc = var_P |> HOLogic.mk_Trueprop; in Logic.mk_implies (prem, conc) end val x_cases = ListExtras.range 0 max |> map mk_case; val assm = HOLogic.mk_binrel @{const_name "less"} (var_x, (mk_nat max)) |> HOLogic.mk_Trueprop; val goal = Logic.list_implies (assm :: x_cases, var_P |> HOLogic.mk_Trueprop) in [goal] end \ by force \\ Names are optional. \ ML_goal \ [@{term "True"}] \ by (rule TrueI) \\ Multiple goals are supported, and result in similar "list of fact" lemmas \ ML_goal multiple_goals: \ [@{term "(P \ Q \ P)"}, @{term "(P \ Q \ Q)"}] \ by simp+ thm multiple_goals[OF TrueI] \\ Handles mixes of @{typ bool} and @{typ prop}. \ ML_goal \ [@{term "PROP A \ PROP A"}, @{term "B \ B"}] \ by simp+ \\ Turns out a lemma name can refer to nothing as well! \ ML_goal nothing: \[]\ done thm nothing[OF TrueI] \\ Attributes can be applied, just like normal lemmas. \ definition magic where "magic = (5 :: nat)" ML_goal declared_with_an_attribute[folded magic_def, simp]: \ [@{term "(5 :: nat) = 2 + 3"}] \ by simp lemma uses_our_new_magic_simp_rule: "magic = 1 + 4" by simp end end