Theory PAC_Specification

(*
  File:         PAC_Specification.thy
  Author:       Mathias Fleury, Daniela Kaufmann, JKU
  Maintainer:   Mathias Fleury, JKU
*)
theory PAC_Specification
  imports PAC_More_Poly
begin


section ‹Specification of the PAC checker›

subsection ‹Ideals›

type_synonym int_poly = int mpoly
definition polynomial_bool :: int_poly set where
  polynomial_bool = (λc. Var c ^ 2 - Var c) ` UNIV

definition pac_ideal where
  pac_ideal A  ideal (A  polynomial_bool)

lemma X2_X_in_pac_ideal:
  Var c ^ 2 - Var c  pac_ideal A
  unfolding polynomial_bool_def pac_ideal_def
  by (auto intro: ideal.span_base)

lemma pac_idealI1[intro]:
  p  A  p  pac_ideal A
  unfolding pac_ideal_def
  by (auto intro: ideal.span_base)

lemma pac_idealI2[intro]:
  p  ideal A  p  pac_ideal A
  using ideal.span_subspace_induct pac_ideal_def by blast

lemma pac_idealI3[intro]:
  p  ideal A  p*q  pac_ideal A
  by (metis ideal.span_scale mult.commute pac_idealI2)

lemma pac_ideal_Xsq2_iff:
  Var c ^ 2  pac_ideal A  Var c  pac_ideal A
  unfolding pac_ideal_def
  apply (subst (2) ideal.span_add_eq[symmetric, OF X2_X_in_pac_ideal[of c, unfolded pac_ideal_def]])
  apply auto
  done

lemma diff_in_polynomial_bool_pac_idealI:
   assumes a1: "p  pac_ideal A"
   assumes a2: "p - p'  More_Modules.ideal polynomial_bool"
   shows p'  pac_ideal A
 proof -
   have "insert p polynomial_bool  pac_ideal A"
     using a1 unfolding pac_ideal_def by (meson ideal.span_superset insert_subset le_sup_iff)
   then show ?thesis
     using a2 unfolding pac_ideal_def by (metis (no_types) ideal.eq_span_insert_eq ideal.span_subset_spanI ideal.span_superset insert_subset subsetD)
qed

lemma diff_in_polynomial_bool_pac_idealI2:
   assumes a1: "p  A"
   assumes a2: "p - p'  More_Modules.ideal polynomial_bool"
   shows p'  pac_ideal A
   using diff_in_polynomial_bool_pac_idealI[OF _ assms(2), of A] assms(1)
   by (auto simp: ideal.span_base)

lemma pac_ideal_alt_def:
  pac_ideal A = ideal (A  ideal polynomial_bool)
  unfolding pac_ideal_def
  by (meson ideal.span_eq ideal.span_mono ideal.span_superset le_sup_iff subset_trans sup_ge2)

text ‹

  The equality on ideals is restricted to polynomials whose variable
  appear in the set of ideals. The function restrict sets:

›
definition restricted_ideal_to where
  restricted_ideal_to B A = {p  A. vars p   B}

abbreviation restricted_ideal_toI where
  restricted_ideal_toI B A  restricted_ideal_to B (pac_ideal (set_mset A))

abbreviation restricted_ideal_toV where
  restricted_ideal_toV B  restricted_ideal_to ((vars ` set_mset B))

