Theory LocalLexingLemmas
theory LocalLexingLemmas
imports LocalLexing Limit
begin
context LocalLexing begin
lemma[simp]: "setmonotone (Append Z k)" by (auto simp add: Append_def setmonotone_def)
lemma subset_𝒫Suc: "𝒫 k u ⊆ 𝒫 k (Suc u)"
  by (simp add: subset_setmonotone[OF setmonotone_limit])
lemma subset_fSuc_strict:
  assumes f: "⋀ u. f u ⊆ f (Suc u)"
  shows "u < v ⟹ f u ⊆ f v"
proof (induct v)
  show "u < 0 ⟹ f u ⊆ f 0"
    by auto
next
  fix v
  assume a:"(u < v ⟹ f u ⊆ f v)"
  assume b:"u < Suc v"
  from b have c: "f u ⊆ f v"
    apply (case_tac "u < v")
    apply (simp add: a)
    apply (case_tac "u = v")
    apply simp
    by auto
  show "f u ⊆ f (Suc v)"
    apply (rule subset_trans[OF c])
    by (rule f)
qed
lemma subset_fSuc:
  assumes f: "⋀ u. f u ⊆ f (Suc u)"
  shows "u ≤ v ⟹ f u ⊆ f v"
  apply (case_tac "u < v")
  apply (rule subset_fSuc_strict[where f=f, OF f])
  by auto
lemma subset_𝒫k: "u ≤ v ⟹ 𝒫 k u ⊆ 𝒫 k v"
  by (rule subset_fSuc, rule subset_𝒫Suc) 
  
lemma subset_𝒫𝒬k: "𝒫 k u ⊆ 𝒬 k" by (auto simp add: natUnion_def)
lemma subset_𝒬𝒫Suc: "𝒬 k ⊆ 𝒫 (Suc k) u" 
proof -
  have a: "𝒬 k ⊆ 𝒫 (Suc k) 0" by simp
  show ?thesis 
    apply (case_tac "u = 0")
    apply (simp add: a)
    apply (rule subset_trans[OF a subset_𝒫k])
    by auto
qed
lemma subset_𝒬Suc: "𝒬 k ⊆ 𝒬 (Suc k)"
  by (rule subset_trans[OF subset_𝒬𝒫Suc subset_𝒫𝒬k])
lemma subset_𝒬: "i ≤ j ⟹ 𝒬 i ⊆ 𝒬 j"
  by (rule subset_fSuc[where u=i and v=j and f = 𝒬, OF subset_𝒬Suc])
lemma empty_𝒳[simp]: "k > length Doc ⟹ 𝒳 k = {}"
  apply (simp add: 𝒳_def)
  apply (insert Lex_is_lexer)
  by (simp add: is_lexer_def)
lemma Sel_empty[simp]: "Sel {} {} = {}"
  apply (insert Sel_is_selector)
  by (auto simp add: is_selector_def)
lemma empty_𝒵[simp]: "k > length Doc ⟹ 𝒵 k u = {}"
  apply (induct u)
  by (simp_all add: 𝒴_def 𝒲_def)
lemma[simp]: "Append {} k = id" by (auto simp add: Append_def)
lemma[simp]: "k > length Doc ⟹ 𝒫 k v = 𝒫 k 0"
  by (induct v, simp_all add: 𝒴_def 𝒲_def)
lemma 𝒬SucEq: "k ≥ length Doc ⟹ 𝒬 (Suc k) = 𝒬 k"
  by (simp add: natUnion_def) 
lemma 𝒬_converges:
  assumes k: "k ≥ length Doc"
  shows "𝒬 k = 𝔓"
proof -
  { 
    fix n
    have "𝒬 (length Doc + n) = 𝔓"
    proof (induct n)
      show "𝒬 (length Doc + 0) = 𝔓" by (simp add: 𝔓_def)
    next
      fix n
      assume hyp: "𝒬 (length Doc + n) = 𝔓"
      have "𝒬 (Suc (length Doc + n)) = 𝔓"
        by (rule trans[OF 𝒬SucEq hyp], auto)
      then show "𝒬 (length Doc + Suc n) = 𝔓"
        by auto
    qed
  }
  note helper = this
  from k have "∃ n. k = length Doc + n" by presburger
  then obtain "n" where n: "k = length Doc + n" by blast
  then show ?thesis
    apply (simp only: n)
    by (rule helper)
qed
lemma 𝔓_covers_𝒬: "𝒬 k ⊆ 𝔓"
proof (case_tac "k ≥ length Doc")
  assume "k ≥ length Doc"
  then have 𝒬: "𝒬 k = 𝔓" by (rule 𝒬_converges)
  then show "𝒬 k ⊆ 𝔓" by (simp only: 𝒬)
