I am trying to formalize the proof that DFA are closed under union, and I have got so far as proving "ā š ā¬. language š āŖ language ā¬ = language (DFA_union š ā¬)"
, but what I would actually like to prove is ā š ā¬. ā š. language š āŖ language ā¬ = language š
. I belive the issue has something to do with polymorphic types, but I am not sure.
Here is what I have:
declare [[show_types]]
declare [[show_sorts]]
declare [[show_consts]]
record ('q, 'a)DFA =
Q0 :: 'q
F :: "'q set"
Ī“ :: "'q ā 'a ā 'q"
primrec Ī“_iter :: "('q, 'a)DFA ā 'a list ā 'q ā 'q" where
"Ī“_iter š [] q = q" |
"Ī“_iter š (a # as) q = Ī“_iter š as (Ī“ š q a)"
definition Ī“0_iter :: "('q, 'a)DFA ā 'a list ā 'q" where
"Ī“0_iter š as = Ī“_iter š as (Q0 š)"
definition language :: "('q, 'a)DFA ā ('a list) set" where
"language š = {w . Ī“0_iter š w ā (F š)}"
fun DFA_union :: "('p, 'a)DFA ā ('q, 'a)DFA ā ('p Ć 'q, 'a)DFA" where
"DFA_union š ā¬ =
ā¦ Q0 = (Q0 š, Q0 ā¬)
, F = {(q, r) . q ā F š āØ r ā F ā¬}
, Ī“ = Ī» (q, r). Ī» a. (Ī“ š q a, Ī“ ā¬ r a)
ā¦"
lemma extract_fst: "ā š ā¬ p q. fst (Ī“_iter (DFA_union š ā¬) ws (p, q)) = Ī“_iter š ws p"
by (induct ws; simp)
lemma extract_snd: "ā š ā¬ p q. snd (Ī“_iter (DFA_union š ā¬) ws (p, q)) = Ī“_iter ā¬ ws q"
by (induct ws; simp)
lemma "ā š ā¬. language š āŖ language ā¬ = language (DFA_union š ā¬)"
proof((rule allI)+)
fix š ā¬
let ?š = "DFA_union š ā¬"
have "language ?š = {w . Ī“0_iter ?š w ā F ?š}"
by (simp add: language_def)
also have "... = {w . fst (Ī“0_iter ?š w) ā (F š) āØ snd (Ī“0_iter ?š w) ā (F ā¬)}"
by auto
also have "... = {w . Ī“0_iter š w ā F š āØ Ī“0_iter ā¬ w ā F ā¬}"
using DFA.select_convs(1) DFA_union.simps Ī“0_iter_def extract_fst extract_snd
by (metis (no_types, lifting))
also have "... = {w . Ī“0_iter š w ā F š} āŖ {w. Ī“0_iter ā¬ w ā F ā¬}"
by blast
also have "... = language š āŖ language ā¬"
by (simp add: language_def)
finally show "language š āŖ language ā¬ = language ?š"
by simp
qed
lemma DFA_union_closed: "ā š ā¬. ā š. language š āŖ language ā¬ = language š"
sorry
If I add types to š or ā¬ in the main lemma I get "Failed to refine any pending goal".
the problem is indeed because of implicit types. In your last statement Isabelle implicitly infers state-types 'p, 'q, 'r
for the three automata A, B, C
,
whereas your DFA_union
lemma fixes the state type of C
to 'p * 'q
. Therefore, if you have to explicitly provide type-annotations. Moreover, it is usually not required to state your lemmas with explicit ā
-quantifiers.
So, you can continue like this:
lemma DFA_union: "language š āŖ language ā¬ = language (DFA_union š ā¬)"
(is "_ = language ?š")
proof -
have "language ?š = {w . Ī“0_iter ?š w ā F ?š}"
...
qed
lemma DFA_union_closed: fixes š :: "('q,'a)DFA" and ā¬ :: "('p,'a)DFA"
shows "ā š :: ('q Ć 'p, 'a)DFA. language š āŖ language ā¬ = language š"
by (intro exI, rule DFA_union)
Note that these type-annotations are also essential in the following sense. A lemma like the following (where all state-types are the same) is just not true.
lemma fixes š :: "('q,'a)DFA" and ā¬ :: "('q,'a)DFA"
shows "ā š :: ('q, 'a)DFA. language š āŖ language ā¬ = language š"
The problem is, plug in the bool
-type for 'q
, then you have automata which
have at most two states. And then you cannot always find an automaton for the union that also has at most two states.