Theory Watched_Literals_Transition_System_Inprocessing
theory Watched_Literals_Transition_System_Inprocessing
imports Watched_Literals_Transition_System
begin
text ‹
The subsumption is very similar to the PCDCL case.
›
inductive cdcl_twl_subsumed :: ‹'v twl_st ⇒ 'v twl_st ⇒ bool› where
subsumed_II:
‹cdcl_twl_subsumed (M, N + {#C, C'#}, U, D, NE, UE, NS, US, N0, U0, {#}, Q)
(M, add_mset C N, U, D, NE, UE, add_mset (clause C') NS, US, N0, U0, {#}, Q)›
if ‹clause C ⊆# clause C'› |
subsumed_RR:
‹cdcl_twl_subsumed (M, N, U + {#C, C'#}, D, NE, UE, NS, US, N0, U0, {#}, Q)
(M, N, add_mset C U, D, NE, UE, NS, add_mset (clause C') US, N0, U0, {#}, Q)›
if ‹clause C ⊆# clause C'› |
subsumed_IR:
‹cdcl_twl_subsumed (M, add_mset C N, add_mset C' U, D, NE, UE, NS, US, N0, U0, {#}, Q)
(M, add_mset C N, U, D, NE, UE, NS, add_mset (clause C') US, N0, U0, {#}, Q)›
if ‹clause C ⊆# clause C'› |
subsumed_RI:
‹cdcl_twl_subsumed (M, add_mset C' N, add_mset C U, D, NE, UE, NS, US, N0, U0, {#}, Q)
(M, add_mset C N, U, D, NE, UE, add_mset (clause C') NS, US, N0, U0, {#}, Q)›
if ‹clause C ⊆# clause C'› ‹¬tautology (clause C)› ‹distinct_mset (clause C)›
lemma cdcl_twl_subsumed_cdcl_subsumed:
‹cdcl_twl_subsumed S T ⟹ cdcl_subsumed (pstate⇩W_of S) (pstate⇩W_of T) ∨ cdcl_subsumed_RI (pstate⇩W_of S) (pstate⇩W_of T)›
apply (induction rule: cdcl_twl_subsumed.induct)
subgoal by (auto simp: cdcl_subsumed.simps pstate⇩W_of.simps)
subgoal by (auto simp: cdcl_subsumed.simps)
subgoal by (auto simp: cdcl_subsumed.simps)
subgoal by (auto simp: cdcl_subsumed_RI.simps)
done
lemma cdcl_twl_subsumed_II_simp:
‹cdcl_twl_subsumed S S'›
if ‹S = (M, N, U, D, NE, UE, NS, US, N0, U0, {#}, Q)›
‹S' = (M, remove1_mset C' N, U, D, NE, UE, add_mset (clause C') NS, US, N0, U0, {#}, Q)›e
‹clause C ⊆# clause C'›
‹C ∈# N›
‹C' ∈# remove1_mset C N›
using that subsumed_II[of C C'] by (auto dest!: multi_member_split)
lemma cdcl_twl_subsumed_RR_simp:
‹cdcl_twl_subsumed S S'›
if ‹S = (M, N, U, D, NE, UE, NS, US, N0, U0, {#}, Q)›
‹S' = (M, N, remove1_mset C' U, D, NE, UE, NS, add_mset (clause C') US, N0, U0, {#}, Q)›
‹clause C ⊆# clause C'›
‹C ∈# U›
‹C' ∈# remove1_mset C U›
using that subsumed_RR[of C C' M N ‹U -{#C,C'#}› D NE UE NS US N0 U0 Q]
by (auto dest!: multi_member_split)
lemma cdcl_twl_subsumed_IR_simp:
‹cdcl_twl_subsumed S S'›
if ‹S = (M, N, U, D, NE, UE, NS, US, N0, U0, {#}, Q)›
‹S' = (M, N, remove1_mset C' U, D, NE, UE, NS, add_mset (clause C') US, N0, U0, {#}, Q)›
‹clause C ⊆# clause C'›
‹C ∈# N›
‹C' ∈# U›
using that subsumed_IR[of C C' M ‹N - {#C#}› ‹U -{#C'#}› D NE UE NS US N0 U0 Q]
by (auto dest!: multi_member_split)
lemma cdcl_twl_subsumed_RI_simp:
‹cdcl_twl_subsumed S T›
if ‹S = (M, N, U, D, NE, UE, NS, US, N0, U0, {#}, Q)› ‹clause C ⊆# clause C'›
‹T = (M, add_mset C (remove1_mset C' N), remove1_mset C U, D, NE, UE, add_mset (clause C') NS,
US, N0, U0, {#}, Q)›
‹¬tautology (clause C)› ‹distinct_mset (clause C)›
‹C' ∈# N› ‹C ∈# U›
using that subsumed_RI[of C C' M ‹N - {#C'#}› ‹U - {#C#}› D NE UE NS US N0 U0 Q]
by (auto dest!: multi_member_split)
text ‹
The lifting from \<^term>‹cdcl_subresolution› is a lot more complicated due to the handling of
unit and nonunit clauses. Basically, we have to split every rule in two. Hence we don't have a
one-to-one mapping anymore, but need to use \<^term>‹cdcl_flush_unit› or rule of that kind.
We don't support (yet) generation of the empty clause. This is very tricky because we entirely
leave the CDCL calculus.
The condition \<^term>‹∀L ∈# clause E. undefined_lit M L› is not necessary from the point of view of CDCL,
but it makes it much easier to fulfill the conditions of the watched literals. It should be possible
to do so, but we would need to add conditions on it. However, this makes the inprocessing harder to
do.
›
inductive cdcl_twl_subresolution :: ‹'v twl_st ⇒ 'v twl_st ⇒ bool› where
twl_subresolution_II_nonunit:
‹cdcl_twl_subresolution (M, N + {#C, C'#}, U, None, NE, UE, NS, US, N0, U0, {#}, Q)
(M, N + {#C, E#}, U, None, NE, UE, add_mset (clause C') NS, US, N0, U0, {#}, Q)›
if
‹clause C = add_mset L D›
‹clause C' = add_mset (-L) D'›
‹count_decided M = 0› ‹D ⊆# D'› ‹¬tautology (D + D')›
‹clause E = remdups_mset D'› ‹size (watched E) = 2› ‹struct_wf_twl_cls E› ‹∀L ∈# clause E. undefined_lit M L› |
twl_subresolution_II_unit:
‹cdcl_twl_subresolution (M, N + {#C, C'#}, U, None, NE, UE, NS, US, N0, U0, {#}, Q)
(Propagated K {#K#} # M, N + {#C#}, U, None, add_mset {#K#} NE, UE,
add_mset (clause C') NS, US, N0, U0, {#}, add_mset (-K) Q)›
if
‹clause C = add_mset L D›
‹clause C' = add_mset (-L) D'›
‹count_decided M = 0› ‹D ⊆# D'› ‹¬tautology (D + D')›
‹remdups_mset D' = {#K#}› ‹undefined_lit M K›|
twl_subresolution_LL_nonunit:
‹cdcl_twl_subresolution (M, N, U + {#C, C'#}, None, NE, UE, NS, US, N0, U0, {#}, Q)
(M, N, U + {#C, E#}, None, NE, UE, NS, add_mset (clause C') US, N0, U0, {#}, Q)›
if
‹clause C = add_mset L D›
‹clause C' = add_mset (-L) D'›
‹count_decided M = 0› ‹D ⊆# D'›
‹clause E = remdups_mset D'› ‹¬tautology (D + D')› ‹size (watched E) = 2› ‹∀L ∈# clause E. undefined_lit M L› |
twl_subresolution_LL_unit:
‹cdcl_twl_subresolution (M, N, U + {#C, C'#}, None, NE, UE, NS, US, N0, U0, {#}, Q)
(Propagated K {#K#} # M, N, U + {#C#}, None, NE, add_mset {#K#} UE, NS,
add_mset (clause C') US, N0, U0, {#}, add_mset (-K) Q)›
if
‹clause C = add_mset L D›
‹clause C' = add_mset (-L) D'›
‹count_decided M = 0› ‹D ⊆# D'›
‹remdups_mset D' = {#K#}› ‹¬tautology (D + D')› ‹undefined_lit M K›|
twl_subresolution_LI_nonunit:
‹cdcl_twl_subresolution (M, N + {#C#}, U + {#C'#}, None, NE, UE, NS, US, N0, U0, {#}, Q)
(M, N + {#C#}, U + {#E#}, None, NE, UE, NS, add_mset (clause C') US, N0, U0, {#}, Q)›
if
‹clause C = add_mset L D›
‹clause C' = add_mset (-L) D'›
‹count_decided M = 0› ‹D ⊆# D'›
‹clause E = remdups_mset D'› ‹¬tautology (D + D')› ‹size (watched E) = 2› ‹∀L ∈# clause E. undefined_lit M L›|
twl_subresolution_LI_unit:
‹cdcl_twl_subresolution (M, N + {#C#}, U + {#C'#}, None, NE, UE, NS, US, N0, U0, {#}, Q)
(Propagated K {#K#} # M, N + {#C#}, U, None, NE, add_mset {#K#} UE, NS,
add_mset (clause C') US, N0, U0, {#}, add_mset (-K) Q)›
if
‹clause C = add_mset L D›
‹clause C' = add_mset (-L) D'›
‹count_decided M = 0› ‹D ⊆# D'›
‹remdups_mset D' = {#K#}› ‹¬tautology (D + D')› ‹undefined_lit M K›|
twl_subresolution_IL_nonunit:
‹cdcl_twl_subresolution (M, N + {#C'#}, U + {#C#}, None, NE, UE, NS, US, N0, U0, {#}, Q)
(M, N + {#E#}, U + {#C#}, None, NE, UE, add_mset (clause C') NS, US, N0, U0, {#}, Q)›
if
‹clause C = add_mset L D›
‹clause C' = add_mset (-L) D'›
‹count_decided M = 0› ‹D ⊆# D'›
‹clause E = remdups_mset D'› ‹¬tautology (D + D')› ‹size (watched E) = 2› ‹∀L ∈# clause E. undefined_lit M L› |
twl_subresolution_IL_unit:
‹cdcl_twl_subresolution (M, N + {#C'#}, U + {#C#}, None, NE, UE, NS, US, N0, U0, {#}, Q)
(Propagated K {#K#} # M, N, U + {#C#}, None, add_mset {#K#} NE, UE,
add_mset (clause C') NS, US, N0, U0, {#}, add_mset (-K) Q)›
if
‹clause C = add_mset L D›
‹clause C' = add_mset (-L) D'›
‹count_decided M = 0› ‹D ⊆# D'›
‹remdups_mset D' = {#K#}› ‹¬tautology (D + D')› ‹undefined_lit M K›
lemma past_invs_count_decided0: ‹count_decided (get_trail S) = 0 ⟹ past_invs S›
by (cases S) (auto simp: past_invs.simps)
lemma cdcl_twl_subresolution_past_invs: ‹cdcl_twl_subresolution S T ⟹ past_invs T›
by (induction rule: cdcl_twl_subresolution.induct)
(auto simp: past_invs_count_decided0)
lemma twl_lazy_update_subresII: ‹count_decided M = 0 ⟹ struct_wf_twl_cls C ⟹
¬ twl_is_an_exception (C) (Q) {#} ⟹ - K ∉# watched C ⟹
twl_lazy_update (M) C ⟹
twl_lazy_update (Propagated K {#K#} # M) C›
using count_decided_ge_get_level[of M]
by (cases C)
(fastforce simp: get_level_cons_if has_blit_def uminus_lit_swap twl_is_an_exception_def
dest!: multi_member_split
elim!: size_mset_SucE)
lemma watched_literals_false_of_max_level_prop_lvl0: ‹count_decided M = 0 ⟹ watched_literals_false_of_max_level (Propagated K {#K#} # M) C›
using count_decided_ge_get_level[of M]
by (cases C)
(fastforce simp: get_level_cons_if has_blit_def uminus_lit_swap twl_is_an_exception_def
dest!: multi_member_split
elim!: size_mset_SucE)
lemma watched_literals_false_of_max_level_lvl0: ‹count_decided M = 0 ⟹ watched_literals_false_of_max_level (M) C›
using count_decided_ge_get_level[of M]
by (cases C)
(fastforce simp: get_level_cons_if has_blit_def uminus_lit_swap twl_is_an_exception_def
dest!: multi_member_split
elim!: size_mset_SucE)
lemma twl_lazy_update_undefined: ‹∀L ∈# clause E. undefined_lit M L ⟹ twl_lazy_update M E›
by (cases E)
(auto simp: has_blit_def Decided_Propagated_in_iff_in_lits_of_l
dest!: multi_member_split)
lemma struct_wf_twl_cls_remdupsI:
‹clause E = remdups_mset D' ⟹ size (watched E) = 2 ⟹ struct_wf_twl_cls E›
by (cases E) auto
lemma cdcl_twl_subresolution_twl_st_inv:
‹cdcl_twl_subresolution S T ⟹ twl_st_inv S ⟹ twl_st_inv T›
by (induction rule: cdcl_twl_subresolution.induct)
(auto simp: twl_st_inv.simps twl_lazy_update_undefined watched_literals_false_of_max_level_lvl0
twl_lazy_update_subresII twl_is_an_exception_add_mset_to_queue
watched_literals_false_of_max_level_prop_lvl0
intro: struct_wf_twl_cls_remdupsI)
lemma cdcl_twl_subresolution_valid_enqueued:
‹cdcl_twl_subresolution S T ⟹ valid_enqueued S ⟹ valid_enqueued T›
by (induction rule: cdcl_twl_subresolution.induct)
(auto simp: get_level_cons_if)
lemma cdcl_twl_subresolution_decompE:
assumes
‹cdcl_twl_subresolution S T› and ‹Multiset.Ball (get_clauses S) (distinct_mset o clause)› and
subres: ‹cdcl_subresolution (pstate⇩W_of S) (pstate⇩W_of T) ⟹ thesis› and
unit: ‹⋀S' T'. cdcl_subresolution (pstate⇩W_of S) S' ⟹
cdcl_propagate S' (T') ⟹ cdcl_flush_unit (T') (pstate⇩W_of T) ⟹ thesis›
shows thesis
using assms(1,2,3)
apply (cases rule: cdcl_twl_subresolution.cases)
subgoal for C L D C' D' M E N U NE UE NS US Q
apply (rule subres)
using cdcl_subresolution.intros(1)[of M D D' ‹clauses N› L ‹clauses U› None NE UE NS US]
by auto
subgoal for C L D C' D' M E N U NE UE NS US N0 U0 Q
apply (rule unit[of ‹(M, clauses N + {#clause C, D'#}, clauses U, None, NE, UE,
add_mset (clause C') NS, US, N0, U0)›
‹(Propagated E D' # M, clauses N + {#clause C, D'#}, clauses U, None, NE, UE,
add_mset (clause C') NS, US, N0, U0)›])
subgoal
by (auto simp: cdcl_subresolution.simps distinct_mset_remdups_mset_id)
subgoal
by (auto simp: cdcl_propagate.simps distinct_mset_remdups_mset_id)
subgoal
by (auto simp: cdcl_flush_unit.simps distinct_mset_remdups_mset_id)
done
supply[[goals_limit=1]]
subgoal for C L D C' D' M E N U NE UE NS US Q
apply (rule subres)
using cdcl_subresolution.intros(2)[of M D D' ‹clauses N› ‹clauses U› L None NE UE NS US]
by auto
subgoal for C L D C' D' M E N U NE UE NS US N0 U0 Q
apply (rule unit[of ‹(M, clauses N, clauses U + {#clause C, D'#}, None, NE, UE,
NS, add_mset (clause C') US, N0, U0)›
‹(Propagated E D' # M, clauses N, clauses U + {#clause C, D'#}, None, NE, UE, NS,
add_mset (clause C') US, N0, U0)›])
subgoal
apply (auto simp: cdcl_subresolution.simps distinct_mset_remdups_mset_id)
apply (rule_tac x=D in exI)
apply (rule_tac x=D' in exI)
apply auto
done
subgoal
by (auto simp: cdcl_propagate.simps distinct_mset_remdups_mset_id)
subgoal
by (auto simp: cdcl_flush_unit.simps distinct_mset_remdups_mset_id)
done
subgoal for C L D C' D' M E N U NE UE NS US Q
apply (rule subres)
using cdcl_subresolution.intros(3)[of M D D' ‹clauses N› L ‹clauses U› None NE UE NS US]
by auto
subgoal for C L D C' D' M E N U NE UE NS US N0 U0 Q
apply (rule unit[of ‹(M, clauses N + {#clause C#}, clauses U + {#D'#}, None, NE, UE,
NS, add_mset (clause C') US, N0, U0)›
‹(Propagated E D' # M, clauses N + {#clause C#}, clauses U + {#D'#}, None, NE, UE, NS,
add_mset (clause C') US, N0, U0)›])
subgoal
apply (auto simp: cdcl_subresolution.simps distinct_mset_remdups_mset_id)
apply (drule_tac x=D in spec)
apply (drule_tac x=D' in spec)
apply auto
done
subgoal
by (auto simp: cdcl_propagate.simps distinct_mset_remdups_mset_id)
subgoal
by (auto simp: cdcl_flush_unit.simps distinct_mset_remdups_mset_id)
done
subgoal for C L D C' D' M E N U NE UE NS US N0 U0 Q
apply (rule subres)
using cdcl_subresolution.intros(4)[of M D' D ‹clauses N› ‹-L› ‹clauses U› None NE UE NS US]
by (auto simp: ac_simps)
subgoal for C L D C' D' M K N U NE UE NS US N0 U0 Q
apply (rule unit[of ‹(M, clauses N + {#D'#}, clauses U + {#clause C#}, None, NE, UE,
add_mset (clause C') NS, US, N0, U0)›
‹(Propagated K D' # M, clauses N + {#D'#}, clauses U + {#clause C#}, None, NE, UE,
add_mset (clause C') NS, US, N0, U0)›])
subgoal
apply (auto simp: cdcl_subresolution.simps distinct_mset_remdups_mset_id)
apply (auto 5 5 intro: dest: spec[of _ ‹-L›] dest!: spec[of _ ‹clauses N›])
done
subgoal
by (auto simp: cdcl_propagate.simps distinct_mset_remdups_mset_id)
subgoal
by (auto simp: cdcl_flush_unit.simps distinct_mset_remdups_mset_id)
done
done
lemma cdcl_twl_subresolution_pcdcl_all_struct_invs:
‹cdcl_twl_subresolution S T ⟹
pcdcl_all_struct_invs (pstate⇩W_of S) ⟹ pcdcl_all_struct_invs (pstate⇩W_of T)›
apply (elim cdcl_twl_subresolution_decompE)
subgoal
by (cases S)
(auto simp: pcdcl_all_struct_invs_def cdcl⇩W_restart_mset.cdcl⇩W_all_struct_inv_def
cdcl⇩W_restart_mset.distinct_cdcl⇩W_state_def
dest!: multi_member_split)
subgoal
by (drule cdcl_subresolution)
(simp_all add: rtranclp_pcdcl_all_struct_invs)
subgoal
apply (drule pcdcl.intros pcdcl_core.intros)+
apply (drule cdcl_subresolution)
using rtranclp_pcdcl_all_struct_invs by blast
done
lemma cdcl_twl_subresolution_smaller_propa:
‹cdcl_twl_subresolution S T ⟹ cdcl⇩W_restart_mset.no_smaller_propa (state⇩W_of T)›
apply (induction rule: cdcl_twl_subresolution.induct)
apply (auto simp: cdcl⇩W_restart_mset.no_smaller_propa_def)
apply (case_tac M'; auto; fail)+
done
lemma cdcl_twl_subresolution_twl_st_exception_inv:
‹cdcl_twl_subresolution S T ⟹ no_dup (get_trail S) ⟹
twl_st_exception_inv S ⟹ twl_st_exception_inv T›
apply (induction rule: cdcl_twl_subresolution.induct)
subgoal
unfolding twl_st_exception_inv.simps
apply (intro ballI)
apply (rename_tac x; case_tac x)
apply (auto simp: twl_exception_inv.simps)
apply (metis mset_subset_eqD mset_subset_eq_add_left set_mset_remdups_mset
uminus_lits_of_l_definedD)
apply (metis Un_iff clause.simps twl_clause.sel(1) twl_clause.sel(2))
by (metis Un_iff clause.simps twl_clause.sel(1) twl_clause.sel(2))
subgoal
unfolding twl_st_exception_inv.simps
apply (intro ballI)
apply (rename_tac x; case_tac x)
apply (auto simp: twl_exception_inv.simps)
apply (metis Un_iff clause.simps no_has_blit_propagate twl_clause.sel(1) twl_clause.sel(2))+
done
subgoal
unfolding twl_st_exception_inv.simps
apply (intro ballI)
apply (rename_tac x; case_tac x)
apply (auto simp: twl_exception_inv.simps)
apply (metis mset_subset_eqD mset_subset_eq_add_left set_mset_remdups_mset
uminus_lits_of_l_definedD)
apply (metis Un_iff clause.simps twl_clause.sel(1) twl_clause.sel(2))
by (metis Un_iff clause.simps twl_clause.sel(1) twl_clause.sel(2))
subgoal
unfolding twl_st_exception_inv.simps
apply (intro ballI)
apply (rename_tac x; case_tac x)
apply (auto simp: twl_exception_inv.simps)
apply (metis Un_iff clause.simps no_has_blit_propagate twl_clause.sel(1) twl_clause.sel(2))+
done
subgoal
unfolding twl_st_exception_inv.simps
apply (intro ballI)
apply (rename_tac x; case_tac x)
apply (auto simp: twl_exception_inv.simps)
apply (metis mset_subset_eqD mset_subset_eq_add_left set_mset_remdups_mset
uminus_lits_of_l_definedD)
apply (metis Un_iff clause.simps twl_clause.sel(1) twl_clause.sel(2))
by (metis Un_iff clause.simps twl_clause.sel(1) twl_clause.sel(2))
subgoal
unfolding twl_st_exception_inv.simps
apply (intro ballI)
apply (rename_tac x; case_tac x)
apply (auto simp: twl_exception_inv.simps)
apply (metis Un_iff clause.simps no_has_blit_propagate twl_clause.sel(1) twl_clause.sel(2))+
done
subgoal
unfolding twl_st_exception_inv.simps
apply (intro ballI)
apply (rename_tac x; case_tac x)
apply (auto simp: twl_exception_inv.simps)
apply (metis mset_subset_eqD mset_subset_eq_add_left set_mset_remdups_mset
uminus_lits_of_l_definedD)
apply (metis Un_iff clause.simps twl_clause.sel(1) twl_clause.sel(2))
by (metis Un_iff clause.simps twl_clause.sel(1) twl_clause.sel(2))
subgoal
unfolding twl_st_exception_inv.simps
apply (intro ballI)
apply (rename_tac x; case_tac x)
apply (auto simp: twl_exception_inv.simps)
apply (metis Un_iff clause.simps no_has_blit_propagate twl_clause.sel(1) twl_clause.sel(2))+
done
done
lemma cdcl_twl_subresolution_dup_enqueued:
‹cdcl_twl_subresolution S T ⟹ no_duplicate_queued S ⟹ no_duplicate_queued T›
by (induction rule: cdcl_twl_subresolution.induct) auto
lemma cdcl_twl_subresolution_distinct_enqueued:
‹cdcl_twl_subresolution S T ⟹ distinct_queued S ⟹ no_duplicate_queued S ⟹ distinct_queued T›
apply (induction rule: cdcl_twl_subresolution.induct)
unfolding distinct_queued.simps
by (auto dest: mset_le_add_mset simp: undefined_notin)
lemma Cons_entails_CNotE:
assumes ‹K # M ⊨as CNot Ca› ‹distinct_mset Ca› and
1: ‹M ⊨as CNot Ca ⟹ -lit_of K ∉# Ca ⟹ thesis› and
2: ‹M ⊨as CNot (remove1_mset (-lit_of K) Ca) ⟹ -lit_of K ∈# Ca ⟹ thesis›
shows thesis
using assms(1,2)
apply (cases ‹-lit_of K ∈# Ca›)
subgoal
by (rule 2)
(auto dest!: multi_member_split
simp: true_annots_true_cls_def_iff_negation_in_model uminus_lit_swap
add_mset_eq_add_mset)
subgoal
by (rule 1)
(auto dest!: multi_member_split
simp: true_annots_true_cls_def_iff_negation_in_model uminus_lit_swap
add_mset_eq_add_mset)
done
lemma propa_confl_cands_enqueued_simps[simp]:
‹propa_confl_cands_enqueued (M, N, U, None, add_mset E NE, UE, NS, US, N0, U0, {#}, Q) ⟷
propa_confl_cands_enqueued (M, N, U, None, NE, UE, NS, US, N0, U0, {#},Q)›
‹propa_confl_cands_enqueued (M, N, U, None, NE, add_mset E UE, NS, US, N0, U0, {#}, Q) ⟷
propa_confl_cands_enqueued (M, N, U, None, NE, UE, NS, US, N0, U0, {#},Q)›
‹propa_confl_cands_enqueued (M, N, U, None, NE, UE, add_mset (C') NS, US, N0, U0, {#}, Q) ⟷
propa_confl_cands_enqueued (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q)›
‹propa_confl_cands_enqueued (M, N, U, None, NE, UE, NS, add_mset (C') US, N0, U0, {#}, Q) ⟷
propa_confl_cands_enqueued (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q)›
apply (auto)
done
lemma propa_confl_cands_enqueuedD:
‹propa_confl_cands_enqueued (M, add_mset C N, U, None, NE, UE, NS, US, N0, U0, {#}, Q) ⟹
propa_confl_cands_enqueued (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q)›
‹propa_confl_cands_enqueued (M, N, add_mset C U, None, NE, UE, NS, US, N0, U0, {#}, Q) ⟹
propa_confl_cands_enqueued (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q)›
by auto
lemma add_mset_diff_add_mset_If:
"(add_mset L' C) - add_mset L C'= (if L = L' then C - C' else remove1_mset L C + {#L'#} - C')"
by (auto simp: multiset_eq_iff)
lemma propa_confl_cands_enqueued_propagate:
assumes
‹Multiset.Ball (N+U) (struct_wf_twl_cls)› and
prev: ‹propa_confl_cands_enqueued (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q)› and
excep: ‹twl_st_exception_inv (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q)› and
‹count_decided M = 0› and
nd: ‹no_dup (Propagated L C # M)›
shows ‹propa_confl_cands_enqueued (Propagated L C # M, N, U, None, NE, UE, NS, US, N0, U0,
{#}, add_mset (-L) Q)›
unfolding propa_confl_cands_enqueued.simps
proof (intro ballI impI)
fix Ca La
assume NU: ‹Ca∈#N + U› and La_Ca: ‹La ∈# clause Ca› and
ent: ‹Propagated L C # M ⊨as CNot (remove1_mset La (clause Ca))› and
not_true: ‹La ∉ lits_of_l (Propagated L C # M)›
have [simp]: ‹get_level M L = 0› for L
using count_decided_ge_get_level[of M] assms
by auto
have dist2: ‹distinct_mset (clause Ca)› and watched: ‹size (watched Ca) = 2›
using assms(1) NU by (cases Ca; auto dest!: multi_member_split)+
then have dist: ‹distinct_mset (remove1_mset La (clause Ca))›
by auto
show ‹(∃L'. L' ∈# watched Ca ∧ L' ∈# add_mset (- L) Q) ∨ (∃L. (L, Ca) ∈# {#})›
proof (rule Cons_entails_CNotE[OF ent dist])
assume ‹M ⊨as CNot (remove1_mset La (clause Ca))› and
‹- lit_of (Propagated L C) ∉# remove1_mset La (clause Ca)›
then have ‹∃L'. L' ∈# watched Ca ∧ L' ∈# Q›
using prev NU not_true La_Ca
by (auto simp: dest!: multi_member_split)
then show ?thesis
by auto
next
assume neg: ‹M ⊨as CNot (remove1_mset (- lit_of (Propagated L C)) (remove1_mset La (clause Ca)))› and
inL: ‹- lit_of (Propagated L C) ∈# remove1_mset La (clause Ca)›
with in_diffD[OF this(2)] have [simp]: ‹L ≠ -La› ‹L ≠ La›
using dist2 not_true by (auto dest!: multi_member_split)
have ‹twl_exception_inv (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q) Ca›
using excep NU by auto
then show ‹(∃L'. L' ∈# watched Ca ∧ L' ∈# add_mset (- L) Q) ∨ (∃L. (L, Ca) ∈# {#})›
apply -
apply (rule ccontr)
using neg watched not_true nd inL
apply (cases Ca)
apply (auto elim!: Cons_entails_CNotE dest!: multi_member_split[of _ N] multi_member_split[of ‹-L›]
simp: distinct_mset_remove1_All uminus_lit_swap removeAll_notin has_blit_def add_mset_diff_add_mset_If
twl_exception_inv.simps size_2_iff all_conj_distrib remove1_mset_add_mset_If)
apply (auto split: if_splits simp: remove1_mset_add_mset_If Decided_Propagated_in_iff_in_lits_of_l
dest: no_dup_consistentD uminus_lits_of_l_definedD
dest!: multi_member_split; fail)+
done
qed
qed
lemma propa_confl_cands_enqueued_learn:
assumes
prev: ‹propa_confl_cands_enqueued (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q)› and
‹∀L ∈# clause C. undefined_lit M L› ‹struct_wf_twl_cls C› ‹no_dup M›
shows ‹propa_confl_cands_enqueued (M, add_mset C N, U, None, NE, UE, NS, US, N0, U0, {#}, Q)›
‹propa_confl_cands_enqueued (M, N, add_mset C U, None, NE, UE, NS, US, N0, U0, {#}, Q)›
using assms
by (cases C; force simp: size_2_iff Decided_Propagated_in_iff_in_lits_of_l)+
lemma propa_confl_cands_enqueued_learn_empty:
assumes
prev: ‹propa_confl_cands_enqueued (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q)›
shows ‹propa_confl_cands_enqueued (M, N, U, Some C, NE, UE, NS, US, add_mset {#} N0, U0, {#}, Q')›
‹propa_confl_cands_enqueued (M, N, U, Some C, NE, UE, NS, US, N0, add_mset {#} U0, {#}, Q')›
using assms
by (cases C; force simp: Decided_Propagated_in_iff_in_lits_of_l)+
lemma twl_exception_inv_skip_clause:
‹twl_exception_inv (M, add_mset C' (N), U, None, NE, UE, NS, US, N0, U0, {#}, Q) C ⟹
twl_exception_inv (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q) C›
‹twl_exception_inv (M, N, add_mset C' U, None, NE, UE, NS, US, N0, U0, {#}, Q) C ⟹
twl_exception_inv (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q) C›
by (cases C) (auto simp: twl_exception_inv.simps)
lemma cdcl_twl_subresolution_propa_confl_cands_enqueued:
assumes
‹cdcl_twl_subresolution S T›
‹Multiset.Ball (get_clauses S) (struct_wf_twl_cls)› and
prev: ‹propa_confl_cands_enqueued S› and
excep: ‹twl_st_exception_inv S› and
nd: ‹no_dup (get_trail S)›
shows ‹propa_confl_cands_enqueued T›
using assms
apply (induction rule: cdcl_twl_subresolution.induct)
subgoal for C L D C' D' M E N U NE UE NS US N0 U0 Q
by (auto simp del: propa_confl_cands_enqueued.simps
simp: add_mset_commute[of C _]
intro!: propa_confl_cands_enqueued_learn(1)[where C=E]
dest: propa_confl_cands_enqueuedD)
subgoal for C L D C' D' M K N U NE UE NS US Q
apply (auto simp del: propa_confl_cands_enqueued.simps
simp: add_mset_commute[of C _] twl_exception_inv_skip_clause[where C'=C' and N=‹add_mset C N›]
intro: propa_confl_cands_enqueued_learn(1)[where C=C' and N=‹add_mset C N›]
intro!: propa_confl_cands_enqueued_propagate
dest: propa_confl_cands_enqueuedD
dest!: multi_member_split[of _ N] multi_member_split[of _ U])
done
subgoal for C L D C' D' M E N U NE UE NS US Q
by (auto simp del: propa_confl_cands_enqueued.simps
simp: add_mset_commute[of C _]
intro!: propa_confl_cands_enqueued_learn(2)[where C=E] struct_wf_twl_cls_remdupsI
dest: propa_confl_cands_enqueuedD)
subgoal for C L D C' D' M K N U NE UE NS US Q
apply (auto simp del: propa_confl_cands_enqueued.simps
simp: add_mset_commute[of C _] twl_exception_inv_skip_clause[where C'=C' and N=‹add_mset C N›]
intro: propa_confl_cands_enqueued_learn(1)[where C=C' and N=‹add_mset C N›]
intro!: propa_confl_cands_enqueued_propagate
dest: propa_confl_cands_enqueuedD
dest!: multi_member_split[of _ N] multi_member_split[of _ U])
apply (simp_all add: twl_exception_inv.simps(1))
done
subgoal for C L D C' D' M E N U NE UE NS US Q
by (auto simp del: propa_confl_cands_enqueued.simps
simp: add_mset_commute[of C _]
intro!: propa_confl_cands_enqueued_learn(2)[where C=E] struct_wf_twl_cls_remdupsI
dest: propa_confl_cands_enqueuedD)
subgoal for C L D C' D' M K N U NE UE NS US Q
apply (auto simp del: propa_confl_cands_enqueued.simps
simp: add_mset_commute[of C _] twl_exception_inv_skip_clause[where C'=C' and N=‹add_mset C N›]
intro: propa_confl_cands_enqueued_learn(1)[where C=C' and N=‹add_mset C N›]
intro!: propa_confl_cands_enqueued_propagate
dest: propa_confl_cands_enqueuedD
dest!: multi_member_split[of _ N] multi_member_split[of _ U])
done
subgoal for C L D C' D' M E N U NE UE NS US Q
by (auto simp del: propa_confl_cands_enqueued.simps
simp: add_mset_commute[of C _]
intro!: propa_confl_cands_enqueued_learn(1)[where C=E] struct_wf_twl_cls_remdupsI
dest: propa_confl_cands_enqueuedD)
subgoal for C L D C' D' M K N U NE UE NS US Q
apply (auto simp del: propa_confl_cands_enqueued.simps
simp: add_mset_commute[of C _] twl_exception_inv_skip_clause[where C'=C' and N=‹add_mset C N›]
intro: propa_confl_cands_enqueued_learn(1)[where C=C' and N=‹add_mset C N›]
intro!: propa_confl_cands_enqueued_propagate
dest: propa_confl_cands_enqueuedD
dest!: multi_member_split[of _ N] multi_member_split[of _ U])
apply (simp_all add: twl_exception_inv.simps(1))
done
done
lemma cdcl_twl_subresolution_conflict:
‹cdcl_twl_subresolution S T ⟹ get_conflict T = None›
by (induction rule: cdcl_twl_subresolution.induct) auto
lemma clause_alt_def:
‹clause C = watched C + unwatched C›
by (cases C) auto
lemma cdcl_twl_subresolution_clauses_to_update_inv:
‹cdcl_twl_subresolution S T ⟹ no_dup (get_trail S) ⟹
clauses_to_update_inv S ⟹ clauses_to_update_inv T›
apply (induction rule: cdcl_twl_subresolution.induct)
subgoal
by (auto simp: all_conj_distrib clauses_to_update_prop.simps filter_mset_empty_conv
eq_commute[of _ ‹remdups_mset _›] clause_alt_def Decided_Propagated_in_iff_in_lits_of_l
dest!: multi_member_split[of ‹_ :: _ literal›])
subgoal
by (auto simp: all_conj_distrib clauses_to_update_prop.simps filter_mset_empty_conv
eq_commute[of _ ‹remdups_mset _›] clause_alt_def Decided_Propagated_in_iff_in_lits_of_l
add_mset_eq_add_mset dest: no_has_blit_propagate
dest!: multi_member_split[of ‹_ :: _ literal›])
subgoal
by (auto simp: all_conj_distrib clauses_to_update_prop.simps filter_mset_empty_conv
eq_commute[of _ ‹remdups_mset _›] clause_alt_def Decided_Propagated_in_iff_in_lits_of_l
dest!: multi_member_split[of ‹_ :: _ literal›])
subgoal
by (auto simp: all_conj_distrib clauses_to_update_prop.simps filter_mset_empty_conv
eq_commute[of _ ‹remdups_mset _›] clause_alt_def Decided_Propagated_in_iff_in_lits_of_l
add_mset_eq_add_mset dest: no_has_blit_propagate
dest!: multi_member_split[of ‹_ :: _ literal›])
subgoal
by (auto simp: all_conj_distrib clauses_to_update_prop.simps filter_mset_empty_conv
eq_commute[of _ ‹remdups_mset _›] clause_alt_def Decided_Propagated_in_iff_in_lits_of_l
dest!: multi_member_split[of ‹_ :: _ literal›])
subgoal
by (auto simp: all_conj_distrib clauses_to_update_prop.simps filter_mset_empty_conv
eq_commute[of _ ‹remdups_mset _›] clause_alt_def Decided_Propagated_in_iff_in_lits_of_l
add_mset_eq_add_mset dest: no_has_blit_propagate
dest!: multi_member_split[of ‹_ :: _ literal›])
subgoal
by (auto simp: all_conj_distrib clauses_to_update_prop.simps filter_mset_empty_conv
eq_commute[of _ ‹remdups_mset _›] clause_alt_def Decided_Propagated_in_iff_in_lits_of_l
dest!: multi_member_split[of ‹_ :: _ literal›])
subgoal
by (auto simp: all_conj_distrib clauses_to_update_prop.simps filter_mset_empty_conv
eq_commute[of _ ‹remdups_mset _›] clause_alt_def Decided_Propagated_in_iff_in_lits_of_l
add_mset_eq_add_mset dest: no_has_blit_propagate
dest!: multi_member_split[of ‹_ :: _ literal›])
done
lemma cdcl_twl_subresolution_twl_struct_invs:
assumes ‹cdcl_twl_subresolution S T›
‹twl_struct_invs S›
shows ‹twl_struct_invs T›
proof -
have ‹Multiset.Ball (get_clauses S) struct_wf_twl_cls› ‹no_dup (get_trail S)›
using assms(2) unfolding twl_struct_invs_def pcdcl_all_struct_invs_def
cdcl⇩W_restart_mset.cdcl⇩W_all_struct_inv_def cdcl⇩W_restart_mset.cdcl⇩W_M_level_inv_def
by (cases S; auto simp: twl_st_simps)+
moreover have ‹pcdcl_all_struct_invs (pstate⇩W_of T)› ‹twl_st_inv T›
using assms cdcl_twl_subresolution_pcdcl_all_struct_invs[of S T]
cdcl_twl_subresolution_twl_st_inv[of S T]
unfolding twl_struct_invs_def
by auto
then have ‹Multiset.Ball (get_clauses T) struct_wf_twl_cls› ‹no_dup (get_trail T)›
unfolding twl_struct_invs_def pcdcl_all_struct_invs_def
cdcl⇩W_restart_mset.cdcl⇩W_all_struct_inv_def cdcl⇩W_restart_mset.cdcl⇩W_M_level_inv_def
by (cases T; auto simp: twl_st_simps; fail)+
ultimately show ?thesis
using cdcl_twl_subresolution_twl_st_inv[of S T]
cdcl_twl_subresolution_valid_enqueued[of S T]
cdcl_twl_subresolution_pcdcl_all_struct_invs[of S T]
cdcl_twl_subresolution_smaller_propa[of S T]
cdcl_twl_subresolution_twl_st_exception_inv[of S T]
cdcl_twl_subresolution_dup_enqueued[of S T]
cdcl_twl_subresolution_distinct_enqueued[of S T]
cdcl_twl_subresolution_propa_confl_cands_enqueued[of S T]
cdcl_twl_subresolution_propa_confl_cands_enqueued[of S T]
propa_confl_cands_enqueued_propa_confl_enqueued[of S]
propa_confl_cands_enqueued_propa_confl_enqueued[of T]
cdcl_twl_subresolution_conflict[of S T]
cdcl_twl_subresolution_twl_st_exception_inv[of S T]
cdcl_twl_subresolution_clauses_to_update_inv[of S T]
cdcl_twl_subresolution_past_invs[of S T] assms
unfolding twl_struct_invs_def
by clarsimp
qed
lemma Propagated_eq_DecidedD:
‹Propagated L C # M1 = M @ Decided K # M' ⟷
M ≠ [] ∧ hd M = Propagated L C ∧ M1 = tl M @ Decided K # M'›
by (cases M) auto
lemma cdcl_twl_subresolution_twl_stgy_invs:
assumes ‹cdcl_twl_subresolution S T›
‹twl_struct_invs S›
‹twl_stgy_invs S›
shows ‹twl_stgy_invs T›
using assms
by (induction rule: cdcl_twl_subresolution.induct)
(auto simp: twl_stgy_invs_def
cdcl⇩W_restart_mset.cdcl⇩W_stgy_invariant_def
cdcl⇩W_restart_mset.conflict_non_zero_unless_level_0_def
cdcl⇩W_restart_mset.no_smaller_confl_def
Propagated_eq_DecidedD)
inductive cdcl_twl_unitres_true :: ‹'v twl_st ⇒ 'v twl_st ⇒ bool› where
‹cdcl_twl_unitres_true (M, N + {#C#}, U, None, NE, UE, NS, US, N0, U0, {#}, Q)
(M, N, U, None, add_mset (clause C) NE, UE, NS, US, N0, U0, {#}, Q)›
if ‹L ∈# clause C› ‹get_level M L = 0› ‹L ∈ lits_of_l M› |
‹cdcl_twl_unitres_true (M, N , U+ {#C#}, None, NE, UE, NS, US, N0, U0, {#}, Q)
(M, N, U, None, NE, add_mset (clause C) UE, NS, US, N0, U0, {#}, Q)›
if ‹L ∈# clause C› ‹get_level M L = 0› ‹L ∈ lits_of_l M›
lemma cdcl_twl_unitres_true_cdcl_unitres_true:
‹cdcl_twl_unitres_true S T ⟹ cdcl_unitres_true (pstate⇩W_of S) (pstate⇩W_of T)›
by (force simp: cdcl_twl_unitres_true.simps cdcl_unitres_true.simps
dest!: multi_member_split)
lemma cdcl_twl_unitres_true_invs:
‹cdcl_twl_unitres_true S T ⟹ twl_st_inv S ⟹ twl_st_inv T›
‹cdcl_twl_unitres_true S T ⟹ valid_enqueued S ⟹ valid_enqueued T›
‹cdcl_twl_unitres_true S T ⟹ twl_st_exception_inv S ⟹ twl_st_exception_inv T›
‹cdcl_twl_unitres_true S T ⟹ no_duplicate_queued S ⟹ no_duplicate_queued T›
‹cdcl_twl_unitres_true S T ⟹ distinct_queued S ⟹ distinct_queued T›
‹cdcl_twl_unitres_true S T ⟹ confl_cands_enqueued S ⟹ confl_cands_enqueued T›
‹cdcl_twl_unitres_true S T ⟹ propa_cands_enqueued S ⟹ propa_cands_enqueued T›
‹cdcl_twl_unitres_true S T ⟹ clauses_to_update_inv S ⟹ clauses_to_update_inv T›
‹cdcl_twl_unitres_true S T ⟹ past_invs S ⟹ past_invs T›
‹cdcl_twl_unitres_true S T ⟹ get_conflict T = None›
‹cdcl_twl_unitres_true S T ⟹ cdcl⇩W_restart_mset.no_smaller_propa (state_of (pstate⇩W_of S)) ⟹
cdcl⇩W_restart_mset.no_smaller_propa (state_of (pstate⇩W_of T))›
‹cdcl_twl_unitres_true S T ⟹ pcdcl_all_struct_invs (pstate⇩W_of S) ⟹ pcdcl_all_struct_invs (pstate⇩W_of T)›
apply (auto simp: cdcl_twl_unitres_true.simps twl_st_inv.simps
twl_exception_inv.simps filter_mset_empty_conv clauses_to_update_prop.simps
past_invs.simps dest: cdcl_twl_unitres_true_cdcl_unitres_true)[11]
apply (auto dest!: cdcl_twl_unitres_true_cdcl_unitres_true
pcdcl.intros(8) pcdcl_all_struct_invs)
done
lemma cdcl_twl_unitres_true_twl_struct_invs:
‹cdcl_twl_unitres_true S T ⟹ twl_struct_invs S ⟹ twl_struct_invs T›
using cdcl_twl_unitres_true_invs[of S T]
by (auto simp: twl_struct_invs_def)
lemma cdcl_twl_unitres_true_twl_stgy_invs:
assumes ‹cdcl_twl_unitres_true S T›
‹twl_struct_invs S›
‹twl_stgy_invs S›
shows ‹twl_stgy_invs T›
using assms
by (induction rule: cdcl_twl_unitres_true.induct)
(auto simp: twl_stgy_invs_def
cdcl⇩W_restart_mset.cdcl⇩W_stgy_invariant_def
cdcl⇩W_restart_mset.conflict_non_zero_unless_level_0_def
cdcl⇩W_restart_mset.no_smaller_confl_def
Propagated_eq_DecidedD)
inductive cdcl_twl_unitres :: ‹'v twl_st ⇒ 'v twl_st ⇒ bool› where
‹cdcl_twl_unitres (M, N + {#D#}, U, None, NE, UE, NS, US, N0, U0, {#}, Q)
(M, add_mset E N, U, None, NE, UE, add_mset (clause D) NS, US, N0, U0, {#}, Q)›
if ‹count_decided M = 0› and
‹clause D = C+C'›
‹add_mset (C+C') (clauses N + NE + NS + N0) ⊨psm mset_set (CNot C')›
‹¬tautology C› ‹distinct_mset C›
‹struct_wf_twl_cls E›
‹Multiset.Ball (clause E) (undefined_lit M)›
‹clause E = C› |
‹cdcl_twl_unitres (M, N + {#D#}, U, None, NE, UE, NS, US, N0, U0, {#}, Q)
(Propagated K C # M, N, U, None, add_mset C NE, UE, add_mset (clause D) NS, US, N0, U0, {#}, add_mset (-K) Q)›
if ‹count_decided M = 0› and
‹clause D = C+C'›
‹add_mset (C+C') (clauses N + NE + NS + N0) ⊨psm mset_set (CNot C')›
‹¬tautology C› ‹distinct_mset C›
‹C = {#K#}›
‹undefined_lit M K› |
‹cdcl_twl_unitres (M, N, U + {#D#}, None, NE, UE, NS, US, N0, U0, {#}, Q)
(M, N, add_mset E U, None, NE, UE, NS, add_mset (clause D) US, N0, U0, {#}, Q)›
if ‹count_decided M = 0› and
‹clause D = C+C'›
‹(clauses N + NE + NS + N0) ⊨psm mset_set (CNot C')›
‹¬tautology C› ‹distinct_mset C›
‹struct_wf_twl_cls E›
‹clause E = C›
‹Multiset.Ball (clause E) (undefined_lit M)›
‹atms_of C ⊆ atms_of_ms (clause ` set_mset N) ∪ atms_of_mm NE ∪ atms_of_mm NS ∪ atms_of_mm N0› |
‹cdcl_twl_unitres (M, N, U + {#D#}, None, NE, UE, NS, US, N0, U0, {#}, Q)
(Propagated K C # M, N, U, None, NE, add_mset C UE, NS, add_mset (clause D) US, N0, U0, {#}, add_mset (-K) Q)›
if ‹count_decided M = 0› and
‹clause D = C+C'›
‹clauses N + NE + NS + N0 ⊨psm mset_set (CNot C')›
‹¬tautology C› ‹distinct_mset C›
‹C = {#K#}›
‹undefined_lit M K›
‹atms_of C ⊆ atms_of_ms (clause ` set_mset N) ∪ atms_of_mm NE ∪ atms_of_mm NS ∪ atms_of_mm N0› |
‹cdcl_twl_unitres (M, N, U + {#D#}, None, NE, UE, NS, US, N0, U0, {#}, Q)
(M, N, U, Some {#}, NE, UE, NS, add_mset (clause D) US, N0, add_mset {#} U0, {#}, {#})›
if ‹count_decided M = 0› and
‹(clauses N + NE + NS + N0) ⊨psm mset_set (CNot (clause D))› |
‹cdcl_twl_unitres (M, N + {#D#}, U, None, NE, UE, NS, US, N0, U0, {#}, Q)
(M, N, U, Some {#}, NE, UE, add_mset (clause D) NS, US, add_mset {#} N0, U0, {#}, {#})›
if ‹count_decided M = 0› and
‹(clauses (add_mset D N) + NE + NS + N0) ⊨psm mset_set (CNot (clause D))›
lemma cdcl_twl_unitres_cdcl_unitres:
‹cdcl_twl_unitres S T ⟹ cdcl_unitres (pstate⇩W_of S) (pstate⇩W_of T)›
by (induction rule: cdcl_twl_unitres.cases)
(fastforce simp: cdcl_unitres.simps)+
lemma cdcl_twl_unitres_invs:
‹cdcl_twl_unitres S T ⟹ twl_st_inv S ⟹ twl_st_inv T›
by (induction rule: cdcl_twl_unitres.induct)
(auto simp: twl_st_inv.simps twl_lazy_update_subresII
twl_lazy_update_undefined watched_literals_false_of_max_level_lvl0
twl_is_an_exception_add_mset_to_queue)
lemma struct_wf_twl_cls_alt_def:
‹struct_wf_twl_cls C ⟷ distinct_mset (clause C) ∧ size (watched C) = 2›
by (cases C) auto
lemma cdcl_twl_unitres_struct_invs:
assumes ‹cdcl_twl_unitres S T› and ‹twl_struct_invs S› and
‹cdcl⇩W_restart_mset.cdcl⇩W_learned_clauses_entailed_by_init ((state⇩W_of S))›
shows ‹twl_struct_invs T›
unfolding twl_struct_invs_def
proof (intro conjI)
have st_inv: ‹twl_st_inv S› and
valid: ‹valid_enqueued S› and
except: ‹twl_st_exception_inv S› and
dup: ‹no_duplicate_queued S› and
dist: ‹distinct_queued S› and
clss: ‹clauses_to_update_inv S› and
past: ‹past_invs S› and
confl_cands: ‹confl_cands_enqueued S› and
propa_cands: ‹propa_cands_enqueued S› and
dupq: ‹no_duplicate_queued S› and
distq: ‹distinct_queued S› and
invs: ‹pcdcl_all_struct_invs (pstate⇩W_of S)› and
propa: ‹cdcl⇩W_restart_mset.no_smaller_propa (state⇩W_of S)›
using assms(2) unfolding twl_struct_invs_def by fast+
have n_d: ‹no_dup (get_trail S)›
using invs unfolding pcdcl_all_struct_invs_def cdcl⇩W_restart_mset.cdcl⇩W_all_struct_inv_def
cdcl⇩W_restart_mset.cdcl⇩W_M_level_inv_def
by auto
show st_inv_T: ‹twl_st_inv T› and ‹valid_enqueued T›
using valid count_decided_ge_get_level[of ‹get_trail S›] assms(1) st_inv n_d except
by (auto simp: twl_st_inv.simps twl_lazy_update_subresII
twl_lazy_update_undefined watched_literals_false_of_max_level_lvl0 get_level_cons_if
twl_is_an_exception_add_mset_to_queue cdcl_twl_unitres.simps
twl_exception_inv.simps filter_mset_empty_conv clauses_to_update_prop.simps
past_invs.simps Decided_Propagated_in_iff_in_lits_of_l clause_alt_def
uminus_lit_swap
dest!: multi_member_split
dest: mset_le_add_mset simp: undefined_notin; fail)+
show ‹twl_st_exception_inv T›
using count_decided_ge_get_level[of ‹get_trail S›] assms(1) except n_d
by (auto simp: twl_st_inv.simps twl_lazy_update_subresII
twl_lazy_update_undefined watched_literals_false_of_max_level_lvl0 get_level_cons_if
twl_is_an_exception_add_mset_to_queue cdcl_twl_unitres.simps
twl_exception_inv.simps filter_mset_empty_conv clauses_to_update_prop.simps
past_invs.simps Decided_Propagated_in_iff_in_lits_of_l clause_alt_def
uminus_lit_swap
dest!: multi_member_split
dest: mset_le_add_mset simp: undefined_notin)
show ‹clauses_to_update_inv T›
using clss assms(1) n_d
by (auto simp: cdcl_twl_unitres.simps filter_mset_empty_conv all_conj_distrib
Decided_Propagated_in_iff_in_lits_of_l clauses_to_update_prop.simps
split: if_splits dest: has_blit_Cons)
(auto simp: clause_alt_def Decided_Propagated_in_iff_in_lits_of_l split: if_splits; fail)+
show invs_T: ‹pcdcl_all_struct_invs (pstate⇩W_of T)›
using cdcl_twl_unitres_cdcl_unitres[OF assms(1)] invs assms(3)
by (auto dest!: cdcl_unitres_learn_subsume rtranclp_pcdcl_all_struct_invs)
show ‹past_invs T›
using assms(1)
by (auto simp: cdcl_twl_unitres.simps past_invs.simps Propagated_eq_DecidedD)
have struct: ‹∀C ∈# get_clauses S. struct_wf_twl_cls C›
by (use st_inv n_d propa_cands confl_cands in ‹cases S; auto simp: twl_st_inv.simps; fail›)+
then have ‹propa_confl_cands_enqueued S›
by (subst propa_confl_cands_enqueued_propa_confl_enqueued[of S])
(use st_inv n_d propa_cands confl_cands in ‹auto simp: twl_st_inv.simps; fail›)+
with assms(1) have ‹propa_confl_cands_enqueued T›
using n_d struct except
by (induction rule: cdcl_twl_unitres.cases)
(auto 5 4 intro!: propa_confl_cands_enqueued_propagate
simp: propa_confl_cands_enqueued_learn propa_confl_cands_enqueued_learn_empty
dest: propa_confl_cands_enqueuedD twl_exception_inv_skip_clause
dest: multi_member_split[of ‹_ :: _ twl_clause›]
simp del: propa_confl_cands_enqueued.simps)
moreover have struct: ‹∀C ∈# get_clauses T. struct_wf_twl_cls C›
by (use st_inv_T in ‹cases T; auto simp: twl_st_inv.simps; fail›)+
moreover have ‹no_dup (get_trail T)›
using invs_T unfolding pcdcl_all_struct_invs_def cdcl⇩W_restart_mset.cdcl⇩W_all_struct_inv_def
cdcl⇩W_restart_mset.cdcl⇩W_M_level_inv_def
by auto
ultimately show ‹confl_cands_enqueued T› and ‹propa_cands_enqueued T›
by (subst (asm) propa_confl_cands_enqueued_propa_confl_enqueued[of T]; auto; fail)+
show ‹no_duplicate_queued T› and ‹distinct_queued T›
using dupq distq n_d assms(1)
by (force simp: cdcl_twl_unitres.simps past_invs.simps Propagated_eq_DecidedD undefined_notin
dest!: multi_member_split split_list dest: mset_le_add_mset)+
show ‹get_conflict T ≠ None ⟶ clauses_to_update T = {#} ∧ literals_to_update T = {#}›
using assms(1)
by (auto simp: cdcl_twl_unitres.simps past_invs.simps Propagated_eq_DecidedD)
show ‹cdcl⇩W_restart_mset.no_smaller_propa (state⇩W_of T)›
using assms(1)
by (auto simp: cdcl_twl_unitres.simps past_invs.simps Propagated_eq_DecidedD
cdcl⇩W_restart_mset.no_smaller_propa_def)
qed
lemma cdcl_twl_unitres_twl_stgy_invs:
assumes ‹cdcl_twl_unitres S T›
‹twl_struct_invs S›
‹twl_stgy_invs S›
shows ‹twl_stgy_invs T›
using assms
by (induction rule: cdcl_twl_unitres.induct)
(auto simp: twl_stgy_invs_def
cdcl⇩W_restart_mset.cdcl⇩W_stgy_invariant_def
cdcl⇩W_restart_mset.conflict_non_zero_unless_level_0_def
cdcl⇩W_restart_mset.no_smaller_confl_def
Propagated_eq_DecidedD)
lemma twl_exception_inv_add_subsumed:
‹twl_exception_inv (M1, N, U, D, NE, UE, add_mset (C') NS, US, N0, U0, WS, Q) =
twl_exception_inv (M1, N, U, D, NE, UE, NS, US, N0, U0, WS, Q)›
‹twl_exception_inv (M1, N, U, D, NE, UE, NS, add_mset (C') US, N0, U0, WS, Q) =
twl_exception_inv (M1, N, U, D, NE, UE, NS, US, N0, U0, WS, Q)›
by (intro ext; cases D; auto simp: twl_exception_inv.simps)+
lemma propa_confl_cands_enqueued_add_subsumed:
‹propa_confl_cands_enqueued (M, N, U, D, NE, UE, add_mset (C') NS, US, N0, U0, WS, Q) ⟷
propa_confl_cands_enqueued (M, N, U, D, NE, UE, NS, US, N0, U0, WS, Q)›
‹propa_confl_cands_enqueued (M, N, U, D, NE, UE, NS, add_mset (C') US, N0, U0, WS, Q) ⟷
propa_confl_cands_enqueued (M, N, U, D, NE, UE, NS, US, N0, U0, WS, Q)›
by (cases D; auto)+
lemma propa_confl_cands_enqueued_remove_learnD:
‹propa_confl_cands_enqueued (M, add_mset C N, U, D, NE, UE, NS, US, N0, U0, WS, Q) ⟹
propa_confl_cands_enqueued (M, N, U, D, NE, UE, NS, US, N0, U0, WS, Q)›
by (cases D; auto)
lemma propa_confl_cands_enqueued_remove_learnD2:
‹propa_confl_cands_enqueued (M, add_mset C (add_mset C' N), U, D, NE, UE, NS, US, N0, U0, WS, Q) ⟹
propa_confl_cands_enqueued (M, add_mset C N, U, D, NE, UE, NS, US, N0, U0, WS, Q)›
‹propa_confl_cands_enqueued (M, N, add_mset C (add_mset C' U), D, NE, UE, NS, US, N0, U0, WS, Q) ⟹
propa_confl_cands_enqueued (M, N, add_mset C U, D, NE, UE, NS, US, N0, U0, WS, Q)›
‹propa_confl_cands_enqueued (M, add_mset C N, (add_mset C' U), D, NE, UE, NS, US, N0, U0, WS, Q) ⟹
propa_confl_cands_enqueued (M, add_mset C N, U, D, NE, UE, NS, US, N0, U0, WS, Q)›
by (cases D; auto)+
lemma cdcl_subsumed_RI_all_struct_invs:
‹cdcl_subsumed_RI S T ⟹ pcdcl_all_struct_invs S ⟹ pcdcl_all_struct_invs T›
by (elim cdcl_subsumed_RID)
(auto simp add: cdcl_learn_clause_all_struct_inv cdcl_learn_clause_entailed_clss_inv
cdcl_learn_clause_psubsumed_invs cdcl_subsumed_all_struct_inv cdcl_subsumed_entailed_clss_inv
cdcl_subsumed_psubsumed_invs pcdcl_all_struct_invs_def
intro: pcdcl.intros(2) pcdcl.intros(4) pcdcl_clauses0_inv)
lemma cdcl_unitres_pcdcl_all_struct_invs:
‹cdcl_unitres S T ⟹ cdcl⇩W_restart_mset.cdcl⇩W_learned_clauses_entailed_by_init (state_of S) ⟹
pcdcl_all_struct_invs (S) ⟹
pcdcl_all_struct_invs (T)›
using cdcl_unitres_learn_subsume rtranclp_pcdcl_all_struct_invs by blast
lemma cdcl_twl_unitres_pcdcl_all_struct_invs:
‹cdcl_twl_unitres S T ⟹ cdcl⇩W_restart_mset.cdcl⇩W_learned_clauses_entailed_by_init (state⇩W_of S) ⟹
pcdcl_all_struct_invs (pstate⇩W_of S) ⟹
pcdcl_all_struct_invs (pstate⇩W_of T)›
by (drule cdcl_twl_unitres_cdcl_unitres)
(simp add: cdcl_unitres_pcdcl_all_struct_invs)
lemma cdcl_twl_subsumed_struct_invs:
assumes ‹cdcl_twl_subsumed S T› and ‹twl_struct_invs S›
shows ‹twl_struct_invs T›
unfolding twl_struct_invs_def
proof (intro conjI)
have st_inv: ‹twl_st_inv S› and
valid: ‹valid_enqueued S› and
except: ‹twl_st_exception_inv S› and
dup: ‹no_duplicate_queued S› and
dist: ‹distinct_queued S› and
clss: ‹clauses_to_update_inv S› and
past: ‹past_invs S› and
confl_cands: ‹confl_cands_enqueued S› and
propa_cands: ‹propa_cands_enqueued S› and
dupq: ‹no_duplicate_queued S› and
distq: ‹distinct_queued S› and
invs: ‹pcdcl_all_struct_invs (pstate⇩W_of S)› and
propa: ‹cdcl⇩W_restart_mset.no_smaller_propa (state⇩W_of S)› and
confl: ‹get_conflict S ≠ None ⟶ clauses_to_update S = {#} ∧ literals_to_update S = {#}› and
smaller: ‹cdcl⇩W_restart_mset.no_smaller_propa (state⇩W_of S)›
using assms(2) unfolding twl_struct_invs_def by fast+
have n_d: ‹no_dup (get_trail S)›
using invs unfolding pcdcl_all_struct_invs_def cdcl⇩W_restart_mset.cdcl⇩W_all_struct_inv_def
cdcl⇩W_restart_mset.cdcl⇩W_M_level_inv_def
by auto
show st_inv_T: ‹twl_st_inv T› and ‹valid_enqueued T›
using valid count_decided_ge_get_level[of ‹get_trail S›] assms(1) st_inv n_d except
by (auto simp: twl_st_inv.simps twl_lazy_update_subresII
twl_lazy_update_undefined watched_literals_false_of_max_level_lvl0 get_level_cons_if
twl_is_an_exception_add_mset_to_queue cdcl_twl_subsumed.simps
twl_exception_inv.simps filter_mset_empty_conv clauses_to_update_prop.simps
past_invs.simps Decided_Propagated_in_iff_in_lits_of_l clause_alt_def
uminus_lit_swap
dest!: multi_member_split
dest: mset_le_add_mset simp: undefined_notin; fail)+
show ‹twl_st_exception_inv T›
using count_decided_ge_get_level[of ‹get_trail S›] assms(1) except n_d
by (cases ‹get_conflict S›)
(auto simp: twl_st_inv.simps twl_lazy_update_subresII
twl_lazy_update_undefined watched_literals_false_of_max_level_lvl0 get_level_cons_if
twl_is_an_exception_add_mset_to_queue cdcl_twl_subsumed.simps
twl_exception_inv.simps filter_mset_empty_conv clauses_to_update_prop.simps
past_invs.simps Decided_Propagated_in_iff_in_lits_of_l clause_alt_def
uminus_lit_swap
dest!: multi_member_split
dest: mset_le_add_mset simp: undefined_notin)
show ‹clauses_to_update_inv T›
using clss assms(1) n_d
by (cases ‹get_conflict S›)
(auto simp: cdcl_twl_subsumed.simps filter_mset_empty_conv all_conj_distrib
Decided_Propagated_in_iff_in_lits_of_l clauses_to_update_prop.simps
split: if_splits dest: has_blit_Cons)
show invs_T: ‹pcdcl_all_struct_invs (pstate⇩W_of T)›
using cdcl_twl_subsumed_cdcl_subsumed[OF assms(1)] assms(2) invs
by (auto dest!: cdcl_unitres_learn_subsume rtranclp_pcdcl_all_struct_invs cdcl_subsumed_RI_all_struct_invs
simp: cdcl_subsumed_all_struct_inv cdcl_subsumed_entailed_clss_inv cdcl_subsumed_psubsumed_invs
pcdcl_all_struct_invs_def
intro: pcdcl.intros(4) pcdcl_clauses0_inv)
show ‹past_invs T›
using assms(1) past
by (auto simp: cdcl_twl_subsumed.simps past_invs.simps Propagated_eq_DecidedD all_conj_distrib
twl_lazy_update_subresII
twl_lazy_update_undefined watched_literals_false_of_max_level_lvl0 get_level_cons_if
twl_is_an_exception_add_mset_to_queue
twl_exception_inv.simps filter_mset_empty_conv clauses_to_update_prop.simps
Decided_Propagated_in_iff_in_lits_of_l clause_alt_def
dest!: multi_member_split
dest: mset_le_add_mset simp: undefined_notin)
have propa_confl_cands_enqueued_IR: ‹propa_confl_cands_enqueued (M, add_mset C' N, add_mset C U, D, NE, UE, NS, US, N0, U0, {#}, Q) ⟹
propa_confl_cands_enqueued (M, add_mset C N, U, D, NE, UE, NS, US, N0, U0, {#}, Q)› for M C' N C U D NE UE US Q NS N0 U0
by (cases D) (auto simp: )
have struct: ‹∀C ∈# get_clauses S. struct_wf_twl_cls C›
by (use st_inv n_d propa_cands confl_cands in ‹cases S; auto simp: twl_st_inv.simps; fail›)+
then have ‹propa_confl_cands_enqueued S›
by (subst propa_confl_cands_enqueued_propa_confl_enqueued[of S])
(use st_inv n_d propa_cands confl_cands in ‹auto simp: twl_st_inv.simps; fail›)+
with assms(1) have ‹propa_confl_cands_enqueued T›
using n_d struct except
by (induction rule: cdcl_twl_subsumed.cases)
(auto 5 4 intro!: propa_confl_cands_enqueued_propagate
simp: propa_confl_cands_enqueued_learn twl_exception_inv_add_subsumed
propa_confl_cands_enqueued_add_subsumed add_mset_commute
dest: propa_confl_cands_enqueuedD twl_exception_inv_skip_clause
propa_confl_cands_enqueued_remove_learnD2 propa_confl_cands_enqueued_IR
dest: multi_member_split[of ‹_ :: _ twl_clause›]
simp del: propa_confl_cands_enqueued.simps)
moreover have struct: ‹∀C ∈# get_clauses T. struct_wf_twl_cls C›
by (use st_inv_T in ‹cases T; auto simp: twl_st_inv.simps; fail›)+
moreover have ‹no_dup (get_trail T)›
using invs_T unfolding pcdcl_all_struct_invs_def cdcl⇩W_restart_mset.cdcl⇩W_all_struct_inv_def
cdcl⇩W_restart_mset.cdcl⇩W_M_level_inv_def
by auto
ultimately show ‹confl_cands_enqueued T› and ‹propa_cands_enqueued T›
by (subst (asm) propa_confl_cands_enqueued_propa_confl_enqueued[of T]; auto; fail)+
show ‹no_duplicate_queued T› and ‹distinct_queued T›
using dupq distq n_d assms(1)
by (force simp: cdcl_twl_subsumed.simps past_invs.simps Propagated_eq_DecidedD undefined_notin
dest!: multi_member_split split_list dest: mset_le_add_mset)+
show ‹get_conflict T ≠ None ⟶ clauses_to_update T = {#} ∧ literals_to_update T = {#}›
using assms(1) confl
by (auto simp: cdcl_twl_subsumed.simps past_invs.simps Propagated_eq_DecidedD)
show ‹cdcl⇩W_restart_mset.no_smaller_propa (state⇩W_of T)›
using assms(1) smaller
apply (auto simp: cdcl_twl_subsumed.simps past_invs.simps Propagated_eq_DecidedD
cdcl⇩W_restart_mset.no_smaller_propa_def)
apply blast+
done
qed
lemma cdcl_subresolutions_entailed_by_init:
‹cdcl_subresolution S T ⟹
cdcl⇩W_restart_mset.cdcl⇩W_learned_clauses_entailed_by_init (state_of S) ⟹
cdcl⇩W_restart_mset.cdcl⇩W_learned_clauses_entailed_by_init (state_of T)›
apply (induction rule: cdcl_subresolution.induct)
subgoal by (auto simp: cdcl⇩W_restart_mset.cdcl⇩W_learned_clauses_entailed_by_init_def
insert_commute)
subgoal for M C C' N U L D NE UE NS US N0 U0
using true_clss_cls_or_true_clss_cls_or_not_true_clss_cls_or[of ‹set_mset N ∪ set_mset NE ∪ set_mset NS ∪ set_mset N0› L C' C]
true_clss_cls_cong_set_mset[of ‹N + NE + NS + N0› ‹C+C'› C']
by (auto simp: cdcl⇩W_restart_mset.cdcl⇩W_learned_clauses_entailed_by_init_def
insert_commute subset_mset.le_iff_add ac_simps)
subgoal for M C C' N L U D NE UE NS US N0 U0
using true_clss_cls_or_true_clss_cls_or_not_true_clss_cls_or[of ‹set_mset (N + {#add_mset L C#}) ∪ set_mset NE ∪ set_mset NS ∪ set_mset N0› L C' C]
true_clss_cls_cong_set_mset[of ‹(N + {#add_mset L C#}) + NE + NS + N0› ‹C+C'› C']
by (auto simp: cdcl⇩W_restart_mset.cdcl⇩W_learned_clauses_entailed_by_init_def
insert_commute subset_mset.le_iff_add ac_simps)
subgoal for M C C' N L U D NE UE NS US N0 U0
using true_clss_cls_or_true_clss_cls_or_not_true_clss_cls_or[of
‹set_mset (N + {#add_mset L C#}) ∪ set_mset NE ∪ set_mset NS ∪ set_mset N0› L C' C]
true_clss_cls_cong_set_mset[of ‹(N + {#add_mset L C#}) + NE + NS + N0› ‹C+C'› C]
by (force simp: cdcl⇩W_restart_mset.cdcl⇩W_learned_clauses_entailed_by_init_def
insert_commute ac_simps)
done
inductive cdcl_twl_promote_false :: ‹'v twl_st ⇒ 'v twl_st ⇒ bool› where
‹cdcl_twl_promote_false (M, add_mset C N, U, D, NE, UE, NS, US, N0, U0, WS, Q)
(M, N, U, Some {#}, NE, UE, NS, US, add_mset {#} N0, U0, WS, Q)›
if ‹clause C = {#}› ‹count_decided M = 0›|
‹cdcl_twl_promote_false (M, N, add_mset C U, D, NE, UE, NS, US, N0, U0, WS, Q)
(M, N, U, Some {#}, NE, UE, NS, US, N0, add_mset {#} U0, WS, Q)›
if ‹clause C = {#}› ‹count_decided M = 0›
lemma cdcl_twl_promote_false_cdcl_promote_false:
‹cdcl_twl_promote_false S T ⟹ cdcl_promote_false (pstate⇩W_of S) (pstate⇩W_of T)›
by (auto simp: cdcl_twl_promote_false.simps cdcl_promote_false.simps)
lemma cdcl_twl_promote_false_twl_stgy_invs:
assumes ‹cdcl_twl_promote_false S T›
‹twl_struct_invs S›
‹twl_stgy_invs S›
shows ‹twl_stgy_invs T›
using assms
by (induction rule: cdcl_twl_promote_false.induct)
(auto simp: twl_stgy_invs_def cdcl⇩W_restart_mset.cdcl⇩W_stgy_invariant_def
cdcl⇩W_restart_mset.no_smaller_confl_def clauses_def
cdcl⇩W_restart_mset.conflict_non_zero_unless_level_0_def)
lemma cdcl_subsumed_RI_stgy_invs:
‹cdcl_subsumed_RI (pstate⇩W_of S) (pstate⇩W_of T) ⟹ twl_stgy_invs S ⟹
twl_stgy_invs T›
apply (cases rule: cdcl_subsumed_RI.cases, assumption)
apply (cases S; cases T; auto simp: twl_stgy_invs_def
cdcl⇩W_restart_mset.cdcl⇩W_stgy_invariant_def cdcl⇩W_restart_mset.no_smaller_confl_def
clauses_def cdcl⇩W_restart_mset.conflict_non_zero_unless_level_0_def
all_conj_distrib)
apply (metis member_add_mset set_image_mset)
apply (metis member_add_mset set_image_mset)
apply (metis member_add_mset set_image_mset)
apply (metis image_mset_add_mset member_add_mset multi_member_split set_image_mset)
done
lemma cdcl_twl_subsumed_stgy_invs:
‹cdcl_twl_subsumed S T ⟹
twl_struct_invs S ⟹
cdcl⇩W_restart_mset.cdcl⇩W_learned_clauses_entailed_by_init (state⇩W_of S) ⟹
cdcl⇩W_restart_mset.cdcl⇩W_learned_clauses_entailed_by_init (state⇩W_of T) ⟹
twl_stgy_invs S ⟹ twl_stgy_invs T›
apply (drule cdcl_twl_subsumed_cdcl_subsumed)
apply (elim disjE)
apply (simp add: state_of_cdcl_subsumed twl_stgy_invs_def)
apply (simp add: cdcl_subsumed_RI_stgy_invs)
done
lemma cdcl_twl_subsumed_twl_stgy_invs:
assumes ‹cdcl_twl_subsumed S T›
‹twl_stgy_invs S›
shows ‹twl_stgy_invs T›
using assms
by (metis (no_types, lifting) assms cdcl_subsumed_RI_stgy_invs
cdcl_twl_subsumed_cdcl_subsumed state⇩W_of_def state_of_cdcl_subsumed twl_stgy_invs_def)
inductive cdcl_twl_pure_remove :: ‹'v twl_st ⇒ 'v twl_st ⇒ bool› where
‹cdcl_twl_pure_remove (M, N, U, None, NE, UE, NS, US, N0, U0, {#}, Q)
(Propagated L {#L#} # M, N, U, None, add_mset {#L#} NE, UE, NS, US, N0, U0, {#}, add_mset (-L) Q)›
if ‹count_decided M = 0›
‹-L ∉ ⋃ ((set_mset o clause) ` set_mset N)›
‹atm_of L ∈ atms_of_mm (clauses N + NE + NS + N0)›
‹undefined_lit M L›
lemma cdcl_twl_pure_remove_cdcl_pure_remove:
‹cdcl_twl_pure_remove S T ⟹ cdcl_pure_literal_remove (pstate⇩W_of S) (pstate⇩W_of T)›
by (auto simp: cdcl_twl_pure_remove.simps cdcl_pure_literal_remove.simps
dest!: multi_member_split)
lemma cdcl_twl_pure_remove_twl_struct_invs:
assumes pure: ‹cdcl_twl_pure_remove S T› and
‹twl_struct_invs S›
shows ‹twl_struct_invs T›
proof -
have st_inv: ‹twl_st_inv S› and
valid: ‹valid_enqueued S› and
smaller: ‹cdcl⇩W_restart_mset.no_smaller_propa (state⇩W_of S)› and
exception: ‹twl_st_exception_inv S› and
‹pcdcl_all_struct_invs (pstate⇩W_of S)› and
dup: ‹no_duplicate_queued S›
‹distinct_queued S›
‹confl_cands_enqueued S›
‹propa_cands_enqueued S› and
invs: ‹pcdcl_all_struct_invs (pstate⇩W_of S)› and
upd_inv: ‹clauses_to_update_inv S›
using assms unfolding twl_struct_invs_def by fast+
have n_d: ‹no_dup (get_trail S)›
using invs unfolding pcdcl_all_struct_invs_def
cdcl⇩W_restart_mset.cdcl⇩W_all_struct_inv_def
cdcl⇩W_restart_mset.cdcl⇩W_M_level_inv_def
by auto
have wf: ‹∀C ∈# get_clauses S. struct_wf_twl_cls C›
using st_inv by (cases S) (auto simp: twl_st_inv.simps)
have propa_confl: ‹propa_confl_cands_enqueued S›
by (subst propa_confl_cands_enqueued_propa_confl_enqueued)
(use wf dup n_d in auto)
have ‹twl_st_inv T›
using pure st_inv
by (auto simp: cdcl_twl_pure_remove.simps twl_st_inv.simps
twl_is_an_exception_add_mset_to_queue watched_literals_false_of_max_level_prop_lvl0
intro!: twl_lazy_update_subresII
dest: multi_member_split)
moreover have ‹valid_enqueued T›
using valid pure
by (auto simp: cdcl_twl_pure_remove.simps twl_st_inv.simps
get_level_cons_if)
moreover have ‹cdcl⇩W_restart_mset.no_smaller_propa (state⇩W_of T)›
using pure smaller
by (auto simp: cdcl⇩W_restart_mset.no_smaller_propa_def
cdcl_twl_pure_remove.simps Propagated_eq_DecidedD)
moreover have ‹twl_st_exception_inv T›
using pure n_d exception apply -
by (cases rule: cdcl_twl_pure_remove.cases, assumption)
(auto simp: cdcl_twl_pure_remove.simps Propagated_eq_DecidedD
twl_exception_inv.simps uminus_lit_swap
intro!: propa_confl_cands_enqueued_propagate
dest!: no_has_blit_propagate'
dest!: multi_member_split[of ‹_ :: _ clause›])
moreover have ‹no_duplicate_queued T›
‹distinct_queued T›
using pure dup apply (auto simp: no_duplicate_queued.simps
cdcl_twl_pure_remove.simps
dest!: multi_member_split[of _ ‹_ :: _ clause›]
dest: mset_subset_eq_insertD msed_map_invR)[]
using pure dup apply (auto simp: no_duplicate_queued.simps
cdcl_twl_pure_remove.simps undefined_notin
dest!: multi_member_split[of _ ‹_ :: _ clause›]
dest: mset_subset_eq_insertD dest: msed_map_invR)[]
apply (solves ‹frule mset_subset_eq_insertD; clarsimp simp: undefined_notin›)+
done
moreover {
have ‹propa_confl_cands_enqueued T›
using pure dup propa_confl wf exception n_d
by (auto simp: cdcl_twl_pure_remove.simps
twl_exception_inv.simps
simp del: propa_confl_cands_enqueued.simps
intro!: propa_confl_cands_enqueued_propagate)[]
then have
‹confl_cands_enqueued T ∧ propa_cands_enqueued T›
by (subst (asm) propa_confl_cands_enqueued_propa_confl_enqueued)
(use pure wf dup n_d in ‹auto simp: cdcl_twl_pure_remove.simps›)[3]
}
moreover have ‹get_conflict T ≠ None ⟶ clauses_to_update T = {#} ∧ literals_to_update T = {#}›
using pure by (auto simp: cdcl_twl_pure_remove.simps)
moreover have ‹clauses_to_update_inv T›
using n_d pure upd_inv
by (auto simp: cdcl_twl_pure_remove.simps filter_mset_empty_conv all_conj_distrib
Decided_Propagated_in_iff_in_lits_of_l clauses_to_update_prop.simps
split: if_splits dest: has_blit_Cons)
(auto simp: clause_alt_def Decided_Propagated_in_iff_in_lits_of_l split: if_splits; fail)+
moreover have ‹past_invs T›
using pure by (auto simp: cdcl_twl_pure_remove.simps past_invs.simps
Propagated_eq_DecidedD)
moreover have ‹pcdcl_all_struct_invs (pstate⇩W_of T)›
using cdcl_twl_pure_remove_cdcl_pure_remove invs pcdcl.intros(10) pcdcl_all_struct_invs pure
by blast
ultimately show ?thesis
unfolding twl_struct_invs_def
by simp
qed
lemma cdcl_twl_pure_remove_twl_stgy_invs:
assumes pure: ‹cdcl_twl_pure_remove S T› and
‹twl_stgy_invs S›
shows ‹twl_stgy_invs T›
using assms by (auto simp: cdcl_twl_pure_remove.simps
twl_stgy_invs_def cdcl⇩W_restart_mset.conflict_non_zero_unless_level_0_def
cdcl⇩W_restart_mset.cdcl⇩W_stgy_invariant_def Propagated_eq_DecidedD
cdcl⇩W_restart_mset.no_smaller_confl_def)
end