zmap.v 4.01 KB
Newer Older
1 2
(** This files extends the implementation of finite over [positive] to finite
maps whose keys range over Coq's data type of binary naturals [Z]. *)
3 4
From stdpp Require Import pmap mapset.
From stdpp Require Export prelude fin_maps.
5
Set Default Proof Using "Type".
6 7
Local Open Scope Z_scope.

Robbert Krebbers's avatar
Robbert Krebbers committed
8
Record Zmap (A : Type) : Type :=
9
  ZMap { Zmap_0 : option A; Zmap_pos : Pmap A; Zmap_neg : Pmap A }.
10 11 12 13
Arguments Zmap_0 {_} _ : assert.
Arguments Zmap_pos {_} _ : assert.
Arguments Zmap_neg {_} _ : assert.
Arguments ZMap {_} _ _ _ : assert.
14

15
Instance Zmap_eq_dec `{EqDecision A} : EqDecision (Zmap A).
16
Proof.
17
 refine (λ t1 t2,
18 19 20
  match t1, t2 with
  | ZMap x t1 t1', ZMap y t2 t2' =>
     cast_if_and3 (decide (x = y)) (decide (t1 = t2)) (decide (t1' = t2'))
21
  end); abstract congruence.
22 23
Defined.
Instance Zempty {A} : Empty (Zmap A) := ZMap None  .
24
Instance Zlookup {A} : Lookup Z A (Zmap A) := λ i t,
25 26 27
  match i with
  | Z0 => Zmap_0 t | Zpos p => Zmap_pos t !! p | Zneg p => Zmap_neg t !! p
  end.
28
Instance Zpartial_alter {A} : PartialAlter Z A (Zmap A) := λ f i t,
29 30 31 32 33
  match i, t with
  | Z0, ZMap o t t' => ZMap (f o) t t'
  | Zpos p, ZMap o t t' => ZMap o (partial_alter f p t) t'
  | Zneg p, ZMap o t t' => ZMap o t (partial_alter f p t')
  end.
34
Instance Zto_list {A} : FinMapToList Z A (Zmap A) := λ t,
35
  match t with
36
  | ZMap o t t' => from_option (λ x, [(0,x)]) [] o ++
37 38 39 40 41 42 43
     (prod_map Zpos id <$> map_to_list t) ++
     (prod_map Zneg id <$> map_to_list t')
  end.
Instance Zomap: OMap Zmap := λ A B f t,
  match t with ZMap o t t' => ZMap (o = f) (omap f t) (omap f t') end.
Instance Zmerge: Merge Zmap := λ A B C f t1 t2,
  match t1, t2 with
44 45
  | ZMap o1 t1 t1', ZMap o2 t2 t2' =>
     ZMap (f o1 o2) (merge f t1 t2) (merge f t1' t2')
46 47 48 49 50 51 52
  end.
Instance Nfmap: FMap Zmap := λ A B f t,
  match t with ZMap o t t' => ZMap (f <$> o) (f <$> t) (f <$> t') end.

Instance: FinMap Z Zmap.
Proof.
  split.
53
  - intros ? [??] [??] H. f_equal.
54 55 56
    + apply (H 0).
    + apply map_eq. intros i. apply (H (Zpos i)).
    + apply map_eq. intros i. apply (H (Zneg i)).
57 58 59
  - by intros ? [].
  - intros ? f [] [|?|?]; simpl; [done| |]; apply lookup_partial_alter.
  - intros ? f [] [|?|?] [|?|?]; simpl; intuition congruence ||
60
      intros; apply lookup_partial_alter_ne; congruence.
61 62
  - intros ??? [??] []; simpl; [done| |]; apply lookup_fmap.
  - intros ? [o t t']; unfold map_to_list; simpl.
63
    assert (NoDup ((prod_map Z.pos id <$> map_to_list t) ++
64
      (prod_map Z.neg id <$> map_to_list t'))).
65
    { apply NoDup_app; split_and?.
66
      - apply (NoDup_fmap_2 _), NoDup_map_to_list.
67
      - intro. rewrite !elem_of_list_fmap. naive_solver.
68
      - apply (NoDup_fmap_2 _), NoDup_map_to_list. }
69 70
    destruct o; simpl; auto. constructor; auto.
    rewrite elem_of_app, !elem_of_list_fmap. naive_solver.
71
  - intros ? t i x. unfold map_to_list. split.
72
    + destruct t as [[y|] t t']; simpl.
73
      * rewrite elem_of_cons, elem_of_app, !elem_of_list_fmap.
74
        intros [?|[[[??][??]]|[[??][??]]]]; simplify_eq/=; [done| |];
75
          by apply elem_of_map_to_list.
76
      * rewrite elem_of_app, !elem_of_list_fmap. intros [[[??][??]]|[[??][??]]];
77
          simplify_eq/=; by apply elem_of_map_to_list.
78
    + destruct t as [[y|] t t']; simpl.
79
      * rewrite elem_of_cons, elem_of_app, !elem_of_list_fmap.
80 81 82
        destruct i as [|i|i]; simpl; [intuition congruence| |].
        { right; left. exists (i, x). by rewrite elem_of_map_to_list. }
        right; right. exists (i, x). by rewrite elem_of_map_to_list.
83
      * rewrite elem_of_app, !elem_of_list_fmap.
84 85 86
        destruct i as [|i|i]; simpl; [done| |].
        { left; exists (i, x). by rewrite elem_of_map_to_list. }
        right; exists (i, x). by rewrite elem_of_map_to_list.
87 88
  - intros ?? f [??] [|?|?]; simpl; [done| |]; apply (lookup_omap f).
  - intros ??? f ? [??] [??] [|?|?]; simpl; [done| |]; apply (lookup_merge f).
89 90 91 92
Qed.

(** * Finite sets *)
(** We construct sets of [Z]s satisfying extensional equality. *)
Robbert Krebbers's avatar
Robbert Krebbers committed
93
Notation Zset := (mapset Zmap).
94
Instance Zmap_dom {A} : Dom (Zmap A) Zset := mapset_dom.
95
Instance: FinMapDom Z Zmap Zset := mapset_dom_spec.