abbreviation restricted_ideal_toVI where
  restricted_ideal_toVI B A  restricted_ideal_to ((vars ` set_mset B)) (pac_ideal (set_mset A))


lemma restricted_idealI:
  p  pac_ideal (set_mset A)  vars p  C  p  restricted_ideal_toI C A
  unfolding restricted_ideal_to_def
  by auto

lemma pac_ideal_insert_already_in:
  pq  pac_ideal (set_mset A)  pac_ideal (insert pq (set_mset A)) = pac_ideal (set_mset A)
  by (auto simp: pac_ideal_alt_def ideal.span_insert_idI)

lemma pac_ideal_add:
  p ∈# A  q ∈# A  p + q  pac_ideal (set_mset A)
  by (simp add: ideal.span_add ideal.span_base pac_ideal_def)
lemma pac_ideal_mult:
  p ∈# A  p * q  pac_ideal (set_mset A)
  by (simp add: ideal.span_base pac_idealI3)

lemma pac_ideal_mono:
  A  B  pac_ideal A  pac_ideal B
  using ideal.span_mono[of A  _ B  _]
  by (auto simp: pac_ideal_def intro: ideal.span_mono)


subsection ‹PAC Format›

text ‹The PAC format contains three kind of steps:
   ‹add› that adds up two polynomials that are known.
   ‹mult› that multiply a known polynomial with another one.
   ‹del› that removes a polynomial that cannot be reused anymore.

To model the simplification that happens, we add the termp - p'  polynomial_bool
stating that termp and  termp' are equivalent.
›

type_synonym pac_st = (nat set × int_poly multiset)

inductive PAC_Format :: pac_st  pac_st  bool where
add:
  PAC_Format (𝒱, A) (𝒱, add_mset p' A)
if
   p ∈# A q ∈# A
   p+q - p'  ideal polynomial_bool
   vars p'  𝒱 |
mult:
  PAC_Format (𝒱, A) (𝒱, add_mset p' A)
if
   p ∈# A
   p*q - p'  ideal polynomial_bool
   vars p'  𝒱
   vars q  𝒱 |
del:
   p ∈# A  PAC_Format (𝒱, A) (𝒱, A - {#p#}) |
extend_pos:
  PAC_Format (𝒱, A) (𝒱  {x'  vars (-Var x + p'). x'  𝒱}, add_mset (-Var x + p') A)
  if
    (p')2 - p'  ideal polynomial_bool
    vars p'  𝒱
    x  𝒱

text  ‹
  In the PAC format above, we have a technical condition on the
  normalisation: termvars p'  vars (p + q) is here to ensure that
  we don't normalise term0 :: int mpoly to  termVar x^2 - Var x :: int mpoly
  for a new variable termx :: nat. This is completely obvious for the normalisation
  process we have in mind when we write the specification, but we must add it
  explicitly because we are too general.
›

lemmas  PAC_Format_induct_split =
   PAC_Format.induct[split_format(complete), of V A V' A' for V A V' A']

lemma PAC_Format_induct[consumes 1, case_names add mult del ext]:
  assumes
    PAC_Format (𝒱, A) (𝒱', A') and
    cases:
      p q p'  A 𝒱. p ∈# A  q ∈# A  p+q - p'  ideal polynomial_bool  vars p'  𝒱  P 𝒱 A 𝒱 (add_mset p' A)
      p q p' A 𝒱. p ∈# A  p*q - p'  ideal polynomial_bool  vars p'  𝒱  vars q  𝒱 
        P 𝒱 A 𝒱 (add_mset p' A)
      p A 𝒱. p ∈# A  P 𝒱 A 𝒱 (A - {#p#})
      p' x r.
        (p')^2 - (p')  ideal polynomial_bool  vars p'  𝒱 
        x  𝒱  P 𝒱 A (𝒱  {x'  vars (p' - Var x). x'  𝒱}) (add_mset (p' -Var x) A)
  shows
     P 𝒱 A 𝒱' A'
  using assms(1) apply -
  by (induct V𝒱 AA 𝒱' A' rule: PAC_Format_induct_split)
   (auto intro: assms(1) cases)


text ‹

The theorem below (based on the proof ideal by Manuel Kauers) is the
correctness theorem of extensions. Remark that the assumption termvars
q  𝒱 is only used to show that termx'  vars q.

›
lemma extensions_are_safe:
  assumes x'  vars p and
    x': x'  𝒱 and
     (vars ` set_mset A)  𝒱 and
    p_x_coeff: coeff p (monomial (Suc 0) x') = 1 and
    vars_q: vars q  𝒱 and
    q: q  More_Modules.ideal (insert p (set_mset A  polynomial_bool)) and
    leading: x'  vars (p - Var x') and
    diff: (Var x' - p)2 - (Var x' - p)  More_Modules.ideal polynomial_bool
  shows
    q  More_Modules.ideal (set_mset A  polynomial_bool)
proof -
  define p' where p'  p - Var x'
  let ?v = Var x' :: int mpoly
  have p_p': p = ?v + p'
    by (auto simp: p'_def)
  define q' where q'  Var x' - p
  have q_q': p = ?v - q'
    by (auto simp: q'_def)
  have diff: q'^2 - q'  More_Modules.ideal polynomial_bool
    using diff unfolding q_q' by auto

  have [simp]: vars ((Var c)2 - Var c :: int mpoly) = {c} for c
    apply (auto simp: vars_def Var_def Var0_def mpoly.MPoly_inverse keys_def lookup_minus_fun
      lookup_times_monomial_right single.rep_eq split: if_splits)
    apply (auto simp: vars_def Var_def Var0_def mpoly.MPoly_inverse keys_def lookup_minus_fun
      lookup_times_monomial_right single.rep_eq when_def ac_simps adds_def lookup_plus_fun
      power2_eq_square times_mpoly.rep_eq minus_mpoly.rep_eq split: if_splits)
    apply (rule_tac x = (2 :: nat 0 nat) * monomial (Suc 0) c in exI)
    apply (auto dest: monomial_0D simp: plus_eq_zero_2 lookup_plus_fun mult_2)
    by (meson Suc_neq_Zero monomial_0D plus_eq_zero_2)


  have eq: More_Modules.ideal (insert p (set_mset A  polynomial_bool)) =
      More_Modules.ideal (insert p (set_mset A  (λc. Var c ^ 2 - Var c) ` {c. c  x'}))
      (is ?A = ?B is _ = More_Modules.ideal ?trimmed)
  proof -
     let ?C = insert p (set_mset A  (λc. Var c ^ 2 - Var c) ` {c. c  x'})
     let ?D = (λc. Var c ^ 2 - Var c) ` {c. c  x'}
     have diff: q'^2 - q'  More_Modules.ideal ?D (is ?q  _)
     proof -
       obtain r t where
         q: ?q = (at. r a * a) and
         fin_t: finite t and
         t: t  polynomial_bool
         using diff unfolding ideal.span_explicit
         by auto
       show ?thesis
       proof (cases ?v^2-?v  t)
         case True
         then show ?thesis
           using q fin_t t unfolding ideal.span_explicit
           by (auto intro!: exI[of _ t - {?v^2 -?v}] exI[of _ r]
             simp: polynomial_bool_def sum_diff1)
        next
          case False
          define t' where t' = t - {?v^2 - ?v}
          have t_t': t = insert (?v^2 - ?v) t' and
            notin: ?v^2 - ?v  t' and
            t'  (λc. Var c ^ 2 - Var c) ` {c. c  x'}
            using False t unfolding t'_def polynomial_bool_def by auto
          have mon: monom (monomial (Suc 0) x') 1 = Var x'
            by (auto simp: coeff_def minus_mpoly.rep_eq Var_def Var0_def monom_def
              times_mpoly.rep_eq lookup_minus lookup_times_monomial_right mpoly.MPoly_inverse)
          then have a. g h. r a = ?v * g + h  x'  vars h
            using polynomial_split_on_var[of r _ x']
            by metis
          then obtain g h where
            r: r a = ?v * g a + h a and
            x'_h: x'  vars (h a) for a
            using polynomial_split_on_var[of r a x']
            by metis
          have  ?q = ((at'. g a * a) + r (?v^2-?v) * (?v - 1)) * ?v + (at'. h a * a)
            using fin_t notin unfolding t_t' q r
            by (auto simp: field_simps comm_monoid_add_class.sum.distrib
              power2_eq_square ideal.scale_left_commute sum_distrib_left)
          moreover have x'  vars ?q
            by (metis (no_types, opaque_lifting) Groups.add_ac(2) Un_iff add_diff_cancel_left'
              diff_minus_eq_add in_mono leading q'_def semiring_normalization_rules(29)
              vars_in_right_only vars_mult)
          moreover {
            have x'  (mt' - {?v^2-?v}. vars (h m * m))
              using fin_t x'_h vars_mult[of h _] t  polynomial_bool
              by (auto simp: polynomial_bool_def t_t' elim!: vars_unE)
            then have x'  vars (at'. h a * a)
              using vars_setsum[of t' λa. h a * a] fin_t x'_h t notin
              by (auto simp: t_t')
          }
          ultimately have ?q = (at'. h a * a)
            unfolding mon[symmetric]
            by (rule polynomial_decomp_alien_var(2)[unfolded])
          then show ?thesis
            using t fin_t t'  (λc. Var c ^ 2 - Var c) ` {c. c  x'}
            unfolding ideal.span_explicit t_t'
            by auto
       qed
    qed
    have eq1: More_Modules.ideal (insert p (set_mset A  polynomial_bool)) =
      More_Modules.ideal (insert (?v^2 - ?v) ?C)
      (is More_Modules.ideal _ = More_Modules.ideal (insert _ ?C))
      by (rule arg_cong[of _ _ More_Modules.ideal])
       (auto simp: polynomial_bool_def)
    moreover have ?v^2 - ?v  More_Modules.ideal ?C
    proof -
      have ?v - q'  More_Modules.ideal ?C
        by (auto simp: q_q' ideal.span_base)
      from ideal.span_scale[OF this, of ?v + q' - 1] have (?v - q') * (?v + q' - 1)  More_Modules.ideal ?C
        by (auto simp: field_simps)
      moreover have q'^2 - q'  More_Modules.ideal ?C
        using diff by (smt (verit) Un_insert_right ideal.span_mono insert_subset subsetD sup_ge2)
      ultimately have (?v - q') * (?v + q' - 1) + (q'^2 - q')  More_Modules.ideal ?C
        by (rule ideal.span_add)
      moreover have ?v^2 - ?v = (?v - q') * (?v + q' - 1) + (q'^2 - q')
        by (auto simp: p'_def q_q' field_simps power2_eq_square)
      ultimately show ?thesis by simp
    qed
    ultimately show ?thesis
      using ideal.span_insert_idI by blast
  qed

  have n < m  n > 0  q. ?v^n = ?v + q * (?v^2 - ?v) for n m :: nat
  proof (induction m arbitrary: n)
    case 0
    then show ?case by auto
  next
    case (Suc m n) note IH = this(1-)
    consider
      n < m |
      m = n n > 1 |
      n = 1
      using IH
      by (cases n < m; cases n) auto
    then show ?case
    proof cases
      case 1
      then show ?thesis using IH by auto
    next
      case 2
      have eq: ?v^(n) = ((?v :: int mpoly) ^ (n-2)) * (?v^2-?v) + ?v^(n-1)
        using 2 by (auto simp: field_simps power_eq_if
          ideal.scale_right_diff_distrib)
      obtain q where
        q: ?v^(n-1) = ?v + q * (?v^2 - ?v)
        using IH(1)[of n-1] 2
        by auto
      show ?thesis
        using q unfolding eq
        by (auto intro!: exI[of _ Var x' ^ (n - 2) + q] simp: distrib_right)
    next
      case 3
      then show ?thesis
        by auto
    qed
  qed

  obtain r t where
    q: q = (at. r a * a) and
    fin_t: finite t and
    t: t  ?trimmed
    using q unfolding eq unfolding ideal.span_explicit
    by auto


  define t' where t'  t - {p}
  have t': t = (if p  t then insert p t' else t') and
    t''[simp]: p  t'
    unfolding t'_def by auto
  show ?thesis
  proof (cases r p = 0  p  t)
    case True
    have
      q: q = (at'. r a * a) and
     fin_t: finite t' and
      t: t'  set_mset A  polynomial_bool
      using q fin_t t True t''
      apply (subst (asm) t')
      apply (auto intro: sum.cong simp: sum.insert_remove t'_def)
      using q fin_t t True t''
      apply (auto intro: sum.cong simp: sum.insert_remove t'_def polynomial_bool_def)
      done
    then show ?thesis
      by (auto simp: ideal.span_explicit)
  next
    case False
    then have r p  0 and p  t
      by auto
    then have t: t = insert p t'
      by (auto simp: t'_def)

   have x'  vars (- p')
     using leading p'_def vars_in_right_only by fastforce
   have mon: monom (monomial (Suc 0) x') 1 = Var x'
     by (auto simp:coeff_def minus_mpoly.rep_eq Var_def Var0_def monom_def
       times_mpoly.rep_eq lookup_minus lookup_times_monomial_right mpoly.MPoly_inverse)
   then have a. g h. r a = (?v + p') * g + h  x'  vars h
     using polynomial_split_on_var2[of x' -p' r _]  x'  vars (- p')
     by (metis diff_minus_eq_add)
   then obtain g h where
     r: r a = p * g a + h a and
     x'_h: x'  vars (h a) for a
     using polynomial_split_on_var2[of x' p' r a] unfolding p_p'[symmetric]
     by metis


  have ISABLLE_come_on: a * (p * g a) = p * (a * g a) for a
    by auto
  have q1: q = p * (at'. g a * a) + (at'. h a * a) + p * r p
    (is _ = _ + ?NOx' + _)
    using fin_t t'' unfolding q t ISABLLE_come_on r
    apply (subst semiring_class.distrib_right)+
    apply (auto simp: comm_monoid_add_class.sum.distrib semigroup_mult_class.mult.assoc
      ISABLLE_come_on simp flip: semiring_0_class.sum_distrib_right
         semiring_0_class.sum_distrib_left)
    by (auto simp: field_simps)
  also have ... = ((at'. g a * a) + r p) * p + (at'. h a * a)
    by (auto simp: field_simps)
  finally have q_decomp: q = ((at'. g a * a) + r p) * p + (at'. h a * a)
    (is q = ?X * p + ?NOx').


   have [iff]: monomial (Suc 0) c = 0 - monomial (Suc 0) c = False for c
     by (metis One_nat_def diff_is_0_eq' le_eq_less_or_eq less_Suc_eq_le monomial_0_iff single_diff zero_neq_one)
  have x  t'  x'  vars x  False for x
    using  t  ?trimmed t assms(2,3)
    apply (auto simp: polynomial_bool_def dest!: multi_member_split)
    apply (frule set_rev_mp)
    apply assumption
    apply (auto dest!: multi_member_split)
    done
   then have x'  (mt'. vars (h m * m))
     using fin_t x'_h vars_mult[of h _]
     by (auto simp: t elim!: vars_unE)
   then have x'  vars ?NOx'
     using vars_setsum[of t' λa. h a * a] fin_t x'_h
     by (auto simp: t)

  moreover {
    have x'  vars p'
      using assms(7)
      unfolding p'_def
      by auto
    then have x'  vars (h p * p')
      using vars_mult[of h p p'] x'_h
      by auto
  }
  ultimately have
    x'  vars q
    x'  vars ?NOx'
    x'  vars p'
    using x' vars_q vars_add[of h p * p' at'. h a * a] x'_h
      leading p'_def
    by auto
  then have ?X = 0 and q_decomp: q = ?NOx'
    unfolding mon[symmetric] p_p'
    using polynomial_decomp_alien_var2[OF q_decomp[unfolded p_p' mon[symmetric]]]
    by auto

  then have r p = (at'. (- g a) * a)
    (is _ = ?CL)
    unfolding add.assoc add_eq_0_iff equation_minus_iff
    by (auto simp: sum_negf ac_simps)


  then have q2: q = (at'. a * (r a - p * g a))
    using fin_t unfolding q
    apply (auto simp: t r q
         comm_monoid_add_class.sum.distrib[symmetric]
         sum_distrib_left
         sum_distrib_right
         left_diff_distrib
        intro!: sum.cong)
    apply (auto simp: field_simps)
    done
  then show ?thesis
    using t fin_t t  ?trimmed unfolding ideal.span_explicit
    by (auto intro!: exI[of _ t'] exI[of _ λa. r a - p * g a]
      simp: field_simps polynomial_bool_def)
  qed
qed

lemma extensions_are_safe_uminus:
  assumes x'  vars p and
    x': x'  𝒱 and
     (vars ` set_mset A)  𝒱 and
    p_x_coeff: coeff p (monomial (Suc 0) x') = -1 and
    vars_q: vars q  𝒱 and
    q: q  More_Modules.ideal (insert p (set_mset A  polynomial_bool)) and
    leading: x'  vars (p + Var x') and
    diff: (Var x' + p)^2 - (Var x' + p)  More_Modules.ideal polynomial_bool
  shows
    q  More_Modules.ideal (set_mset A  polynomial_bool)
proof -
  have q  More_Modules.ideal (insert (- p) (set_mset A  polynomial_bool))
    by (metis ideal.span_breakdown_eq minus_mult_minus q)

  then show ?thesis
    using extensions_are_safe[of x' -p 𝒱 A q] assms
    using vars_in_right_only by force
qed

text ‹This is the correctness theorem of a PAC step: no polynomials are
added to the ideal.›

lemma vars_subst_in_left_only:
  x  vars p  x  vars (p - Var x) for p :: int mpoly
  by (metis One_nat_def Var.abs_eq Var0_def group_eq_aux monom.abs_eq mult_numeral_1 polynomial_decomp_alien_var(1) zero_neq_numeral)

lemma vars_subst_in_left_only_diff_iff:
  fixes p :: int mpoly
  assumes x  vars p
  shows vars (p - Var x) = insert x (vars p)
proof -
  have xa. x  vars p  xa  vars (p - Var x)  xa  vars p  xa = x
    by (metis (no_types, opaque_lifting) diff_0_right diff_minus_eq_add empty_iff in_vars_addE insert_iff
      keys_single minus_diff_eq monom_one mult.right_neutral one_neq_zero single_zero
      vars_monom_keys vars_mult_Var vars_uminus)
  moreover have xa. x  vars p  xa  vars p  xa  vars (p - Var x)
    by (metis add.inverse_inverse diff_minus_eq_add empty_iff insert_iff keys_single minus_diff_eq
      monom_one mult.right_neutral one_neq_zero single_zero vars_in_right_only vars_monom_keys
      vars_mult_Var vars_uminus)
  ultimately show ?thesis
    using assms
    by (auto simp: vars_subst_in_left_only)
qed

lemma vars_subst_in_left_only_iff:
  x  vars p  vars (p + Var x) = insert x (vars p) for p :: int mpoly
  using vars_subst_in_left_only_diff_iff[of x -p]
  by (metis diff_0 diff_diff_add vars_uminus)

lemma coeff_add_right_notin:
  x  vars p  MPoly_Type.coeff (Var x - p) (monomial (Suc 0) x) = 1
  apply (auto simp flip: coeff_minus simp: not_in_vars_coeff0)
  by (simp add: MPoly_Type.coeff_def Var.rep_eq Var0_def)

lemma coeff_add_left_notin:
  x  vars p  MPoly_Type.coeff (p - Var x) (monomial (Suc 0) x) = -1 for p :: int mpoly
  apply (auto simp flip: coeff_minus simp: not_in_vars_coeff0)
  by (simp add: MPoly_Type.coeff_def Var.rep_eq Var0_def)

lemma ideal_insert_polynomial_bool_swap: r - s  ideal polynomial_bool 
  More_Modules.ideal (insert r  (A  polynomial_bool)) = More_Modules.ideal (insert s (A  polynomial_bool))
  apply auto
  using ideal.eq_span_insert_eq ideal.span_mono sup_ge2 apply blast+
  done

lemma PAC_Format_subset_ideal:
  PAC_Format (𝒱, A) (𝒱', B)  (vars ` set_mset A)  𝒱 
     restricted_ideal_toI 𝒱 B  restricted_ideal_toI 𝒱 A  𝒱  𝒱'  (vars ` set_mset B)  𝒱'
  unfolding restricted_ideal_to_def
  apply (induction rule:PAC_Format_induct)
  subgoal for p q pq A 𝒱
    using vars_add
    by (force simp: ideal.span_add_eq ideal.span_base pac_ideal_insert_already_in[OF diff_in_polynomial_bool_pac_idealI[of p + q _ pq]]
        pac_ideal_add
      intro!: diff_in_polynomial_bool_pac_idealI[of p + q _ pq])
  subgoal for p q pq
    using vars_mult[of p q]
    by (force simp: ideal.span_add_eq ideal.span_base pac_ideal_mult
      pac_ideal_insert_already_in[OF diff_in_polynomial_bool_pac_idealI[of p*q _ pq]])
  subgoal for p A
    using pac_ideal_mono[of set_mset (A - {#p#}) set_mset A]
    by (auto dest: in_diffD)
  subgoal for p x' r'
    apply (subgoal_tac x'  vars p)
    using extensions_are_safe_uminus[of x' -Var x' + p 𝒱 A] unfolding pac_ideal_def
    apply (auto simp: vars_subst_in_left_only coeff_add_left_notin)
    done
  done


text ‹
  In general, if deletions are disallowed, then the stronger termB = pac_ideal A holds.
›
lemma restricted_ideal_to_restricted_ideal_toID:
  restricted_ideal_to 𝒱 (set_mset A)  restricted_ideal_toI 𝒱 A
   by (auto simp add: Collect_disj_eq pac_idealI1 restricted_ideal_to_def)


lemma rtranclp_PAC_Format_subset_ideal:
  rtranclp PAC_Format (𝒱, A) (𝒱', B)  (vars ` set_mset A)  𝒱 
     restricted_ideal_toI 𝒱 B  restricted_ideal_toI 𝒱 A  𝒱  𝒱'  (vars ` set_mset B)  𝒱'
  apply (induction rule:rtranclp_induct[of PAC_Format (_, _) (_, _), split_format(complete)])
  subgoal
    by (simp add: restricted_ideal_to_restricted_ideal_toID)
  subgoal
    by (drule PAC_Format_subset_ideal)
      (auto simp: restricted_ideal_to_def Collect_mono_iff)
  done


end