Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Archive-of-Formal-Proofs/thys/LL1_Parser/   (Sammlung formaler Beweise Version 2026-5©)  Datei vom 29.4.2026 mit Größe 41 kB image not shown  

Quelle  First_Map.thy

  Sprache: Isabelle
 

section \>First java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "macro" is null

theory
imports Nullable_Set "HOL-Library.Finite_Map""list_union ls1=ls1 @ flr (<>x. x \notins)ls)"
begin

type_synonym ('n, 't) first_map = "('n, 't lookahead list) fmap"

fun nullableSym :: "('n, 't) symbol ==> 'n set ==> bool" where
  "nullableSym (T _) _ = False"
"nullableSym (NT x) nu = (x nu)"

definition findOrEmpty :: "'n ==> ('n, 't) first_map ==> 't lookahead list" where
  "findOrEmpty x m = (case fmlookup m x of None ==> [] | Some y ==> y)"

fun firstSym :: "('n, 't) symbol ==> ('n, 't) first_map ==> 't lookahead list" where
  "firstSym (T x) _ = [LA x]"
"firstSym (NT x) fi = findOrEmpty x fi"


definition list_union :: "'a list ==> 'a list ==> 'a list" (infixr @@ 65where
  "list_union ls1 ls2 = ls1 @ (filter (λx. x set ls1) ls2)"

lemma in_atleast1_list: "a set (ls1 @@ ls2) ==> a set ls1 a set ls2"
  unfolding list_union_def
  by auto

lemma set_list_union[simp]: "set (ls1 @@ ls2) = set ls1 set ls2"
  unfolding list_union_def
  by auto

lemma mem_list_union: "ls1 = ls1 @@ ls2 ==> unnfolding l list_unon_ef
  by (metis Un_if set_list_unio)

lemma list_union_I2: " set ls2 ==> e  set (ls1 @@ ls2)"
  by simp

fun firstGamma :: "('n, 't) rhs ==> 'n set ==> ('n, 't) first_map ==> 't lookahead list" where
  "firstGamma [] _ _ = []"
| "firstGamma (s#gamma') nu fi =
    (if nullableSym s nu then firstSym s fi @@ firstGamma gamma' nu fi else firstSym s fi)"

definition updateFi :: "'n set ==> ('n, 't) prod ==>
  updateFi λnu (x, gamma) fi. (let
    fg = firstGamma gammametis Un_iff
    xFirst x fi;
    xFirst=xFirst @@ fg (ifxFirst'  xFirst  else x xFirst'fi))java.lang.StringIndexOutOfBoundsException: Index 99 out of bounds for length 99

definition firstPass :: "('n, 't) prods ==> 'n set ==> ('n, 't) first_map ==> ('n, 't) first_map" where
  "firstPass ps nu fi = foldr (updateFi nu) ps fi"

partial_function (option) mkFirstMap' :: "('n, 't) prods ==> 'n set ==> ('n, 't) first_map
    ==> ('n, 't) first_map option" where
  "mkFirstMap' ps nu fi = (let fi' = firstPass ps nu fi in
    (if fi = fi' then Some fi else mkFirstMap' ps nu fi'))"

definition mkFirstMap :: "('n, 't) grammar ==> 'n set ==> ('n, 't) first_map" where
  "mkFirstMap g nu = the (mkFirstMap' (prods g) nu fmempty)"


subsection Termination

fun leftmostLookahead :: "('n, 't) rhs ==> 't lookahead option" where
  "leftmostLookahead [] = None"
"leftmostLookahead ((T y)#gamma') = Some (LA y)"
"leftmostLookahead ((NT _)#gamma') = leftmostLookahead gamma'"

definition leftmostLookaheads :: "('n, 't) prods ==> 't lookahead set" where
  "leftmostLookaheads ps = the ` leftmostLookahead ` snd ` set ps"

lemma in_leftmostLookaheads_cons: "x leftmostLookaheads ps ==> x leftmostLookaheads (p # ps)"
  unfolding leftmostLookaheads_def by auto

definition:(', ') first_map ==> 't lookahead) set" where
  "pairsOf fi = {(a, b). a | firstSym firstGamma'   else"

definition all_nt :: "('n"pdateFi <> \lambdam (t
   fndOrpt

definition all_pairs_are_first_candidates:: "('n, 't) first_map ==> ('n, 't) prods ==> 'n set ==> ('n, 't) first_map

  (' :: "('n, 't) prods \Rightarrow' set 🚫

definition countFirstCands :: "('n,')prods ('map nat"e
  "countFirstCands
    card (allCandidates

 llable_leftmost_lk_some
    Longrightarrow leftmostLookahead (gpreuf
  by"tmostLookahead a fttoaeda

lemma gpre_nullable_in_left lefps e etsLookae`se s
  "(x, (@ #)<>set ps ==> all_nt gpre ==>\in>leftmostLookaheads
roof(induction ps)
  case Nil
  then show ?case by auto
next
  case (Conspjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
  then ow
  proof (cases "p
    case r
    then "all_pairs_are_first_candidates ps =
      usingons)pre_nullable_leftmost_lk_some_me
  next
    case
 n gnssimpeftmostLookaheads_cons
  qed
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

lemma
  ( )in set ps all_nt gpre (LA y)<>leftmostLookaheads ps"
  e
sing
proofnductioninu bta: p)
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
  then show ?case by auto
next
  case (Cons y gsuf)
  consider (T) a where "y = T a" | (NT_nullable) a where "y = NT a" and "nullableSym y nu"
    | (NT_not_nullable) a where "y = NT a" and "¬ nullableSym y nu" by (cases y; auto)
  then show ?case
  proof cases
    case T
    then show ?thesis using Cons.prems by (auto intro: gpre_nullable_in_leftmost_lks)
  next
    case (NT_nullable a)
    then consider (in_findOrEmpty) "la 
     rstGamma set (firstGamma gsuf
      usinga"nd< nullableSym y nu" by (cases y; auto)
    then show ?thesis
proof
      
      ve<>fi_
        using  next
      wusing_candidates_def
    next
      eirstGamma
      then       _ty
        (auto]pdall_nt_def
    qed
  next
    case NT_not_nullable
    nin> pairsOf sOf_def
      (cases "fmlookup fi a"; auto intro: fmdomI simp add: NT_not_nullable findOrEmpty_def)
    not_nullableave \inusingdef
  qed
qed

lemman_firstGamma_in_leftmost_lks set ps ==>
  ==> set (firstGamma gamma nu fi la 
  byintroeftmost_lkspadd_def

lemma updateFi_cases
  xesmman' rhs
  efines> firstGamma gamma nu fi"
  defines "st findOrEmpty x fi"
'equiv>xFirst @@ fg"
  obtains (unchangedateFi
  | (emptypdateFi
    wwhere xFirst ==> set fg<>lapsjava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
    updateFi nudst
  unfolding updateFi_defp ps'. (P ps' nu fi = firstPass'i P (p # ps') nu
  by atomize_elim (auto split: if_split_asm simp: Let_def xFirstbylistls. P   ;)

lemma firstPass_induct:
  s'rods
    andu'
    :'st_map
    andOrEmpty_exists_set
  assumes[i
'siLongrightarrow> fi 🚫
    and Cons_same: "Pni<> fi frstsspnu i\Longrightarrow P (p # ps') nu fi)"
  shows "P (ps :: ('n, 't) prods) nu fi"
  using Nil Cons_changed Cons_same
   tterels. P ls nu

lemma_rEmpty_iff_in_pairsOf set (findOrEmpty x fi longleftrightarrow (x, la) < pairsOflist_union_def
  unfoldingmpty_def

lemma in_pairsOf_exists
  unfolding pairsOf_deffindOrEmpty_def_byorce

lemma in_findOrEmpty_exists_set:
    "la > pairsOf fi"
  using in_findOrEmpty_iff_in_pairsOf   obtain maa wherea)  es

lemmadd_value pairsOf (fmupd x s fi)  set s"
  by (simp add: in_pairsOf_exists)

lemma firstPass_Nil[simp]: "firstPass [] x y = y"
  unfolding firstPass_def by simp

text<Lemma for the simplification of termPass<>.
In ca2
insteadreplacingihisdeftini <term\open.net

lemma firstPass_cons[simp]: "firstPass
  by (simp


   OrEmptyi
 \ori@amma
  thenfmlookup fmlookup fi x = Some
  case

lemma
  by(OrEmpty_iff_in_pairsOfty_def
 ion
lemma in_add_keys_neq
  by (okup fmlookup (firstPass


lemma updateFi_subset: "pairsOf fi
proof e ureI)
  fix y la
  assume A: "(<inirsOf
  obtain x gamma where p_def: " (, gam) (ces
nsideri
    | "x =
    | "x y" "updateFi nu (x, gamma) fi = fmupd x (findOrEmpt x f@fsaaga i i
    usingunl_patF by ets
  then o ")<in pairsOf (updateFijava.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
  ?or> ?fg = []")
1
    then fdOEmtyx(fldptFn# )f
  next
    case
   ?
by (simp add: A in_add_value in_findOrEmpty_iff_in_pairsOf p_def list_union_def)
  next
    case 3
    then show ?thesis
      by (metis A in_add_keys_neq p_def)
  l
qed
 
lemma f l m (d(pateFin) i)
  using updal?r'xis

lemmahesis
  by( rts pdeFdf)

lemma_my frPas i irmp f f'
  using

lemmay_set
  " rstPass_def
findOrEmptymmatPass
case
  then
next
  caseuto
  thenjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
qed

a"pu=o \>x No"
 ction
ase
  re  

  case java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
then
qed

lemma firstPass_neq_findOrEmpty
  assumes "fmlookup fi x
  Longrightarrow> pairsOf (firstPass ps nu fi) lmstokha < asff"
proof (then
  case None
  then have "fmlookup fi x = None" by (auto intro: firstPass_None)
  then shownext
nextobtainmma

 hen<>[]" using firstPass_empty_set assms by fastforce
  then show ?thesis
    using assms
     atosmad SoeidOEpyde li to.si)
qed

textpairsOf

lemma firstPass_only_appends: "thenjava.lang.StringIndexOutOfBoundsException: Index 82 out of bounds for length 82
  unfoldingPass_def
proof (induction ps)
  case Nil
  then show ?case by auto
next
  case (Cons p ps  moreovere"et< leftmostLookaheads ps - pairsOf (firstPass ps nu fi)
  obtain y gamma where p_def: "p = (y, gamma)" by (cases)
 ammardateFi fi
  let ?xFirst = "findOrEmpty
  let ?xFirst' = "?xFirst @@ proofrule
  show case
  proof (cases "?xFirst      ( <in OfPass#')rjava.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
    case True
    then show ?thesis using p_def Cons by         firstPass_conss_cons xammaaps2fiunfold_updateFixammajava.lang.StringIndexOutOfBoundsException: Index 87 out of bounds for length 87
  next
    case False
    note outerFalse = this
    have "findOrEmpty x (foldr (updateFinu   )java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
     mupddrupdateFis)
      using p_def False by (auto simp add: updateFi_defjava.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
    then show ?thesis using Cons by (cases "x = y") (auto simp add: list_union_def findOrEmpty_def)
  qed
qed

lemma
  \<Longrightarrow> suf \<noteq> [] \<Longrightarrow> la \<in> set suf \<Longrightarrow> la \<notin> set (findOrEmpty x fi)"
proof (induction ps arbitrary: x fi suf)
  case Nil
  then show ?case by auto
java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
  case (Cons p ps)
  obtain y gamma where p_def: "p = (y, gamma)" by (cases p)
  let ?fg = "firstGamma gamma nu (foldr (updateFi nu) ps fi)"
  let ?xFirst = "findOrEmpty y (foldr (updateFi nu) ps fi)"
  letshowsfirst_sym
show
  proof (cases "
True
    then 
      using Cons.IH Cons.prems(1-3)_

  next
    ealse
    obtain
)
      \Longrightarrow> xgpresuf\>setprods\ongrightarrow nullable_gamma g gpre
      proof (cases "x = y")
        caseTrue
          enhave"findOrEmptyx(rstPass snu ) First
          using False p_def
          by (simp add: findOrEmpty_def firstPass_def updateFi_def)
        proofases
            = (findOrEmpty x fi @ suf')rstGammamanurstPassufi
          using Cons.prems(1) suf'_def True
          by (auto qed
        wesisnfoldinglist_union_defConsfef orce
       irstGamma_first_symr<> first_map_sound fi g
        case False
        then have "findOrEmpty x (firstPass (p # ps) nu fi) = findOrEmpty x (firstPass \>(x, gamma) \<in> set (prods g) \< la \<in> set (firstGamma gamma nu fi)\>first_sym g la (NT x)"
          using p_def by (auto simp add: findOrEmpty_def updateFi_defproofjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
        then show ?thesis using Cons by auto
      qed
       lookuppdrst@@ ?xFirst') ?fi') y = omemerst\> tFirst
qed

lemma pairsOf_injinoteq firstPass ps nu fi \<Longrightarrow> pairsOf fi \<noteq> pairsOf (firstPassps)
 -
  assumeess
  Pass_preserves_apac sremsjava.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
    using firstPass_neq_findOrEmpty
    by (metis fmap_ext)
  obtain suf where suf_def: "by (simp add irstPass_not_equiv_candidates_lteserves_apacs_apac
      and " "uf\<noteq> []
    ingirstPass_only_appendsfyorce
thenlaerea<n>set suf" and "la \<notin> set (findOrEmpty y fi)"
    by (meson firstPass_suf_distinct last_in_set suf_def)
  then show ?thesis
   _ndOrEmpty_iff_in_pairsOfsuf_defjava.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
    by fastforce
qed

lemma firstPass_not_equiv_subset:
  "fi \<noteq> firstPass ps nu fi
  using pairsOf_inj firstPass_subset by blast

lemma caseNil
  \
proof (induction ps)
  case Nil
  then show ?case by simp
next
  case (Cons p ps)
Longrightarrow> \<exists>xFirst'. ookuprstPassi t and set xFirst \<subseteq> set xFirst'"
  from Cons.prems have "all_pairs_are_first_candidatesfirstGamma'
    unfolding all_pairs_are_first_candidates_def using firstPass_cons_subset by blast
  then thenaveookupirstPassp)u)lookupfixjava.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
    by (auto intro: in_firstGamma_in_leftmost_lks simp add: \<open>p = (x, gamma)\<close>)
  then show ?case using Cons.prems all_pairs_are_first_candidates_def by fastforce
qed

lemma       then have "fmlookup (firstPass(p#psnuixeFirstusinge
 ldinging ftmostLookaheads_def

lemma firstPass_not_equiv_candidates_lt: "all_pairs_are_first_candidates (stPass ips
  \<Longrightarrow> fi \<noteq> (firstPass ps nu fi)
          by fastforce
proof
      casealse
    and A2: "fi \<noteq> (firstPass        by( :open>p ma<lose unfold_updateFi)
  have "finite (lhSet ps \<times> leftmostLookaheads ps)"
    java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
    tstjava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
      \<subset> lhSet ps \<times> leftmostLookaheads ps - pairsOf fi"
    using firstPass_not_equiv_subset firstPass_subset_lhs_lksA1  stforce
matelyt< leftmostLookaheads ps - pairsOf (firstPass ps nu fi))
    < card (lhSet ps \<times> leftmostLookaheads ps - pairsOf fi)"
    by (auto intro: psubset_card_mono
  then show "countFirstCands ps (firstPass ps nu fi) < countFirstCands ps fi"
    unfoldingnext
qed

lemma firstPass_preserves_apac': "all_pairs_are_first_candidates fi ps1ps2
  \<Longrightarrow> all_pairs_are_first_candidates (firstPass ps2 nu    #java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
proofthen
  case Nil
  then show ?case unfolding all_pairs_are_first_candidates_def by (simp add: firstPass_def)
next
  case (Cons p ps2')
  obtain x gamma where p_def: "p = (x        (metis fmupd_lookup)
  then show ?case using Cons.IH[of "ps1 @ [p]"] Cons.prems
  proof (cases -Consereppre = "ppre @ [p]"], auto)
      updateFi_cases[where x = x and nu = nu and gamma = gamma and i=rstPass  ]
    case (new la)
    then have "x' \<in> lhSet (ps1 lemma firstPass_equiv_right_nt' nullable_set_for<Longrightarrow> fi=rstPassufui
      if "(x', a <inpairsOfsOf(firstPasstPass(  2nui)for java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
   
      from that consider "x = x'" and "la' \<in>cases
        | "x = x'" and "la' \<in> set (firstGamma         [where=erxuf]
        | "(x'la in pairsOf (firstPass ps2' nu fi)"
        unfolding p_def
gass_consofx mmaps2u]fold_updateFi  amma
          in_add_keys in_add_keys_neq in_atleast1_list
        by metis
       isngsremsonsf1p
        by (cases,ed
          simp: lhSet_def p_def all_pairs_are_first_candidates_def in_findOrEmpty_iff_in_pairsOf
    qed
    then show ?thesis by (simp add: all_pairs_are_first_candidates_def
  qed (auto simp add: p_def)
qed

lemma firstPass_preserves_apac:
  "all_pairs_are_first_candidates java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
  using firstPass_preserves_apac'[of fi "[]" ps] byuto

text\<open>Termination proof for \<^term>\<open>mkFirstMap'\<close> given that   java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
sallherefore everyowingingeration<close

lemma mkFirstMap'_dom_if_apac:
  "mkFirstMap' ps nu fi \<noteq> None" if "all_pairs_are_first_candidates fi ps"
  using that
proof (induction "(ps, nu, fi)" arbitrary: fi
    rule: measure_induct_rule[where f = "\<lambda>(ps, nu, fi). countFirstCands  ]
  case
  ave\<>firstPass ps nu fi \<Longrightarrow> countFirstCands ps (firstPass ps nu fi) < countFirstCands ps i"
    using less.prems by (simp add: firstPass_not_equiv_candidates_lt firstPass_preserves_apac)
  moreover have "fi \<noteq> firstPass ps nu fi \<Longrightarrow> all_pairs_are_first_candidates (firstPass ps nu fi) ps"
    using less.prems by (rule firstPass_preserves_apac)
  ultimately have F: "fi \<noteq> firstPass ps nu fi \<Longrightarrow> mkFirstMap' ps nu (firstPass ps nu fi) \<noteq> None" by
    (simp add: less.hyps)
  then show ?case
  proof (cases "fi \<noteq> firstPass ps nu fi")
    case True
    then show ?thesis using F by (simp add: mkFirstMap'.simps[of ps nu fi])
  next
    case False
    then show ?thesis by (simp add: mkFirstMap'.simps[of ps nu fi])
  qed
qed

lemma empty_fi_apac: "all_pairs_are_first_candidates fmempty ps"
  unfolding all_pairs_are_first_candidates_def pairsOf_def by auto

lemma mkFirstMap_simp: "mkFirstMap g nu \<equiv> (let fi' = firstPass (prods g) nu fmempty in
    (if fmempty = fi' then fmempty else the (mkFirstMap' (prods g) nu fi')))"
  unfolding mkFirstMap_def
  by (smt (verit, del_insts) mkFirstMap'.simps option.sel)


subsection \<open>Correctness Definitions\<close>

definition first_map_sound :: "('n, 't) first_map \<Rightarrow> ('n, 't) grammar \<Rightarrow> bool" where
  "first_map_sound fi g =
  (\<forall>x la xFirst. fmlookup fi x = Some xFirst \<and> la \<in> set xFirst \<longrightarrow> first_sym g la (NT x))"

definition first_map_complete :: "('n, 't) first_map \<Rightarrow> ('n, 't) grammar \<Rightarrow> bool" where
  "first_map_complete fi g = (\<forall>la s x. first_sym g la s
    \<and> s = (NT x) \<longrightarrow> (\<exists>xFirst. fmlookup fi x = Some xFirst \<and> la \<in> set xFirst))"

abbreviation first_map_for :: "('n, 't) first_map \<Rightarrow> ('n, 't) grammar \<Rightarrow> bool" where
  "first_map_for fi g \<equiv> first_map_sound fi g \<and> first_map_complete fi g"


subsection \<open>Soundness\<close>

lemma firstSym_first_sym: assumes "first_map_sound fi g" and "la \<in> set (firstSym s fi)"
  shows "first_sym g la s"
proof (cases s)
  case (NT x)
  then show ?thesis using assms first_map_sound_def in_findOrEmpty_exists_set by fastforce
next
  case (T x)
  then show ?thesis using assms(2) FirstT by fastforce
qed

lemma nullable_app: "nullable_gamma g xs \<Longrightarrow> nullable_gamma g ys \<Longrightarrow> nullable_gamma g (xs @ ys)"
  by (induction xs; force elim: nullable_gamma.cases intro: NullableCons)

lemma nullableSym_nullable_sym: assumes "nullable_set_for nu g"
  shows "nullableSym s nu \<longleftrightarrow> nullable_sym g s"
proof (cases s)
  case (NT x1)
  then show ?thesis using assms nullable_set_sound_def nullable_set_complete_def by fastforce
next
  case (T x2)
  then show ?thesis by (simp add: nullable_sym.simps)
qed

lemma firstGamma_first_sym': "nullable_set_for nu g \<Longrightarrow> first_map_sound fi g
  \<Longrightarrow> (x, gpre @ gsuf) \<in> set (prods g) \<Longrightarrow> nullable_gamma g gpre
  \<Longrightarrow> la \<in> set (firstGamma gsuf nu fi) \<Longrightarrow> first_sym g la (NT x)"
proof (induction gsuf arbitrary: gpre)
  case Nil
  then show ?case by auto
next
  case (Cons s syms)
  then show ?case
  proof (cases "nullableSym s nu")
    case True
    consider (la_in_firstSym) "la \<in> set (firstSym s fi)"
      | (la_in_firstGamma) "la \<in> set (firstGamma syms nu fi)"
      using Cons.prems(5) True by auto
    then show ?thesis
    proof (cases)
      case la_in_firstSym
      then show ?thesis using Cons.prems(2,3,4) FirstNT firstSym_first_sym by fast
    next
      case la_in_firstGamma
      have "(x, (gpre @ [s]) @ syms) \<in> set (prods g)" using Cons.prems(3) by auto
      moreover have "nullable_gamma g (gpre @ [s])"
      proof (rule nullable_app)
        show "nullable_gamma g gpre" by (simp add: Cons.prems(4))
      next
        have "nullable_sym g s" using Cons.prems(1) True nullableSym_nullable_sym by auto
        then show "nullable_gamma g [s]" by - (rule NullableCons, auto simp add: NullableNil)
      qed
      moreover have "la \<in> set (firstGamma syms nu fi)" by (simp add: la_in_firstGamma)
      ultimately show ?thesis using Cons.prems(1,2) by - (rule Cons.IH[where gpre = "gpre @ [s]"])
    qed
  next
    case False
    then show ?thesis using firstSym_first_sym Cons.prems(2,3,4,5) FirstNT by fastforce
  qed
qed

lemma firstGamma_first_sym: "nullable_set_for nu g \<Longrightarrow> first_map_sound fi g
    \<Longrightarrow> (x, gamma) \<in> set (prods g) \<Longrightarrow> la \<in> set (firstGamma gamma nu fi) \<Longrightarrow> first_sym g la (NT x)"
  using NullableNil append.left_neutral firstGamma_first_sym' by force

lemma firstPass_preserves_soundness': "nullable_set_for nu g \<Longrightarrow> first_map_sound fi g
  \<Longrightarrow> set ps \<subseteq> set (prods g) \<Longrightarrow> first_map_sound (firstPass ps nu fi) g"
proof (induction ps)
  case Nil
  then show ?case by (simp add: firstPass_def)
next
  case (Cons a suf)
  obtain x gamma where "a = (x, gamma)" by fastforce
  let ?fi' = "firstPass suf nu fi"
  let ?fg = "firstGamma gamma nu ?fi'"
  let ?xFirst = "findOrEmpty x ?fi'"
  let ?xFirst' = "?xFirst @@ ?fg"
  have fi'_sound: "first_map_sound ?fi' g" using Cons by auto
  show ?case
  proof (cases "?xFirst = ?xFirst'")
    case True
    then show ?thesis using \<open>a = (x, gamma)\<close> True fi'_sound by (auto simp add: unfold_updateFi)
  next
    case False
    have "fmlookup (fmupd x (?xFirst @@ ?xFirst') ?fi') y = Some yFirst  \<Longrightarrow> la \<in> set yFirst
        \<Longrightarrow> first_sym g la (NT y)" for y yFirst la
    proof (cases "x = y")
      case True
      assume "fmlookup (fmupd x (?xFirst @@ ?xFirst') ?fi') y = Some yFirst" "la \<in> set yFirst"
      then consider (la_in_xFirst) "la \<in> set ?xFirst" | (la_in_fg) "la \<in> set ?fg"
        using \<open>la \<in> set yFirst\<close> True
        by auto
      then show ?thesis
      proof (cases)
        case la_in_xFirst
        then have "la \<in> set (firstSym (NT y) ?fi')" using True by auto
        then show ?thesis by - (rule firstSym_first_sym, auto simp add: fi'_sound)
      next
        case la_in_fg
        have "(y, gamma) \<in> set (prods g)" using Cons.prems(3) True \<open>a = (x, gamma)\<close> by auto
      then show ?thesis using fi'_sound Cons.prems(1) la_in_fg by
        - (rule firstGamma_first_sym[of nu g ?fi' y gamma], auto)
      qed
    next
      case False
      assume "fmlookup (fmupd x (?xFirst @@ ?xFirst') ?fi') y = Some yFirst" "la \<in> set yFirst"
      then have "fmlookup ?fi' y = Some yFirst" by (simp add: False)
      then show ?thesis using \<open>la \<in> set yFirst\<close> fi'_sound first_map_sound_def by fastforce
    qed
    then have "first_map_sound (fmupd x ?xFirst' ?fi') g" unfolding first_map_sound_def by auto
    then show ?thesis using \<open>a = (x, gamma)\<close> False fi'_sound by (auto simp add: unfold_updateFi)
  qed
qed

lemma firstPass_preserves_soundness: "nullable_set_for nu g \<Longrightarrow> first_map_sound fi g
    \<Longrightarrow> first_map_sound (firstPass (prods g) nu fi) g"
  by (simp add: firstPass_preserves_soundness')

lemma mkFirstMap'_preserves_soundness: "nullable_set_for nu g \<Longrightarrow> first_map_sound fi g
  \<Longrightarrow> all_pairs_are_first_candidates fi (prods g)
  \<Longrightarrow> first_map_sound (the (mkFirstMap' (prods g) nu fi)) g"
proof (induction "countFirstCands (prods g) fi" arbitrary: fi rule: less_induct)
  case less
  let ?fi' = "firstPass (prods g) nu fi"
  obtain fi'' where fi''_def: "mkFirstMap' (prods g) nu ?fi' = Some fi''"
    using firstPass_preserves_apac[of fi "prods g" nu] less.prems(3)
      mkFirstMap'_dom_if_apac[of "firstPass (prods g) nu fi"] by auto
  moreover have "first_map_sound (if fi = ?fi' then fi else fi'') g"
  proof (cases "fi = ?fi'")
    case True
    then show ?thesis using less.prems(2) by auto
  next
    case False
    have "countFirstCands (prods g) ?fi' < countFirstCands (prods g) fi" using less.prems(3) False
      by (simp add: firstPass_not_equiv_candidates_lt firstPass_preserves_apac)
    moreover have "first_map_sound ?fi' g" using less.prems by
      - (rule firstPass_preserves_soundness, auto)
    ultimately show ?thesis using firstPass_preserves_apac less fi''_def by fastforce
  qed
  ultimately show ?case by (auto simp add: mkFirstMap'.simps Let_def)
qed

lemma empty_fi_sound: "first_map_sound fmempty g"
  unfolding first_map_sound_def by auto

theorem mkFirstMap_sound: "nullable_set_for nu g \<Longrightarrow> first_map_sound (mkFirstMap g nu) g"
  unfolding mkFirstMap_def
  by (simp add: empty_fi_sound mkFirstMap'_preserves_soundness empty_fi_apac)


subsection \<open>Completeness\<close>

lemma la_in_firstGamma_t: "nullable_set_for nu g \<Longrightarrow> nullable_gamma g gpre
  \<Longrightarrow> LA y \<in> set (firstGamma (gpre @ T y # gsuf) nu fi)"
proof (induction gpre)
  case Nil
  then show ?case by simp
next
  case (Cons s gpre)
  from Cons.prems(2) have "nullable_sym g s" by (cases) auto
  then have "nullableSym s nu" using Cons.prems(1) nullableSym_nullable_sym by blast
  from Cons.prems(2) have "nullable_gamma g gpre" by (cases) simp
  then have "LA y \<in> set (firstGamma (gpre @ T y # gsuf) nu fi)" using Cons.IH Cons.prems(1) by auto
  then show ?case using \<open>nullableSym s nu\<close> by auto
qed

lemma la_in_firstGamma_nt: "nullable_set_for nu g \<Longrightarrow> nullable_gamma g gpre
  \<Longrightarrow> fmlookup fi x = Some xFirst \<Longrightarrow> la \<in> set xFirst
  \<Longrightarrow> la \<in> set (firstGamma (gpre @ NT x # gsuf) nu fi)"
proof (induction gpre)
  case Nil
  then show ?case by (simp add: findOrEmpty_def)
next
  case (Cons s gpre)
  from Cons.prems(2) have "nullable_sym g s" by (cases) auto
  then have "nullableSym s nu" using Cons.prems(1) nullableSym_nullable_sym by blast
  from Cons.prems(2) have "nullable_gamma g gpre" by (cases) simp
  then have "la \<in> set (firstGamma (gpre @ NT x # gsuf) nu fi)"
    using Cons.IH Cons.prems(1,3,4) by blast
  then show ?case using \<open>nullableSym s nu\<close> by auto
qed

lemma firstPass_preserves_key_value_subset: "fmlookup fi x = Some xFirst
  \<Longrightarrow> \<exists>xFirst'. fmlookup (firstPass ps nu fi) x = Some xFirst' \<and> set xFirst \<subseteq> set xFirst'"
proof (induction ps arbitrary: x)
  case Nil
  then show ?case unfolding firstPass_def by auto
next
  case (Cons p ps)
  then obtain y gamma where "p = (y, gamma)" by fastforce
  let ?fi' = "firstPass ps nu fi"
  let ?fg = "firstGamma gamma nu ?fi'"
  let ?yFirst = "findOrEmpty y ?fi'"
  let ?yFirst' = "?yFirst @@ ?fg"
  obtain xFirst' where "fmlookup ?fi' x = Some xFirst'" and "set xFirst \<subseteq> set xFirst'"
    using Cons by auto
  show ?case
  proof (cases "?yFirst = ?yFirst'")
    case True
    then have "fmlookup (firstPass (p # ps) nu fi) x = fmlookup ?fi' x" by
      (simp add: \<open>p = (y, gamma)\<close> unfold_updateFi)
    then show ?thesis using \<open>fmlookup ?fi' x = Some xFirst'\<close> \<open>set xFirst \<subseteq> set xFirst'\<close> by simp
  next
    case False
    show ?thesis
    proof (cases "x = y")
      case True
      then have "fmlookup (firstPass (p # ps) nu fi) x = Some ?yFirst'" using False by
        (auto simp add: \<open>p = (y, gamma)\<close> unfold_updateFi list_union_def)
      moreover have "set xFirst' \<subseteq> set ?yFirst'"
        using True \<open>fmlookup ?fi' x = Some xFirst'\<close> findOrEmpty_def in_findOrEmpty_exists_set
        by fastforce
      ultimately show ?thesis using \<open>set xFirst \<subseteq> set xFirst'\<close> by blast
    next
      case False
      then have "fmlookup (firstPass (p # ps) nu fi) x = fmlookup ?fi' x"
        by (simp add: \<open>p = (y, gamma)\<close> unfold_updateFi)
      then show ?thesis using \<open>fmlookup ?fi' x = Some xFirst'\<close> \<open>set xFirst \<subseteq> set xFirst'\<close> by simp
    qed
  qed
qed

lemma firstPass_equiv_cons_tl: assumes "fi = firstPass (p # ps) nu fi"
  shows "fi = firstPass ps nu fi"
proof-
  obtain x gamma where "p = (x, gamma)" by fastforce
  let ?fi' = "firstPass ps nu fi"
  let ?fg = "firstGamma gamma nu ?fi'"
  let ?xFirst = "findOrEmpty x ?fi'"
  let ?xFirst' = "?xFirst @@ ?fg"
  show "fi = firstPass ps nu fi"
  proof (cases "?xFirst = ?xFirst'")
    case True
    then show ?thesis using True assms by (auto simp add: \<open>p = (x, gamma)\<close> unfold_updateFi)
  next
    case False
    show ?thesis
    proof -
      have "fi = fmupd x ?xFirst' ?fi'" using False assms by
        (simp add: \<open>p = (x, gamma)\<close> unfold_updateFi list_union_def split: if_splits)
      then have "fmlookup fi x = Some ?xFirst'" by (metis fmupd_lookup)
      have "firstPass ps nu fi = fi"
        by (metis assms firstPass_cons_subset firstPass_subset pairsOf_inj subset_antisym)
      then have "firstGamma gamma nu (firstPass ps nu fi) = []"
        using \<open>fmlookup fi x = Some ?xFirst'\<close> False
        unfolding findOrEmpty_def by (auto split: option.splits)
      moreover have "firstGamma gamma nu (firstPass ps nu fi) \<noteq> []"
        by (metis False append_self_conv empty_iff filter_True list.set(1) list_union_def)
      ultimately show "fi = firstPass ps nu fi" by auto
    qed
  qed
qed

lemma firstPass_equiv_right_t': "(lx, gpre @ (T y) # gsuf) \<in> set psuf \<Longrightarrow> nullable_set_for nu g
  \<Longrightarrow> nullable_gamma g gpre \<Longrightarrow> fi = firstPass psuf nu fi \<Longrightarrow> prods g = ppre @ psuf
  \<Longrightarrow> (\<exists>lxFirst. fmlookup fi lx = Some lxFirst \<and> (LA y) \<in> set lxFirst)"
proof (induction psuf arbitrary: ppre)
  case Nil
  then show ?case by auto
next
  case (Cons p psuf)
  obtain lx' gamma where "p = (lx', gamma)" by fastforce
  from Cons.prems(1) consider (prod_is_p) "(lx, gpre @ T y # gsuf) = p"
    | (prod_in_psuf) "(lx, gpre @ T y # gsuf) \<in> set psuf" by auto
  then show ?case
  proof (cases)
    case prod_is_p
    let ?fi' = "firstPass psuf nu fi"
    let ?fg = "firstGamma (gpre @ T y # gsuf) nu ?fi'"
    let ?lxFirst = "findOrEmpty lx ?fi'"
    let ?lxFirst' = "?lxFirst @@ ?fg"
    from Cons.prems(4) have " fi = firstPass ((lx, gpre @ T y # gsuf) # psuf) nu fi"
      using prod_is_p by blast
    then consider (same) "?lxFirst = ?lxFirst'" "fi = firstPass psuf nu fi"
      | (new) "?lxFirst \<noteq> ?lxFirst'" "fi = fmupd lx ?lxFirst' ?fi'"
      by (metis Nil_is_append_conv firstPass_cons list_union_def unfold_updateFi)
    then show ?thesis
    proof (cases)
      case same
      have "LA y \<in> set ?fg" using Cons.prems(2,3) by - (rule la_in_firstGamma_t, auto)
      then have "LA y \<in> set ?lxFirst" using same(1) by (auto intro: mem_list_union)
      then have "LA y \<in> set (findOrEmpty lx fi)" using same(2) by auto
      then show ?thesis by (simp add: in_findOrEmpty_exists_set)
    next
      case new
      from new(2) obtain lxFirst where "fmlookup fi lx = Some lxFirst" and "?lxFirst' = lxFirst" by
        (metis fmupd_lookup)
      then have "LA y \<in> set lxFirst" using la_in_firstGamma_t Cons.prems(2,3) by fastforce
      then show ?thesis using \<open>fmlookup fi lx = Some lxFirst\<close> by simp
    qed
  next
    case prod_in_psuf
    then have "(lx, gpre @ T y # gsuf) \<in> set psuf" by auto
    moreover have "fi = firstPass psuf nu fi" using Cons.prems(4) firstPass_equiv_cons_tl by blast
    moreover have "prods g = (ppre @ [p]) @ psuf" by (simp add: Cons.prems(5))
    ultimately show ?thesis using Cons.prems(2,3) by
      - (rule Cons.IH[where ppre = "ppre @ [p]"], auto)
  qed
qed

lemma firstPass_equiv_right_t: "(lx, gpre @ (T y) # gsuf) \<in> set (prods g) \<Longrightarrow> nullable_set_for nu g
  \<Longrightarrow> nullable_gamma g gpre \<Longrightarrow> fi = firstPass (prods g) nu fi
  \<Longrightarrow> \<exists>lxFirst. fmlookup fi lx = Some lxFirst \<and> LA y \<in> set lxFirst"
  by (simp add: firstPass_equiv_right_t')

lemma firstPass_equiv_right_nt': "nullable_set_for nu g \<Longrightarrow> fi = firstPass psuf nu fi
  \<Longrightarrow> (lx, gpre @ (NT rx) # gsuf) \<in> set psuf \<Longrightarrow> nullable_gamma g gpre
  \<Longrightarrow> fmlookup fi rx = Some rxFirst \<Longrightarrow> la \<in> set rxFirst \<Longrightarrow> ppre @ psuf = (prods g)
  \<Longrightarrow> \<exists>lxFirst. fmlookup fi lx = Some lxFirst \<and> la \<in> set lxFirst"
proof (induction psuf arbitrary: ppre)
  case Nil
  then show ?case by auto
next
  case (Cons p psuf)
  obtain lx' gamma where "p = (lx', gamma)" by fastforce
  from Cons.prems(1) consider (prod_is_p) "(lx, gpre @ NT rx # gsuf) = p"
    | (prod_in_psuf) "(lx, gpre @ NT rx # gsuf) \<in> set psuf" using Cons.prems(3) by auto
  then show ?case
  proof (cases)
    case prod_is_p
    let ?fi' = "firstPass psuf nu fi"
    let ?fg = "firstGamma (gpre @ NT rx # gsuf) nu ?fi'"
    let ?lxFirst = "findOrEmpty lx ?fi'"
    let ?lxFirst' = "?lxFirst @@ ?fg"
    from Cons.prems(2) have "fi = firstPass ((lx, gpre @ NT rx # gsuf) # psuf) nu fi"
      using prod_is_p by blast
    then consider (same) "?lxFirst = ?lxFirst'" "fi = firstPass psuf nu fi"
      | (new) "?lxFirst \<noteq> ?lxFirst'" "fi = fmupd lx ?lxFirst' ?fi'"
      using firstPass_cons la_in_firstGamma_nt[OF Cons.prems(1,4-6)]
        unfold_updateFi[where gamma = "gpre @ NT rx # gsuf"]
      unfolding list_union_def
      by (auto split: if_splits)
    then show ?thesis
    proof (cases)
      case same
      then have "la \<in> set (findOrEmpty lx fi)" using Cons.prems(1,4,5,6) la_in_firstGamma_nt by
          (metis mem_list_union)
      then show ?thesis by (simp add: in_findOrEmpty_exists_set)
    next
      case new
      have "la \<in> set ?lxFirst'"
      proof (rule list_union_I2)
        from Cons.prems(2) have "fi = firstPass psuf nu fi" by (rule firstPass_equiv_cons_tl)
        then have "fmlookup (firstPass psuf nu fi) rx = Some rxFirst" using Cons.prems(5) by auto
        then show "la \<in> set ?fg"
          using Cons.prems(1,4,6) \<open>fi = firstPass ((lx, gpre @ NT rx # gsuf) # psuf) nu fi\<close>
          by - (rule la_in_firstGamma_nt[where xFirst = "rxFirst"])
      qed
      then show ?thesis by (metis fmupd_lookup new(2))
    qed
  next
    case prod_in_psuf
    then have "(lx, gpre @ NT rx # gsuf) \<in> set psuf" by auto
    moreover have "fi = firstPass psuf nu fi" using Cons.prems(2) firstPass_equiv_cons_tl by blast
    moreover have "prods g = (ppre @ [p]) @ psuf" by (simp add: Cons.prems(7))
    ultimately show ?thesis using Cons.prems(1,4,5,6,7) prod_in_psuf by
      - (rule Cons.IH[where ppre = "ppre @ [p]"], auto)
  qed
qed

lemma firstPass_equiv_right_nt: "nullable_set_for nu g \<Longrightarrow> fi = firstPass (prods g) nu fi
  \<Longrightarrow> (lx, gpre @ (NT rx) # gsuf) \<in> set (prods g) \<Longrightarrow> nullable_gamma g gpre
  \<Longrightarrow> fmlookup fi rx = Some rxFirst \<Longrightarrow> la \<in> set rxFirst
  \<Longrightarrow> \<exists>lxFirst. fmlookup fi lx = Some lxFirst \<and> la \<in> set lxFirst"
  by (simp add: firstPass_equiv_right_nt')

lemma firstPass_equiv_complete: assumes "nullable_set_for nu g" "fi = firstPass (prods g) nu fi"
  shows "first_map_complete fi g"
proof -
  have "first_sym g la s
    \<Longrightarrow> (\<forall>x. s = NT x \<longrightarrow> (\<exists> xFirst. fmlookup fi x = Some xFirst \<and> la \<in> set xFirst))" for la s
  proof (induction rule: first_sym.induct)
    case (FirstT)
    then show ?case by blast
  next
    case (FirstNT lx gpre s gsuf la)
    then show ?case
    proof (cases s)
      case (NT rx)
      then obtain rxFirst where "fmlookup fi rx = Some rxFirst \<and> la \<in> set rxFirst"
        using FirstNT.IH by auto
      then show ?thesis using FirstNT.hyps(1,2) NT assms firstPass_equiv_right_nt by fastforce
    next
      case (T y)
      from FirstNT.hyps(3) have "la = LA y" by (cases) (auto simp add: T)
      then show ?thesis using firstPass_equiv_right_t using FirstNT.hyps(1,2) T assms by fastforce
    qed
  qed
  then show ?thesis by (simp add: first_map_complete_def)
qed

lemma mkFirstMap'_complete: "nullable_set_for nu g \<Longrightarrow> all_pairs_are_first_candidates fi (prods g)
  \<Longrightarrow> first_map_complete (the (mkFirstMap' (prods g) nu fi)) g"
proof (induction "countFirstCands (prods g) fi" arbitrary: fi rule: less_induct)
  case less
  let ?fi' = "firstPass (prods g) nu fi"
  obtain fi' where fi'_def: "mkFirstMap' (prods g) nu ?fi' = Some fi'"
    by (meson firstPass_preserves_apac less.prems(2) mkFirstMap'_dom_if_apac not_Some_eq)
  moreover have "first_map_complete (if fi = ?fi' then fi else fi') g"
  proof (cases "fi = ?fi'")
    case True
    then show ?thesis using firstPass_equiv_complete less.prems(1) by auto
  next
    case False
    have "countFirstCands (prods g) ?fi' < countFirstCands (prods g) fi" by
      (simp add: False firstPass_not_equiv_candidates_lt firstPass_preserves_apac less.prems(2))
    moreover have "nullable_set_for nu g" by (simp add: less.prems(1))
    moreover have "all_pairs_are_first_candidates ?fi' (prods g)" by
      (simp add: firstPass_preserves_apac less.prems(2))
    ultimately show ?thesis
      using fi'_def less.hyps by force
  qed
  ultimately show ?case by (auto simp add: mkFirstMap'.simps Let_def)
qed

theorem mkFirstMap_complete: "nullable_set_for nu g \<Longrightarrow> first_map_complete (mkFirstMap g nu) g"
  unfolding mkFirstMap_def
  using empty_fi_apac mkFirstMap'_complete by fastforce

theorem mkFirstMap_correct: "nullable_set_for nu g \<Longrightarrow> first_map_for (mkFirstMap g nu) g"
  using mkFirstMap_sound mkFirstMap_complete
  by fastforce

declare mkFirstMap'.simps[code]

end

Messung V0.5 in Prozent
C=82 H=95 G=88

¤ Dauer der Verarbeitung: 0.32 Sekunden  (vorverarbeitet am  2026-06-10) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.