(* Copyright 2013 IMDEA Software Institute Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. *)
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
(******************************************************************************)
(* This file contains the reference implementation of finite maps with keys   *)
(* satisfying condition p and supporting disjoint union via a top element.    *)
(******************************************************************************)
(* I decided to have union_map_class be a class, rather than a structure. The class packages a condition on keys. Ordinary union_maps have a trivially true condition. Heaps have a condition that the pointers are non-null.  Then ordinary union maps, as well as heaps, are declared as instances of this class, to automatically inherit all the lemmas about the operations.  An alternative implementation would have been to define union_map_class as a structure parametrized by the condition, and then obtain heaps by taking the parameter condition of non-null pointers, and ordinary union_maps by taking parameter condition to true.  I decided on the more complicated design to avoid the universe jump. Heap values are dynamic, and live in Type(1), while most of the times, ordinary union_maps store values from Type(0), and can be nested. If the two structures (heaps and ordinary union maps) share the same code, they will both lift to the common universe of Type(1), preventing me from using maps at Type(0), and storing them in the heap.  With the class design, no code is shared, only the lemmas (i.e., only the class type, but that can freely live in an arbitrary universe). The price to pay is that the code of the methods has to be duplicated when declaring instances (such as in heaps.v, or below for union_mapUMC), just to keep the universes from jumping.  *)
Module UM.
Section UM.
Variables (K : ordType) (V : Type) (p : pred K).
Inductive base :=
Undef | Def (f : {finMap K -> V}) of all p (supp f).
Section FormationLemmas.
Variable (f g : {finMap K -> V}).

(* Specifications: *)
Lemma all_supp_insP k v : p k -> all p (supp f) -> all p (supp (ins k v f)).
Lemma all_supp_remP k : all p (supp f) -> all p (supp (rem k f)).
Lemma all_supp_fcatP :
all p (supp f) -> all p (supp g) -> all p (supp (fcat f g)).
Lemma all_supp_kfilterP q :
all p (supp f) -> all p (supp (kfilter q f)).