proposition: Lemma refine_BagADT_QSInsert : forall r_o (r_n : IndexedQueryStructure qs_schema BagIndexKeys), DelegateToBag_AbsR r_o r_n -> forall (idx :Fin.t _) t freshIdx, UnConstrFreshIdx (GetUnConstrRelation r_o idx) freshIdx -> refine {r_n' | DelegateToBag_AbsR (UpdateUnConstrRelation r_o idx ( EnsembleInsert {| indexedElement := t; elementIndex := freshIdx |} (GetUnConstrRelation r_o idx))) r_n'} (CallBagInsert idx r_n t).
proof: Proof. unfold refine; intros. unfold CallBagInsert, CallBagMethod in *; simpl in *; computes_to_inv; subst. computes_to_econstructor; simpl. unfold DelegateToBag_AbsR in *; intuition; intros. intros; destruct (fin_eq_dec idx idx0); subst. - rewrite get_update_unconstr_eq, get_update_indexed_eq. destruct (H idx0) as [l [ [ [bnd fresh_bnd] [l' [l'_eq [l_eqv NoDup_l'] ] ] ] [ [bnd' fresh_bnd'] [l'' [l''_eq [l''_eqv NoDup_l''] ] ] ] ] ]. exists (cons t l); repeat split. + exists (S freshIdx); unfold EnsembleInsert, UnConstrFreshIdx; intros. unfold UnConstrFreshIdx in H0; intuition; subst; simpl; eauto. + unfold UnIndexedEnsembleListEquivalence; exists ({| indexedElement := t; elementIndex := freshIdx |} :: l')%list; intuition. * simpl in *; rewrite l'_eq; trivial. * simpl; destruct H2; [left; symmetry; exact H2 | right; apply l_eqv; eauto]. * unfold EnsembleInsert; destruct H2; [rewrite <- H2; left; trivial | right; eapply l_eqv; eauto ]. * simpl; apply NoDup_cons; eauto. unfold not; intros; apply in_map_iff in H2; destruct H2; destruct H2; apply l_eqv in H3. unfold UnConstrFreshIdx in H0; unfold In in H2; apply H0 in H3; unfold GetNRelSchema in *; omega. + exists (S v1); unfold Ensembles.Add, UnConstrFreshIdx; intros. inversion H2; subst. unfold UnConstrFreshIdx in H1; intuition; subst; simpl; eauto. inversion H3; subst. simpl; eauto. + unfold UnIndexedEnsembleListEquivalence; exists ({| indexedElement := t; elementIndex := v1 |} :: l'')%list; intuition. * simpl in *; rewrite l''_eq; trivial. * simpl; destruct H2; [right; apply l''_eqv; eauto | left; inversion H2; reflexivity ]. * unfold Ensembles.Add; destruct H2; [ right; subst; econstructor | left; eapply l''_eqv; eauto ]. * simpl; apply NoDup_cons; eauto. unfold not; intros; apply in_map_iff in H2; destruct H2; destruct H2; apply l''_eqv in H3; unfold UnConstrFreshIdx in H1; unfold In in H2; apply H1 in H3; unfold GetNRelSchema in *; omega. - rewrite get_update_unconstr_neq, get_update_indexed_neq; eauto. Qed.
imports: Fiat.Common.Coq__8_4__8_5__Compat Coq.Lists.List Coq.Program.Program Fiat.QueryStructure.Specification.Representation.Tuple Fiat.QueryStructure.Specification.Representation.Heading Fiat.Common.ilist2 Fiat.Common.i2list Fiat.Common.ilist3 Fiat.Common.i3list Coq.Bool.Bool Coq.Strings.String Coq.Structures.OrderedTypeEx Coq.Arith.Arith Fiat.Common.String_as_OT Fiat.Common.Ensembles.IndexedEnsembles Fiat.Common.DecideableEnsembles Fiat.Common.List.ListFacts Fiat.QueryStructure.Specification.Operations.FlattenCompList Fiat.QueryStructure.Implementation.Operations.General.QueryRefinements Fiat.QueryStructure.Implementation.Operations.General.InsertRefinements Fiat.QueryStructure.Implementation.Operations.General.EmptyRefinements Fiat.QueryStructure.Specification.Representation.QueryStructureNotations Fiat.QueryStructure.Implementation.ListImplementation Fiat.Common.List.PermutationFacts Fiat.QueryStructure.Implementation.DataStructures.BagADT.BagADT Fiat.QueryStructure.Implementation.DataStructures.BagADT.QueryStructureImplementation Fiat.QueryStructure.Implementation.DataStructures.BagADT.IndexSearchTerms Fiat.QueryStructure.Implementation.Operations.General.DeleteRefinements