proposition: Lemma refine_foreign_key_check (h : RawHeading) (rel : Ensemble IndexedRawTuple) (l : list RawTuple) (P : Ensemble RawTuple) (P_dec : DecideableEnsemble P) : EnsembleIndexedListEquivalence rel l -> refine {b | decides b (exists tup' : @IndexedRawTuple h, rel tup' /\ P (indexedElement tup'))} (ret (Check_List_Ex_Prop (DecideableEnsembles.dec) l)).
proof: Proof. intros. unfold refine; intros; computes_to_inv; subst; computes_to_econstructor. case_eq (Check_List_Ex_Prop DecideableEnsembles.dec l); simpl; intros. destruct H as [l' [fresh_l' [l'_eq [equiv_l_l' _] ] ] ]; subst. destruct (Check_List_Ex_Prop_dec DecideableEnsembles.dec P _ dec_decides_P H0); intuition. apply in_map_iff in H1; destruct_ex; intuition; subst. eexists; intuition; eauto; eapply equiv_l_l'; eauto. unfold not; intros; eapply Check_List_Ex_Prop_dec'; eauto using dec_decides_P. destruct_ex; intuition; eexists; intuition; try apply H; eauto. destruct H as [l' [fresh_l' [l'_eq [equiv_l_l' _] ] ] ]; subst. eapply in_map; eapply equiv_l_l'; unfold In; eauto. Qed.
imports: Fiat.Common.Coq__8_4__8_5__Compat Coq.Strings.String Coq.ZArith.ZArith Coq.Lists.List Coq.Logic.FunctionalExtensionality Coq.Sets.Ensembles Coq.Bool.Bool Fiat.Common.ilist2 Fiat.Computation Fiat.ADT Fiat.ADTRefinement Fiat.ADTNotation Fiat.QueryStructure.Specification.Representation.QueryStructureSchema Fiat.QueryStructure.Specification.Operations.Query Fiat.QueryStructure.Specification.Operations.Insert Fiat.QueryStructure.Specification.Representation.QueryStructure Fiat.ADTRefinement.BuildADTRefinements Fiat.Common.DecideableEnsembles Fiat.Common.Ensembles.IndexedEnsembles Fiat.Common.Ensembles.EnsembleListEquivalence Fiat.QueryStructure.Implementation.Operations.General.QueryRefinements Fiat.QueryStructure.Implementation.Operations.General.InsertRefinements Fiat.QueryStructure.Implementation.Operations.General.QueryStructureRefinements Fiat.QueryStructure.Implementation.Constraints.ConstraintChecksRefinements