Theory Normal_Form
section ‹A Normal Form for Linear Temporal Logic›
theory Normal_Form imports
LTL_Master_Theorem.Master_Theorem
begin
subsection ‹LTL Equivalences›
text ‹Several valid laws of LTL relating strong and weak operators that are useful later.›
lemma ltln_strong_weak_2:
"w ⊨⇩n φ U⇩n ψ ⟷ w ⊨⇩n (φ and⇩n F⇩n ψ) W⇩n ψ" (is "?thesis1")
"w ⊨⇩n φ M⇩n ψ ⟷ w ⊨⇩n φ R⇩n (ψ and⇩n F⇩n φ)" (is "?thesis2")
proof -
have "∃j. suffix (i + j) w ⊨⇩n ψ"
if "suffix j w ⊨⇩n ψ" and "∀j≤i. ¬ suffix j w ⊨⇩n ψ" for i j
proof
from that have "j > i"
by (cases "j > i") auto
thus "suffix (i + (j - i)) w ⊨⇩n ψ"
using that by auto
qed
thus ?thesis1
unfolding ltln_strong_weak by auto
next
have "∃j. suffix (i + j) w ⊨⇩n φ"
if "suffix j w ⊨⇩n φ" and "∀j<i. ¬ suffix j w ⊨⇩n φ" for i j
proof
from that have "j ≥ i"
by (cases "j ≥ i") auto
thus "suffix (i + (j - i)) w ⊨⇩n φ"
using that by auto
qed
thus ?thesis2
unfolding ltln_strong_weak by auto
qed
lemma ltln_weak_strong_2:
"w ⊨⇩n φ W⇩n ψ ⟷ w ⊨⇩n φ U⇩n (ψ or⇩n G⇩n φ)" (is "?thesis1")
"w ⊨⇩n φ R⇩n ψ ⟷ w ⊨⇩n (φ or⇩n G⇩n ψ) M⇩n ψ" (is "?thesis2")
proof -
have "suffix j w ⊨⇩n φ"
if "⋀j. j < i ⟹ suffix j w ⊨⇩n φ" and "⋀j. suffix (i + j) w ⊨⇩n φ" for i j
using that(1)[of j] that(2)[of "j - i"] by (cases "j < i") simp_all
thus ?thesis1
unfolding ltln_weak_strong unfolding semantics_ltln.simps suffix_suffix by blast
next
have "suffix j w ⊨⇩n ψ"
if "⋀j. j ≤ i ⟹ suffix j w ⊨⇩n ψ" and "⋀j. suffix (i + j) w ⊨⇩n ψ" for i j
using that(1)[of j] that(2)[of "j - i"] by (cases "j ≤ i") simp_all
thus ?thesis2
unfolding ltln_weak_strong unfolding semantics_ltln.simps suffix_suffix by blast
qed
subsection ‹$\evalnu{\psi}{M}$, $\evalmu{\psi}{N}$, $\flatten{\psi}{M}$, and $\flattentwo{\psi}{N}$›
text ‹The following four functions use "promise sets", named $M$ or $N$, to rewrite arbitrary
formulas into formulas from the class $\Sigma_1$-, $\Sigma_2$-, $\Pi_1$-, and $\Pi_2$,
respectively. In general the obtained formulas are not equivalent, but under some conditions
(as outlined below) they are.›
no_notation FG_advice ("_[_]⇩μ" [90,60] 89)
no_notation GF_advice ("_[_]⇩ν" [90,60] 89)
notation FG_advice ("_[_]⇩Σ⇩1" [90,60] 89)
notation GF_advice ("_[_]⇩Π⇩1" [90,60] 89)
fun flatten_sigma_2:: "'a ltln ⇒ 'a ltln set ⇒ 'a ltln" ("_[_]⇩Σ⇩2")
where
"(φ U⇩n ψ)[M]⇩Σ⇩2 = (φ[M]⇩Σ⇩2) U⇩n (ψ[M]⇩Σ⇩2)"
| "(φ W⇩n ψ)[M]⇩Σ⇩2 = (φ[M]⇩Σ⇩2) U⇩n ((ψ[M]⇩Σ⇩2) or⇩n (G⇩n φ[M]⇩Π⇩1))"
| "(φ M⇩n ψ)[M]⇩Σ⇩2 = (φ[M]⇩Σ⇩2) M⇩n (ψ[M]⇩Σ⇩2)"
| "(φ R⇩n ψ)[M]⇩Σ⇩2 = ((φ[M]⇩Σ⇩2) or⇩n (G⇩n ψ[M]⇩Π⇩1)) M⇩n (ψ[M]⇩Σ⇩2)"
| "(φ and⇩n ψ)[M]⇩Σ⇩2 = (φ[M]⇩Σ⇩2) and⇩n (ψ[M]⇩Σ⇩2)"
| "(φ or⇩n ψ)[M]⇩Σ⇩2 = (φ[M]⇩Σ⇩2) or⇩n (ψ[M]⇩Σ⇩2)"
| "(X⇩n φ)[M]⇩Σ⇩2 = X⇩n (φ[M]⇩Σ⇩2)"
| "φ[M]⇩Σ⇩2 = φ"
fun flatten_pi_2 :: "'a ltln ⇒ 'a ltln set ⇒ 'a ltln" ("_[_]⇩Π⇩2")
where
"(φ W⇩n ψ)[N]⇩Π⇩2 = (φ[N]⇩Π⇩2) W⇩n (ψ[N]⇩Π⇩2)"
| "(φ U⇩n ψ)[N]⇩Π⇩2 = (φ[N]⇩Π⇩2 and⇩n (F⇩n ψ[N]⇩Σ⇩1)) W⇩n (ψ[N]⇩Π⇩2)"
| "(φ R⇩n ψ)[N]⇩Π⇩2 = (φ[N]⇩Π⇩2) R⇩n (ψ[N]⇩Π⇩2)"
| "(φ M⇩n ψ)[N]⇩Π⇩2 = (φ[N]⇩Π⇩2) R⇩n ((ψ[N]⇩Π⇩2) and⇩n (F⇩n φ[N]⇩Σ⇩1))"
| "(φ and⇩n ψ)[N]⇩Π⇩2 = (φ[N]⇩Π⇩2) and⇩n (ψ[N]⇩Π⇩2)"
| "(φ or⇩n ψ)[N]⇩Π⇩2 = (φ[N]⇩Π⇩2) or⇩n (ψ[N]⇩Π⇩2)"
| "(X⇩n φ)[N]⇩Π⇩2 = X⇩n (φ[N]⇩Π⇩2)"
| "φ[N]⇩Π⇩2 = φ"
lemma GF_advice_restriction:
"φ[𝒢ℱ (φ W⇩n ψ) w]⇩Π⇩1 = φ[𝒢ℱ φ w]⇩Π⇩1"
"ψ[𝒢ℱ (φ R⇩n ψ) w]⇩Π⇩1 = ψ[𝒢ℱ ψ w]⇩Π⇩1"
by (metis (no_types, lifting) 𝒢ℱ_semantics' inf_commute inf_left_commute inf_sup_absorb subformulas⇩μ.simps(6) GF_advice_inter_subformulas)
(metis (no_types, lifting) GF_advice_inter 𝒢ℱ.simps(5) 𝒢ℱ_semantics' 𝒢ℱ_subformulas⇩μ inf.commute sup.boundedE)
lemma FG_advice_restriction:
"ψ[ℱ𝒢 (φ U⇩n ψ) w]⇩Σ⇩1 = ψ[ℱ𝒢 ψ w]⇩Σ⇩1"
"φ[ℱ𝒢 (φ M⇩n ψ) w]⇩Σ⇩1 = φ[ℱ𝒢 φ w]⇩Σ⇩1"
by (metis (no_types, lifting) FG_advice_inter ℱ𝒢.simps(4) ℱ𝒢_semantics' ℱ𝒢_subformulas⇩ν inf.commute sup.boundedE)
(metis (no_types, lifting) FG_advice_inter ℱ𝒢.simps(7) ℱ𝒢_semantics' ℱ𝒢_subformulas⇩ν inf.right_idem inf_commute sup.cobounded1)
lemma flatten_sigma_2_intersection:
"M ∩ subformulas⇩μ φ ⊆ S ⟹ φ[M ∩ S]⇩Σ⇩2 = φ[M]⇩Σ⇩2"
by (induction φ) (simp; blast intro: GF_advice_inter)+
lemma flatten_sigma_2_intersection_eq:
"M ∩ subformulas⇩μ φ = M' ⟹ φ[M']⇩Σ⇩2 = φ[M]⇩Σ⇩2"
using flatten_sigma_2_intersection by auto
lemma flatten_sigma_2_monotone:
"w ⊨⇩n φ[M]⇩Σ⇩2 ⟹ M ⊆ M' ⟹ w ⊨⇩n φ[M']⇩Σ⇩2"
by (induction φ arbitrary: w)
(simp; blast dest: GF_advice_monotone)+
lemma flatten_pi_2_intersection:
"N ∩ subformulas⇩ν φ ⊆ S ⟹ φ[N ∩ S]⇩Π⇩2 = φ[N]⇩Π⇩2"
by (induction φ) (simp; blast intro: FG_advice_inter)+
lemma flatten_pi_2_intersection_eq:
"N ∩ subformulas⇩ν φ = N' ⟹ φ[N']⇩Π⇩2 = φ[N]⇩Π⇩2"
using flatten_pi_2_intersection by auto
lemma flatten_pi_2_monotone:
"w ⊨⇩n φ[N]⇩Π⇩2 ⟹ N ⊆ N' ⟹ w ⊨⇩n φ[N']⇩Π⇩2"
by (induction φ arbitrary: w)
(simp; blast dest: FG_advice_monotone)+
lemma ltln_weak_strong_stable_words_1:
"w ⊨⇩n (φ W⇩n ψ) ⟷ w ⊨⇩n φ U⇩n (ψ or⇩n (G⇩n φ[𝒢ℱ φ w]⇩Π⇩1))" (is "?lhs ⟷ ?rhs")
proof
assume ?lhs
moreover
{
assume assm: "w ⊨⇩n G⇩n φ"
moreover
obtain i where "⋀j. ℱ φ (suffix i w) ⊆ 𝒢ℱ φ w"
by (metis MOST_nat_le 𝒢ℱ_suffix μ_stable_def order_refl suffix_μ_stable)
hence "⋀j. ℱ φ (suffix i (suffix j w)) ⊆ 𝒢ℱ φ w"
by (metis ℱ_suffix 𝒢ℱ_ℱ_subset 𝒢ℱ_suffix semiring_normalization_rules(24) subset_Un_eq suffix_suffix sup.orderE)
ultimately
have "suffix i w ⊨⇩n G⇩n (φ[𝒢ℱ φ w]⇩Π⇩1)"
using GF_advice_a1[OF ‹⋀j. ℱ φ (suffix i (suffix j w)) ⊆ 𝒢ℱ φ w›]
by (simp add: add.commute)
hence "?rhs"
using assm by auto
}
moreover
have "w ⊨⇩n φ U⇩n ψ ⟹ ?rhs"
by auto
ultimately
show ?rhs
using ltln_weak_to_strong(1) by blast
next
assume ?rhs
thus ?lhs
unfolding ltln_weak_strong_2 unfolding semantics_ltln.simps
by (metis 𝒢ℱ_suffix order_refl GF_advice_a2)
qed
lemma ltln_weak_strong_stable_words_2:
"w ⊨⇩n (φ R⇩n ψ) ⟷ w ⊨⇩n (φ or⇩n (G⇩n ψ[𝒢ℱ ψ w]⇩Π⇩1)) M⇩n ψ" (is "?lhs ⟷ ?rhs")
proof
assume ?lhs
moreover
{
assume assm: "w ⊨⇩n G⇩n ψ"
moreover
obtain i where "⋀j. ℱ ψ (suffix i w) ⊆ 𝒢ℱ ψ w"
by (metis MOST_nat_le 𝒢ℱ_suffix μ_stable_def order_refl suffix_μ_stable)
hence "⋀j. ℱ ψ (suffix i (suffix j w)) ⊆ 𝒢ℱ ψ w"
by (metis ℱ_suffix 𝒢ℱ_ℱ_subset 𝒢ℱ_suffix semiring_normalization_rules(24) subset_Un_eq suffix_suffix sup.orderE)
ultimately
have "suffix i w ⊨⇩n G⇩n (ψ[𝒢ℱ ψ w]⇩Π⇩1)"
using GF_advice_a1[OF ‹⋀j. ℱ ψ (suffix i (suffix j w)) ⊆ 𝒢ℱ ψ w›]
by (simp add: add.commute)
hence "?rhs"
using assm by auto
}
moreover
have "w ⊨⇩n φ M⇩n ψ ⟹ ?rhs"
by auto
ultimately
show ?rhs
using ltln_weak_to_strong by blast
next
assume ?rhs
thus ?lhs
unfolding ltln_weak_strong_2 unfolding semantics_ltln.simps
by (metis GF_advice_a2 𝒢ℱ_suffix order_refl)
qed
lemma ltln_weak_strong_stable_words:
"w ⊨⇩n (φ W⇩n ψ) ⟷ w ⊨⇩n φ U⇩n (ψ or⇩n (G⇩n φ[𝒢ℱ (φ W⇩n ψ) w]⇩Π⇩1))"
"w ⊨⇩n (φ R⇩n ψ) ⟷ w ⊨⇩n (φ or⇩n (G⇩n ψ[𝒢ℱ (φ R⇩n ψ) w]⇩Π⇩1)) M⇩n ψ"
unfolding ltln_weak_strong_stable_words_1 ltln_weak_strong_stable_words_2 GF_advice_restriction by simp+
lemma flatten_sigma_2_IH_lifting:
assumes "ψ ∈ subfrmlsn φ"
assumes "suffix i w ⊨⇩n ψ[𝒢ℱ ψ (suffix i w)]⇩Σ⇩2 = suffix i w ⊨⇩n ψ"
shows "suffix i w ⊨⇩n ψ[𝒢ℱ φ w]⇩Σ⇩2 = suffix i w ⊨⇩n ψ"
by (metis (no_types, lifting) inf.absorb_iff2 inf_assoc inf_commute assms(2) 𝒢ℱ_suffix flatten_sigma_2_intersection_eq[of "𝒢ℱ φ w" ψ "𝒢ℱ ψ w"] 𝒢ℱ_semantics' subformulas⇩μ_subset[OF assms(1)])
lemma flatten_sigma_2_correct:
"w ⊨⇩n φ[𝒢ℱ φ w]⇩Σ⇩2 ⟷ w ⊨⇩n φ"
proof (induction φ arbitrary: w)
case (And_ltln φ1 φ2)
then show ?case
using flatten_sigma_2_IH_lifting[of _ "φ1 and⇩n φ2" 0] by simp
next
case (Or_ltln φ1 φ2)
then show ?case
using flatten_sigma_2_IH_lifting[of _ "φ1 or⇩n φ2" 0] by simp
next
case (Next_ltln φ)
then show ?case
using flatten_sigma_2_IH_lifting[of _ "X⇩n φ" 1] by fastforce
next
case (Until_ltln φ1 φ2)
then show ?case
using flatten_sigma_2_IH_lifting[of _ "φ1 U⇩n φ2"] by fastforce
next
case (Release_ltln φ1 φ2)
then show ?case
unfolding ltln_weak_strong_stable_words
using flatten_sigma_2_IH_lifting[of _ "φ1 R⇩n φ2"] by fastforce
next
case (WeakUntil_ltln φ1 φ2)
then show ?case
unfolding ltln_weak_strong_stable_words
using flatten_sigma_2_IH_lifting[of _ "φ1 W⇩n φ2"] by fastforce
next
case (StrongRelease_ltln φ1 φ2)
then show ?case
using flatten_sigma_2_IH_lifting[of _ "φ1 M⇩n φ2"] by fastforce
qed auto
lemma ltln_strong_weak_stable_words_1:
"w ⊨⇩n φ U⇩n ψ ⟷ w ⊨⇩n (φ and⇩n (F⇩n ψ[ℱ𝒢 ψ w]⇩Σ⇩1)) W⇩n ψ" (is "?lhs ⟷ ?rhs")
proof
assume ?rhs
moreover
obtain i where "ν_stable ψ (suffix i w)"
by (metis MOST_nat less_Suc_eq suffix_ν_stable)
hence "∀ψ ∈ ℱ𝒢 ψ w. suffix i w ⊨⇩n G⇩n ψ"
using ℱ𝒢_suffix 𝒢_elim ν_stable_def by blast
{
assume assm: "w ⊨⇩n G⇩n (φ and⇩n (F⇩n ψ[ℱ𝒢 ψ w]⇩Σ⇩1))"
hence "suffix i w ⊨⇩n (F⇩n ψ)[ℱ𝒢 ψ w]⇩Σ⇩1"
by simp
hence "suffix i w ⊨⇩n F⇩n ψ"
by (blast dest: FG_advice_b2_helper[OF ‹∀ψ ∈ ℱ𝒢 ψ w. suffix i w ⊨⇩n G⇩n ψ›])
hence "w ⊨⇩n φ U⇩n ψ"
using assm by auto
}
ultimately
show ?lhs
by (meson ltln_weak_to_strong(1) semantics_ltln.simps(5) until_and_left_distrib)
next
assume ?lhs
moreover
have "⋀i. suffix i w ⊨⇩n ψ ⟹ suffix i w ⊨⇩n ψ[ℱ𝒢 ψ w]⇩Σ⇩1"
using ℱ𝒢_suffix by (blast intro: FG_advice_b1)
ultimately
show "?rhs"
unfolding ltln_strong_weak_2 by fastforce
qed
lemma ltln_strong_weak_stable_words_2:
"w ⊨⇩n φ M⇩n ψ ⟷ w ⊨⇩n φ R⇩n (ψ and⇩n (F⇩n φ[ℱ𝒢 φ w]⇩Σ⇩1))" (is "?lhs ⟷ ?rhs")
proof
assume ?rhs
moreover
obtain i where "ν_stable φ (suffix i w)"
by (metis MOST_nat less_Suc_eq suffix_ν_stable)
hence "∀ψ ∈ ℱ𝒢 φ w. suffix i w ⊨⇩n G⇩n ψ"
using ℱ𝒢_suffix 𝒢_elim ν_stable_def by blast
{
assume assm: "w ⊨⇩n G⇩n (ψ and⇩n (F⇩n φ[ℱ𝒢 φ w]⇩Σ⇩1))"
hence "suffix i w ⊨⇩n (F⇩n φ)[ℱ𝒢 φ w]⇩Σ⇩1"
by simp
hence "suffix i w ⊨⇩n F⇩n φ"
by (blast dest: FG_advice_b2_helper[OF ‹∀ψ ∈ ℱ𝒢 φ w. suffix i w ⊨⇩n G⇩n ψ›])
hence "w ⊨⇩n φ M⇩n ψ"
using assm by auto
}
ultimately
show ?lhs
using ltln_weak_to_strong(3) semantics_ltln.simps(5) strong_release_and_right_distrib by blast
next
assume ?lhs
moreover
have "⋀i. suffix i w ⊨⇩n φ ⟹ suffix i w ⊨⇩n φ[ℱ𝒢 φ w]⇩Σ⇩1"
using ℱ𝒢_suffix by (blast intro: FG_advice_b1)
ultimately
show "?rhs"
unfolding ltln_strong_weak_2 by fastforce
qed
lemma ltln_strong_weak_stable_words:
"w ⊨⇩n φ U⇩n ψ ⟷ w ⊨⇩n (φ and⇩n (F⇩n ψ[ℱ𝒢 (φ U⇩n ψ) w]⇩Σ⇩1)) W⇩n ψ"
"w ⊨⇩n φ M⇩n ψ ⟷ w ⊨⇩n φ R⇩n (ψ and⇩n (F⇩n φ[ℱ𝒢 (φ M⇩n ψ) w]⇩Σ⇩1))"
unfolding ltln_strong_weak_stable_words_1 ltln_strong_weak_stable_words_2 FG_advice_restriction by simp+
lemma flatten_pi_2_IH_lifting:
assumes "ψ ∈ subfrmlsn φ"
assumes "suffix i w ⊨⇩n ψ[ℱ𝒢 ψ (suffix i w)]⇩Π⇩2 = suffix i w ⊨⇩n ψ"
shows "suffix i w ⊨⇩n ψ[ℱ𝒢 φ w]⇩Π⇩2 = suffix i w ⊨⇩n ψ"
by (metis (no_types, lifting) inf.absorb_iff2 inf_assoc inf_commute assms(2) ℱ𝒢_suffix flatten_pi_2_intersection_eq[of "ℱ𝒢 φ w" ψ "ℱ𝒢 ψ w"] ℱ𝒢_semantics' subformulas⇩ν_subset[OF assms(1)])
lemma flatten_pi_2_correct:
"w ⊨⇩n φ[ℱ𝒢 φ w]⇩Π⇩2 ⟷ w ⊨⇩n φ"
proof (induction φ arbitrary: w)
case (And_ltln φ1 φ2)
then show ?case
using flatten_pi_2_IH_lifting[of _ "φ1 and⇩n φ2" 0] by simp
next
case (Or_ltln φ1 φ2)
then show ?case
using flatten_pi_2_IH_lifting[of _ "φ1 or⇩n φ2" 0] by simp
next
case (Next_ltln φ)
then show ?case
using flatten_pi_2_IH_lifting[of _ "X⇩n φ" 1] by fastforce
next
case (Until_ltln φ1 φ2)
then show ?case
unfolding ltln_strong_weak_stable_words
using flatten_pi_2_IH_lifting[of _ "φ1 U⇩n φ2"] by fastforce
next
case (Release_ltln φ1 φ2)
then show ?case
using flatten_pi_2_IH_lifting[of _ "φ1 R⇩n φ2"] by fastforce
next
case (WeakUntil_ltln φ1 φ2)
then show ?case
using flatten_pi_2_IH_lifting[of _ "φ1 W⇩n φ2"] by fastforce
next
case (StrongRelease_ltln φ1 φ2)
then show ?case
unfolding ltln_strong_weak_stable_words
using flatten_pi_2_IH_lifting[of _ "φ1 M⇩n φ2"] by fastforce
qed auto
subsection ‹Main Theorem›
text ‹Using the four previously defined functions we obtain our normal form.›
theorem normal_form_with_flatten_sigma_2:
"w ⊨⇩n φ ⟷
(∃M ⊆ subformulas⇩μ φ. ∃N ⊆ subformulas⇩ν φ.
w ⊨⇩n φ[M]⇩Σ⇩2 ∧ (∀ψ ∈ M. w ⊨⇩n G⇩n (F⇩n ψ[N]⇩Σ⇩1)) ∧ (∀ψ ∈ N. w ⊨⇩n F⇩n (G⇩n ψ[M]⇩Π⇩1)))" (is "?lhs ⟷ ?rhs")
proof
assume ?lhs
then have "w ⊨⇩n φ[𝒢ℱ φ w]⇩Σ⇩2"
using flatten_sigma_2_correct by blast
then show ?rhs
using 𝒢ℱ_subformulas⇩μ ℱ𝒢_subformulas⇩ν 𝒢ℱ_implies_GF ℱ𝒢_implies_FG by metis
next
assume ?rhs
then obtain M N where "w ⊨⇩n φ[M]⇩Σ⇩2" and "M ⊆ 𝒢ℱ φ w" and "N ⊆ ℱ𝒢 φ w"
using X_𝒢ℱ_Y_ℱ𝒢 by blast
then have "w ⊨⇩n φ[𝒢ℱ φ w]⇩Σ⇩2"
using flatten_sigma_2_monotone by blast
then show ?lhs
using flatten_sigma_2_correct by blast
qed
theorem normal_form_with_flatten_pi_2:
"w ⊨⇩n φ ⟷
(∃M ⊆ subformulas⇩μ φ. ∃N ⊆ subformulas⇩ν φ.
w ⊨⇩n φ[N]⇩Π⇩2 ∧ (∀ψ ∈ M. w ⊨⇩n G⇩n (F⇩n ψ[N]⇩Σ⇩1)) ∧ (∀ψ ∈ N. w ⊨⇩n F⇩n (G⇩n ψ[M]⇩Π⇩1)))" (is "?lhs ⟷ ?rhs")
proof
assume ?lhs
then have "w ⊨⇩n φ[ℱ𝒢 φ w]⇩Π⇩2"
using flatten_pi_2_correct by blast
then show ?rhs
using 𝒢ℱ_subformulas⇩μ ℱ𝒢_subformulas⇩ν 𝒢ℱ_implies_GF ℱ𝒢_implies_FG by metis
next
assume ?rhs
then obtain M N where "w ⊨⇩n φ[N]⇩Π⇩2" and "M ⊆ 𝒢ℱ φ w" and "N ⊆ ℱ𝒢 φ w"
using X_𝒢ℱ_Y_ℱ𝒢 by metis
then have "w ⊨⇩n φ[ℱ𝒢 φ w]⇩Π⇩2"
using flatten_pi_2_monotone by metis
then show ?lhs
using flatten_pi_2_correct by blast
qed
end