isabelletheorem-provingautomaton

Existance proofs with polymorphic types


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".


Solution

  • 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.