next
  assume "¬ length Doc ≤ k"
  then have "k < length Doc" by auto
  then show ?thesis
    apply (simp only: 𝔓_def)
    apply (rule subset_𝒬)
    by auto
qed
lemma Sel_upper_bound: "A ⊆ B ⟹ Sel A B ⊆ B"
  by (metis Sel_is_selector is_selector_def)
lemma Sel_lower_bound: "A ⊆ B ⟹ A ⊆ Sel A B"
  by (metis Sel_is_selector is_selector_def)  
lemma 𝔓_covers_𝒫: "𝒫 k u ⊆ 𝔓"
  by (rule subset_trans[OF subset_𝒫𝒬k 𝔓_covers_𝒬])
lemma 𝒲_montone: "P ⊆ Q ⟹ 𝒲 P k ⊆ 𝒲 Q k"
  by (auto simp add: 𝒲_def)
lemma Sel_precondition: 
  "𝒵 k u ⊆ 𝒲 (𝒫 k u) k"
proof (induct u)
  case 0 thus ?case by simp
next
  case (Suc u)
  have 1: "𝒴 (𝒵 k u) (𝒫 k u) k ⊆ 𝒲 (𝒫 k u) k"
    apply (simp add: 𝒴_def)
    apply (rule_tac Sel_upper_bound)
    using Suc by simp
  have 2: "𝒲 (𝒫 k u) k ⊆ 𝒲 (𝒫 k (Suc u)) k"
    by (metis 𝒲_montone subset_𝒫Suc)    
  show ?case
    apply (rule_tac subset_trans[where B="𝒲 (𝒫 k u) k"])
    apply (simp add: 1)
    apply (simp only: 2)
    done
qed    
lemma 𝒲_bounded_by_𝒳: "𝒲 P k ⊆ 𝒳 k"
  by (metis (no_types, lifting) 𝒲_def mem_Collect_eq subsetI)
lemma 𝒵_subset_𝒳: "𝒵 k n ⊆ 𝒳 k"
  by (metis Sel_precondition 𝒲_bounded_by_𝒳 rev_subsetD subsetI)
lemma 𝒵_subset_Suc: "𝒵 k n ⊆ 𝒵 k (Suc n)"
apply (induct n)
apply simp
by (metis Sel_lower_bound Sel_precondition 𝒴_def 𝒵.simps(2))
lemma 𝒴_upper_bound: "𝒴 (𝒵 k u) (𝒫 k u) k ⊆ 𝒲  (𝒫 k u) k"
  apply (simp add: 𝒴_def)
  by (metis Sel_precondition Sel_upper_bound)
lemma 𝔓_induct[consumes 1, case_names Base Induct]:
  assumes p: "p ∈ 𝔓"
  assumes base: "P []"
  assumes induct: "⋀ p k u. (⋀ q. q ∈ 𝒫 k u ⟹ P q) ⟹ p ∈ 𝒫 k (Suc u) ⟹ P p"
  shows "P p"
proof -
  {
    fix p :: "tokens"
    fix k :: nat
    fix u :: nat
    have "p ∈ 𝒫 k u ⟹ P p"
    proof (induct k arbitrary: p u)
      case 0
        have "p ∈ 𝒫 0 u ⟹ P p"
        proof (induct u arbitrary: p)
          case 0 thus ?case using base by simp
        next
          case (Suc u) show ?case
            apply (rule induct[OF _ Suc(2)])
            apply (rule Suc(1))
            by simp
        qed
        with 0 show ?case by simp
    next
      case (Suc k)
        have "p ∈ 𝒫 (Suc k) u ⟹ P p"
        proof (induct u arbitrary: p)
          case 0 thus ?case
            apply simp
            apply (induct rule: natUnion_decompose) 
            using Suc by simp
        next
          case (Suc u) show ?case
            apply (rule induct[OF _ Suc(2)])
            apply (rule Suc(1))
            by simp
        qed
        with Suc show ?case by simp
    qed 
  }
  note all = this
  from p show ?thesis
    apply (simp add: 𝔓_def)
    apply (induct rule: natUnion_decompose)
    using all by simp
qed 
    
lemma Append_mono: "U ⊆ V ⟹ P ⊆ Q ⟹ Append U k P ⊆ Append V k Q"
  by (auto simp add: Append_def)
lemma pointwise_Append: "pointwise (Append T k)"
by (auto simp add: pointwise_def Append_def)
lemma regular_Append: "regular (Append T k)"
proof -
  have "pointwise (Append T k)" using pointwise_Append by blast
  then have "pointbased (Append T k)" using pointwise_implies_pointbased by blast
  then have "continuous (Append T k)" using pointbased_implies_continuous by blast 
  moreover have "setmonotone (Append T k)" by (simp add: setmonotone_def Append_def)
  ultimately show ?thesis using regular_def by blast
qed
end
end