Theory Regexp_Method
section ‹Proving Relation (In)equalities via Regular Expressions›
theory Regexp_Method
imports Equivalence_Checking Relation_Interpretation
begin
primrec rel_of_regexp :: "('a * 'a) set list ⇒ nat rexp ⇒ ('a * 'a) set" where
"rel_of_regexp vs Zero = {}" |
"rel_of_regexp vs One = Id" |
"rel_of_regexp vs (Atom i) = vs ! i" |
"rel_of_regexp vs (Plus r s) = rel_of_regexp vs r ∪ rel_of_regexp vs s " |
"rel_of_regexp vs (Times r s) = rel_of_regexp vs r O rel_of_regexp vs s" |
"rel_of_regexp vs (Star r) = (rel_of_regexp vs r)^*"
lemma rel_of_regexp_rel: "rel_of_regexp vs r = rel (λi. vs ! i) r"
by (induct r) auto
primrec rel_eq where
"rel_eq (r, s) vs = (rel_of_regexp vs r = rel_of_regexp vs s)"
lemma rel_eqI: "check_eqv r s ⟹ rel_eq (r, s) vs"
unfolding rel_eq.simps rel_of_regexp_rel
by (rule Relation_Interpretation.soundness)
(rule Equivalence_Checking.soundness)
lemmas regexp_reify = rel_of_regexp.simps rel_eq.simps
lemmas regexp_unfold = trancl_unfold_left subset_Un_eq
ML ‹
local
fun check_eqv (ct, b) = Thm.mk_binop @{cterm "Pure.eq :: bool ⇒ bool ⇒ prop"}
ct (if b then @{cterm True} else @{cterm False});
val (_, check_eqv_oracle) = Context.>>> (Context.map_theory_result
(Thm.add_oracle (@{binding check_eqv}, check_eqv)));
in
val regexp_conv =
@{computation_conv bool terms: check_eqv datatypes: "nat rexp"}
(fn _ => fn b => fn ct => check_eqv_oracle (ct, b))
end
›
method_setup regexp = ‹
Scan.succeed (fn ctxt =>
SIMPLE_METHOD' (
(TRY o eresolve_tac ctxt @{thms rev_subsetD})
THEN' (Subgoal.FOCUS_PARAMS (fn {context = ctxt', ...} =>
TRY (Local_Defs.unfold_tac ctxt' @{thms regexp_unfold})
THEN Reification.tac ctxt' @{thms regexp_reify} NONE 1
THEN resolve_tac ctxt' @{thms rel_eqI} 1
THEN CONVERSION (HOLogic.Trueprop_conv (regexp_conv ctxt')) 1
THEN resolve_tac ctxt' [TrueI] 1) ctxt)))
› ‹decide relation equalities via regular expressions›
hide_const (open) le_rexp nPlus nTimes norm nullable bisimilar is_bisimulation closure
pre_bisim add_atoms check_eqv rel word_rel rel_eq
text ‹Example:›
lemma "(r ∪ s^+)^* = (r ∪ s)^*"
by regexp
end