Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
stdpp
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Monitor
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Adam
stdpp
Commits
de801e30
Commit
de801e30
authored
9 years ago
by
Robbert Krebbers
Browse files
Options
Downloads
Patches
Plain Diff
Clean up Patricia trees implementation.
parent
a4363377
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
theories/base.v
+9
-0
9 additions, 0 deletions
theories/base.v
theories/pmap.v
+170
-254
170 additions, 254 deletions
theories/pmap.v
with
179 additions
and
254 deletions
theories/base.v
+
9
−
0
View file @
de801e30
...
...
@@ -767,6 +767,15 @@ Infix "=.>*" := (Forall2 bool_le) (at level 70).
Instance
:
PartialOrder
bool_le
.
Proof
.
repeat
split
;
repeat
intros
[|];
compute
;
tauto
.
Qed
.
Lemma
andb_True
b1
b2
:
b1
&&
b2
↔
b1
∧
b2
.
Proof
.
destruct
b1
,
b2
;
simpl
;
tauto
.
Qed
.
Lemma
orb_True
b1
b2
:
b1
||
b2
↔
b1
∨
b2
.
Proof
.
destruct
b1
,
b2
;
simpl
;
tauto
.
Qed
.
Lemma
negb_True
b
:
negb
b
↔
¬
b
.
Proof
.
destruct
b
;
simpl
;
tauto
.
Qed
.
Lemma
Is_true_false
(
b
:
bool
)
:
b
=
false
→
¬
b
.
Proof
.
now
intros
->
?
.
Qed
.
(** * Miscellaneous *)
Class
Half
A
:=
half
:
A
→
A
.
Notation
"½"
:=
half
:
C_scope
.
...
...
This diff is collapsed.
Click to expand it.
theories/pmap.v
+
170
−
254
View file @
de801e30
...
...
@@ -21,7 +21,7 @@ be represented as a binary tree of an arbitrary size that contains [None] at
all nodes. *)
Inductive
Pmap_raw
(
A
:
Type
)
:
Type
:=
|
PLeaf
:
Pmap_raw
A
|
PNode
:
Pmap_raw
A
→
option
A
→
Pmap_raw
A
→
Pmap_raw
A
.
|
PNode
:
option
A
→
Pmap_raw
A
→
Pmap_raw
A
→
Pmap_raw
A
.
Arguments
PLeaf
{_}
.
Arguments
PNode
{_}
_
_
_
.
...
...
@@ -29,234 +29,151 @@ Instance Pmap_raw_eq_dec `{∀ x y : A, Decision (x = y)} (x y : Pmap_raw A) :
Decision
(
x
=
y
)
.
Proof
.
solve_decision
.
Defined
.
(** The following decidable predicate describes non empty trees. *)
Inductive
Pmap_ne
{
A
}
:
Pmap_raw
A
→
Prop
:=
|
Pmap_ne_val
l
x
r
:
Pmap_ne
(
PNode
l
(
Some
x
)
r
)
|
Pmap_ne_l
l
r
:
Pmap_ne
l
→
Pmap_ne
(
PNode
l
None
r
)
|
Pmap_ne_r
l
r
:
Pmap_ne
r
→
Pmap_ne
(
PNode
l
None
r
)
.
Local
Hint
Constructors
Pmap_ne
.
Instance
Pmap_ne_dec
{
A
}
:
∀
t
:
Pmap_raw
A
,
Decision
(
Pmap_ne
t
)
.
Proof
.
refine
(
fix
go
t
:=
match
t
return
Decision
(
Pmap_ne
t
)
with
|
PLeaf
=>
right
_
|
PNode
_
(
Some
x
)
_
=>
left
_
|
PNode
l
Node
r
=>
cast_if_or
(
go
l
)
(
go
r
)
end
);
clear
go
;
abstract
first
[
constructor
;
by
auto
|
by
inversion
1
]
.
Defined
.
(** The following predicate describes well well formed trees. A tree is well
formed if it is empty or if all nodes at the bottom contain a value. *)
Inductive
Pmap_wf
{
A
}
:
Pmap_raw
A
→
Prop
:=
|
Pmap_wf_leaf
:
Pmap_wf
PLeaf
|
Pmap_wf_node
l
x
r
:
Pmap_wf
l
→
Pmap_wf
r
→
Pmap_wf
(
PNode
l
(
Some
x
)
r
)
|
Pmap_wf_empty
l
r
:
Pmap_wf
l
→
Pmap_wf
r
→
(
Pmap_ne
l
∨
Pmap_ne
r
)
→
Pmap_wf
(
PNode
l
None
r
)
.
Local
Hint
Constructors
Pmap_wf
.
Instance
Pmap_wf_dec
{
A
}
:
∀
t
:
Pmap_raw
A
,
Decision
(
Pmap_wf
t
)
.
Proof
.
refine
(
fix
go
t
:=
match
t
return
Decision
(
Pmap_wf
t
)
with
|
PLeaf
=>
left
_
|
PNode
l
(
Some
x
)
r
=>
cast_if_and
(
go
l
)
(
go
r
)
|
PNode
l
Node
r
=>
cast_if_and3
(
decide
(
Pmap_ne
l
∨
Pmap_ne
r
))
(
go
l
)
(
go
r
)
end
);
clear
go
;
abstract
first
[
constructor
;
by
auto
|
by
inversion
1
]
.
Defined
.
(** Now we restrict the data type of trees to those that are well formed and
thereby obtain a data type that ensures canonicity. *)
Inductive
Pmap
(
A
:
Type
)
:
Type
:=
PMap
{
pmap_car
:
Pmap_raw
A
;
pmap_bool_prf
:
bool_decide
(
Pmap_wf
pmap_car
)
}
.
Arguments
PMap
{_}
_
_
.
Arguments
pmap_car
{_}
_
.
Arguments
pmap_bool_prf
{_}
_
.
Definition
PMap'
{
A
}
(
t
:
Pmap_raw
A
)
(
p
:
Pmap_wf
t
)
:
Pmap
A
:=
PMap
t
(
bool_decide_pack
_
p
)
.
Definition
pmap_prf
{
A
}
(
m
:
Pmap
A
)
:
Pmap_wf
(
pmap_car
m
)
:=
bool_decide_unpack
_
(
pmap_bool_prf
m
)
.
Lemma
Pmap_eq
{
A
}
(
m1
m2
:
Pmap
A
)
:
m1
=
m2
↔
pmap_car
m1
=
pmap_car
m2
.
Proof
.
split
;
[
by
intros
->
|
intros
];
destruct
m1
as
[
t1
?],
m2
as
[
t2
?]
.
simplify_equality'
;
f_equal
;
apply
proof_irrel
.
Qed
.
(** * Operations on the data structure *)
Global
Instance
Pmap_eq_dec
`{
∀
x
y
:
A
,
Decision
(
x
=
y
)}
(
m1
m2
:
Pmap
A
)
:
Decision
(
m1
=
m2
)
:=
match
Pmap_raw_eq_dec
(
pmap_car
m1
)
(
pmap_car
m2
)
with
|
left
H
=>
left
(
proj2
(
Pmap_eq
m1
m2
)
H
)
|
right
H
=>
right
(
H
∘
proj1
(
Pmap_eq
m1
m2
))
Fixpoint
Pmap_wf
{
A
}
(
t
:
Pmap_raw
A
)
:
bool
:=
match
t
with
|
PLeaf
=>
true
|
PNode
None
PLeaf
PLeaf
=>
false
|
PNode
_
l
r
=>
Pmap_wf
l
&&
Pmap_wf
r
end
.
Instance
Pempty_raw
{
A
}
:
Empty
(
Pmap_raw
A
)
:=
PLeaf
.
Global
Instance
Pempty
{
A
}
:
Empty
(
Pmap
A
)
:=
PMap'
∅
Pmap_wf_leaf
.
Arguments
Pmap_wf
_
!
_
/
:
simpl
nomatch
.
Lemma
Pmap_wf_l
{
A
}
o
(
l
r
:
Pmap_raw
A
)
:
Pmap_wf
(
PNode
o
l
r
)
→
Pmap_wf
l
.
Proof
.
destruct
o
,
l
,
r
;
simpl
;
rewrite
?andb_True
;
tauto
.
Qed
.
Lemma
Pmap_wf_r
{
A
}
o
(
l
r
:
Pmap_raw
A
)
:
Pmap_wf
(
PNode
o
l
r
)
→
Pmap_wf
r
.
Proof
.
destruct
o
,
l
,
r
;
simpl
;
rewrite
?andb_True
;
tauto
.
Qed
.
Local
Hint
Immediate
Pmap_wf_l
Pmap_wf_r
.
Definition
PNode'
{
A
}
(
o
:
option
A
)
(
l
r
:
Pmap_raw
A
)
:=
match
l
,
o
,
r
with
PLeaf
,
None
,
PLeaf
=>
PLeaf
|
_,
_,
_
=>
PNode
o
l
r
end
.
Arguments
PNode'
_
_
_
_
:
simpl
never
.
Lemma
PNode_wf
{
A
}
o
(
l
r
:
Pmap_raw
A
)
:
Pmap_wf
l
→
Pmap_wf
r
→
Pmap_wf
(
PNode'
o
l
r
)
.
Proof
.
destruct
o
,
l
,
r
;
simpl
;
auto
.
Qed
.
Local
Hint
Resolve
PNode_wf
.
(** Operations *)
Instance
Pempty_raw
{
A
}
:
Empty
(
Pmap_raw
A
)
:=
PLeaf
.
Instance
Plookup_raw
{
A
}
:
Lookup
positive
A
(
Pmap_raw
A
)
:=
fix
go
(
i
:
positive
)
(
t
:
Pmap_raw
A
)
{
struct
t
}
:
option
A
:=
let
_
:
Lookup
_
_
_
:=
@
go
in
match
t
with
|
PLeaf
=>
None
|
PNode
l
o
r
=>
|
PNode
o
l
r
=>
match
i
with
1
=>
o
|
i
~
0
=>
l
!!
i
|
i
~
1
=>
r
!!
i
end
end
.
Local
Arguments
lookup
_
_
_
_
_
!
_
/
:
simpl
nomatch
.
Fixpoint
Psingleton_raw
{
A
}
(
i
:
positive
)
(
x
:
A
)
:
Pmap_raw
A
:=
match
i
with
|
1
=>
PNode
(
Some
x
)
PLeaf
PLeaf
|
i
~
0
=>
PNode
None
(
Psingleton_raw
i
x
)
PLeaf
|
i
~
1
=>
PNode
None
PLeaf
(
Psingleton_raw
i
x
)
end
.
Fixpoint
Ppartial_alter_raw
{
A
}
(
f
:
option
A
→
option
A
)
(
i
:
positive
)
(
t
:
Pmap_raw
A
)
{
struct
t
}
:
Pmap_raw
A
:=
match
t
with
|
PLeaf
=>
match
f
None
with
None
=>
PLeaf
|
Some
x
=>
Psingleton_raw
i
x
end
|
PNode
o
l
r
=>
match
i
with
|
1
=>
o
|
i
~
0
=>
@
lookup
_
_
_
go
i
l
|
i
~
1
=>
@
lookup
_
_
_
go
i
r
|
1
=>
PNode'
(
f
o
)
l
r
|
i
~
0
=>
PNode'
o
(
Ppartial_alter_raw
f
i
l
)
r
|
i
~
1
=>
PNode'
o
l
(
Ppartial_alter_raw
f
i
r
)
end
end
.
Instance
Plookup
{
A
}
:
Lookup
positive
A
(
Pmap
A
)
:=
λ
i
m
,
pmap_car
m
!!
i
.
Lemma
Plookup_empty
{
A
}
i
:
(
∅
:
Pmap_raw
A
)
!!
i
=
None
.
Proof
.
by
destruct
i
.
Qed
.
Fixpoint
Pfmap_raw
{
A
B
}
(
f
:
A
→
B
)
(
t
:
Pmap_raw
A
)
:
Pmap_raw
B
:=
match
t
with
|
PLeaf
=>
PLeaf
|
PNode
o
l
r
=>
PNode
(
f
<$>
o
)
(
Pfmap_raw
f
l
)
(
Pfmap_raw
f
r
)
end
.
Fixpoint
Pto_list_raw
{
A
}
(
j
:
positive
)
(
t
:
Pmap_raw
A
)
(
acc
:
list
(
positive
*
A
))
:
list
(
positive
*
A
)
:=
match
t
with
|
PLeaf
=>
acc
|
PNode
o
l
r
=>
default
[]
o
(
λ
x
,
[(
Preverse
j
,
x
)])
++
Pto_list_raw
(
j
~
0
)
l
(
Pto_list_raw
(
j
~
1
)
r
acc
)
end
%
list
.
Fixpoint
Pomap_raw
{
A
B
}
(
f
:
A
→
option
B
)
(
t
:
Pmap_raw
A
)
:
Pmap_raw
B
:=
match
t
with
|
PLeaf
=>
PLeaf
|
PNode
o
l
r
=>
PNode'
(
o
≫=
f
)
(
Pomap_raw
f
l
)
(
Pomap_raw
f
r
)
end
.
Fixpoint
Pmerge_raw
{
A
B
C
}
(
f
:
option
A
→
option
B
→
option
C
)
(
t1
:
Pmap_raw
A
)
(
t2
:
Pmap_raw
B
)
:
Pmap_raw
C
:=
match
t1
,
t2
with
|
PLeaf
,
t2
=>
Pomap_raw
(
f
None
∘
Some
)
t2
|
t1
,
PLeaf
=>
Pomap_raw
(
flip
f
None
∘
Some
)
t1
|
PNode
o1
l1
r1
,
PNode
o2
l2
r2
=>
PNode'
(
f
o1
o2
)
(
Pmerge_raw
f
l1
l2
)
(
Pmerge_raw
f
r1
r2
)
end
.
Lemma
Pmap_ne_lookup
{
A
}
(
t
:
Pmap_raw
A
)
:
Pmap_ne
t
→
∃
i
x
,
t
!!
i
=
Some
x
.
(** Proofs *)
Lemma
Pmap_wf_canon
{
A
}
(
t
:
Pmap_raw
A
)
:
(
∀
i
,
t
!!
i
=
None
)
→
Pmap_wf
t
→
t
=
PLeaf
.
Proof
.
induction
1
as
[
?
x
?|
l
r
?
IHl
|
l
r
?
IHr
]
.
*
intros
.
by
exists
1
,
x
.
*
destruct
IHl
as
[
i
[
x
?]]
.
by
exists
(
i
~
0
),
x
.
*
destruct
IHr
as
[
i
[
x
?]]
.
by
exists
(
i
~
1
),
x
.
induction
t
as
[
|
o
l
IHl
r
IHr
];
intros
Ht
?;
auto
.
assert
(
o
=
None
)
as
->
by
(
apply
(
Ht
1
))
.
assert
(
l
=
PLeaf
)
as
->
by
(
apply
IHl
;
try
apply
(
λ
i
,
Ht
(
i
~
0
));
eauto
)
.
by
assert
(
r
=
PLeaf
)
as
->
by
(
apply
IHr
;
try
apply
(
λ
i
,
Ht
(
i
~
1
));
eauto
)
.
Qed
.
Lemma
Pmap_wf_eq_get
{
A
}
(
t1
t2
:
Pmap_raw
A
)
:
Pmap_wf
t1
→
Pmap_wf
t2
→
(
∀
i
,
t1
!!
i
=
t2
!!
i
)
→
t1
=
t2
.
Lemma
Pmap_wf_eq
{
A
}
(
t1
t2
:
Pmap_raw
A
)
:
(
∀
i
,
t1
!!
i
=
t2
!!
i
)
→
Pmap_wf
t1
→
Pmap_wf
t2
→
t1
=
t2
.
Proof
.
intros
t1wf
.
revert
t2
.
induction
t1wf
as
[|
?
x
?
?
IHl
?
IHr
|
l
r
?
IHl
?
IHr
Hne1
]
.
*
destruct
1
as
[|
|
????
[?|?]];
intros
Hget
.
+
done
.
+
discriminate
(
Hget
1
)
.
+
destruct
(
Pmap_ne_lookup
l
)
as
[
i
[??]];
trivial
.
specialize
(
Hget
(
i
~
0
))
.
simpl
in
*.
congruence
.
+
destruct
(
Pmap_ne_lookup
r
)
as
[
i
[??]];
trivial
.
specialize
(
Hget
(
i
~
1
))
.
simpl
in
*.
congruence
.
*
destruct
1
;
intros
Hget
.
+
discriminate
(
Hget
xH
)
.
+
f_equal
.
-
apply
IHl
;
trivial
.
intros
i
.
apply
(
Hget
(
i
~
0
))
.
-
apply
(
Hget
1
)
.
-
apply
IHr
;
trivial
.
intros
i
.
apply
(
Hget
(
i
~
1
))
.
+
specialize
(
Hget
1
)
.
simpl
in
*.
congruence
.
*
destruct
1
;
intros
Hget
.
+
destruct
Hne1
.
-
destruct
(
Pmap_ne_lookup
l
)
as
[
i
[??]];
trivial
.
specialize
(
Hget
(
i
~
0
));
simpl
in
*.
congruence
.
-
destruct
(
Pmap_ne_lookup
r
)
as
[
i
[??]];
trivial
.
specialize
(
Hget
(
i
~
1
));
simpl
in
*.
congruence
.
+
specialize
(
Hget
1
);
simpl
in
*.
congruence
.
+
f_equal
.
-
apply
IHl
;
trivial
.
intros
i
.
apply
(
Hget
(
i
~
0
))
.
-
apply
IHr
;
trivial
.
intros
i
.
apply
(
Hget
(
i
~
1
))
.
revert
t2
.
induction
t1
as
[|
o1
l1
IHl
r1
IHr
];
intros
[|
o2
l2
r2
]
Ht
??;
simpl
;
auto
.
*
discriminate
(
Pmap_wf_canon
(
PNode
o2
l2
r2
));
eauto
.
*
discriminate
(
Pmap_wf_canon
(
PNode
o1
l1
r1
));
eauto
.
*
f_equal
;
[
apply
(
Ht
1
)|
|]
.
+
apply
IHl
;
try
apply
(
λ
x
,
Ht
(
x
~
0
));
eauto
.
+
apply
IHr
;
try
apply
(
λ
x
,
Ht
(
x
~
1
));
eauto
.
Qed
.
Lemma
PNode_lookup
{
A
}
o
(
l
r
:
Pmap_raw
A
)
i
:
PNode'
o
l
r
!!
i
=
PNode
o
l
r
!!
i
.
Proof
.
by
destruct
i
,
o
,
l
,
r
.
Qed
.
Fixpoint
Psingleton_raw
{
A
}
(
i
:
positive
)
(
x
:
A
)
:
Pmap_raw
A
:=
match
i
with
|
1
=>
PNode
PLeaf
(
Some
x
)
PLeaf
|
i
~
0
=>
PNode
(
Psingleton_raw
i
x
)
None
PLeaf
|
i
~
1
=>
PNode
PLeaf
None
(
Psingleton_raw
i
x
)
end
.
Lemma
Psingleton_ne
{
A
}
i
(
x
:
A
)
:
Pmap_ne
(
Psingleton_raw
i
x
)
.
Proof
.
induction
i
;
simpl
;
intuition
.
Qed
.
Local
Hint
Resolve
Psingleton_ne
.
Lemma
Psingleton_wf
{
A
}
i
(
x
:
A
)
:
Pmap_wf
(
Psingleton_raw
i
x
)
.
Proof
.
induction
i
;
simpl
;
intuition
.
Qed
.
Local
Hint
Resolve
Psingleton_wf
.
Proof
.
induction
i
as
[[]|[]|];
simpl
;
rewrite
?andb_true_r
;
auto
.
Qed
.
Lemma
Ppartial_alter_wf
{
A
}
f
i
(
t
:
Pmap_raw
A
)
:
Pmap_wf
t
→
Pmap_wf
(
Ppartial_alter_raw
f
i
t
)
.
Proof
.
revert
i
;
induction
t
as
[|
o
l
IHl
r
IHr
];
intros
i
?;
simpl
.
*
destruct
(
f
None
);
auto
using
Psingleton_wf
.
*
destruct
i
;
simpl
;
eauto
.
Qed
.
Lemma
Pfmap_wf
{
A
B
}
(
f
:
A
→
B
)
t
:
Pmap_wf
t
→
Pmap_wf
(
Pfmap_raw
f
t
)
.
Proof
.
induction
t
as
[|[
x
|]
[]
?
[]
?];
simpl
in
*
;
rewrite
?andb_True
;
intuition
.
Qed
.
Lemma
Pomap_wf
{
A
B
}
(
f
:
A
→
option
B
)
t
:
Pmap_wf
t
→
Pmap_wf
(
Pomap_raw
f
t
)
.
Proof
.
induction
t
;
simpl
;
eauto
.
Qed
.
Lemma
Pmerge_wf
{
A
B
C
}
(
f
:
option
A
→
option
B
→
option
C
)
t1
t2
:
Pmap_wf
t1
→
Pmap_wf
t2
→
Pmap_wf
(
Pmerge_raw
f
t1
t2
)
.
Proof
.
revert
t2
.
induction
t1
;
intros
[];
simpl
;
eauto
using
Pomap_wf
.
Qed
.
Lemma
Plookup_empty
{
A
}
i
:
(
∅
:
Pmap_raw
A
)
!!
i
=
None
.
Proof
.
by
destruct
i
.
Qed
.
Lemma
Plookup_singleton
{
A
}
i
(
x
:
A
)
:
Psingleton_raw
i
x
!!
i
=
Some
x
.
Proof
.
by
induction
i
.
Qed
.
Lemma
Plookup_singleton_ne
{
A
}
i
j
(
x
:
A
)
:
i
≠
j
→
Psingleton_raw
i
x
!!
j
=
None
.
Proof
.
revert
j
.
induction
i
;
intros
[?|?|];
simpl
;
auto
.
congruence
.
Qed
.
Definition
PNode_canon
{
A
}
(
l
:
Pmap_raw
A
)
(
o
:
option
A
)
(
r
:
Pmap_raw
A
)
:=
match
l
,
o
,
r
with
PLeaf
,
None
,
PLeaf
=>
PLeaf
|
_,
_,
_
=>
PNode
l
o
r
end
.
Lemma
PNode_canon_wf
{
A
}
(
l
:
Pmap_raw
A
)
(
o
:
option
A
)
(
r
:
Pmap_raw
A
)
:
Pmap_wf
l
→
Pmap_wf
r
→
Pmap_wf
(
PNode_canon
l
o
r
)
.
Proof
.
intros
H1
H2
.
destruct
H1
,
o
,
H2
;
simpl
;
intuition
.
Qed
.
Local
Hint
Resolve
PNode_canon_wf
.
Lemma
PNode_canon_lookup_xH
{
A
}
(
l
:
Pmap_raw
A
)
o
(
r
:
Pmap_raw
A
)
:
PNode_canon
l
o
r
!!
1
=
o
.
Proof
.
by
destruct
l
,
o
,
r
.
Qed
.
Lemma
PNode_canon_lookup_xO
{
A
}
(
l
:
Pmap_raw
A
)
o
(
r
:
Pmap_raw
A
)
i
:
PNode_canon
l
o
r
!!
i
~
0
=
l
!!
i
.
Proof
.
by
destruct
l
,
o
,
r
.
Qed
.
Lemma
PNode_canon_lookup_xI
{
A
}
(
l
:
Pmap_raw
A
)
o
(
r
:
Pmap_raw
A
)
i
:
PNode_canon
l
o
r
!!
i
~
1
=
r
!!
i
.
Proof
.
by
destruct
l
,
o
,
r
.
Qed
.
Ltac
PNode_canon_rewrite
:=
repeat
first
[
rewrite
PNode_canon_lookup_xH
|
rewrite
PNode_canon_lookup_xO
|
rewrite
PNode_canon_lookup_xI
]
.
Instance
Ppartial_alter_raw
{
A
}
:
PartialAlter
positive
A
(
Pmap_raw
A
)
:=
fix
go
f
i
t
{
struct
t
}
:
Pmap_raw
A
:=
match
t
with
|
PLeaf
=>
match
f
None
with
None
=>
PLeaf
|
Some
x
=>
Psingleton_raw
i
x
end
|
PNode
l
o
r
=>
match
i
with
|
1
=>
PNode_canon
l
(
f
o
)
r
|
i
~
0
=>
PNode_canon
(
@
partial_alter
_
_
_
go
f
i
l
)
o
r
|
i
~
1
=>
PNode_canon
l
o
(
@
partial_alter
_
_
_
go
f
i
r
)
end
end
.
Lemma
Ppartial_alter_wf
{
A
}
f
i
(
t
:
Pmap_raw
A
)
:
Pmap_wf
t
→
Pmap_wf
(
partial_alter
f
i
t
)
.
Proof
.
intros
twf
.
revert
i
.
induction
twf
.
*
unfold
partial_alter
.
simpl
.
case
(
f
None
);
intuition
.
*
intros
[?|?|];
simpl
;
intuition
.
*
intros
[?|?|];
simpl
;
intuition
.
Qed
.
Instance
Ppartial_alter
{
A
}
:
PartialAlter
positive
A
(
Pmap
A
)
:=
λ
f
i
m
,
PMap'
(
partial_alter
f
i
(
pmap_car
m
))
(
Ppartial_alter_wf
f
i
_
(
pmap_prf
m
))
.
Proof
.
revert
j
.
induction
i
;
intros
[?|?|];
simpl
;
auto
with
congruence
.
Qed
.
Lemma
Plookup_alter
{
A
}
f
i
(
t
:
Pmap_raw
A
)
:
partial_alter
f
i
t
!!
i
=
f
(
t
!!
i
)
.
P
partial_alter
_raw
f
i
t
!!
i
=
f
(
t
!!
i
)
.
Proof
.
revert
i
.
induction
t
.
*
intros
i
.
change
(
match
f
None
with
Some
x
=>
Psingleton_raw
i
x
|
None
=>
PLeaf
end
!!
i
=
f
None
);
destruct
(
f
None
)
.
+
intros
.
apply
Plookup_singleton
.
+
by
destruct
i
.
*
intros
[?|?|];
simpl
;
by
PNode_canon_rewrite
.
revert
i
;
induction
t
as
[|
o
l
IHl
r
IHr
];
intros
i
;
simpl
.
*
by
destruct
(
f
None
);
rewrite
?Plookup_singleton
.
*
destruct
i
;
simpl
;
rewrite
PNode_lookup
;
simpl
;
auto
.
Qed
.
Lemma
Plookup_alter_ne
{
A
}
f
i
j
(
t
:
Pmap_raw
A
)
:
i
≠
j
→
partial_alter
f
i
t
!!
j
=
t
!!
j
.
i
≠
j
→
P
partial_alter
_raw
f
i
t
!!
j
=
t
!!
j
.
Proof
.
revert
i
j
.
induction
t
as
[|
l
IHl
?
r
IHr
]
.
*
intros
.
change
(
match
f
None
with
Some
x
=>
Psingleton_raw
i
x
|
None
=>
PLeaf
end
!!
j
=
None
);
destruct
(
f
None
);
[|
done
]
.
intros
.
by
apply
Plookup_singleton_ne
.
*
intros
[?|?|]
[?|?|];
simpl
;
PNode_canon_rewrite
;
auto
;
congruence
.
revert
i
j
;
induction
t
as
[|
o
l
IHl
r
IHr
];
simpl
.
*
by
intros
;
destruct
(
f
None
);
rewrite
?Plookup_singleton_ne
.
*
by
intros
[?|?|]
[?|?|]
?;
simpl
;
rewrite
?PNode_lookup
;
simpl
;
auto
.
Qed
.
Instance
Pfmap_raw
:
FMap
Pmap_raw
:=
λ
A
B
f
,
fix
go
t
:=
match
t
with
|
PLeaf
=>
PLeaf
|
PNode
l
x
r
=>
PNode
(
go
l
)
(
f
<$>
x
)
(
go
r
)
end
.
Lemma
Pfmap_ne
`
(
f
:
A
→
B
)
(
t
:
Pmap_raw
A
)
:
Pmap_ne
t
→
Pmap_ne
(
fmap
f
t
)
.
Proof
.
induction
1
;
csimpl
;
auto
.
Qed
.
Local
Hint
Resolve
Pfmap_ne
.
Lemma
Pfmap_wf
`
(
f
:
A
→
B
)
(
t
:
Pmap_raw
A
)
:
Pmap_wf
t
→
Pmap_wf
(
fmap
f
t
)
.
Proof
.
induction
1
;
csimpl
;
intuition
.
Qed
.
Global
Instance
Pfmap
:
FMap
Pmap
:=
λ
A
B
f
m
,
PMap'
(
f
<$>
pmap_car
m
)
(
Pfmap_wf
f
_
(
pmap_prf
m
))
.
Lemma
Plookup_fmap
{
A
B
}
(
f
:
A
→
B
)
(
t
:
Pmap_raw
A
)
i
:
(
f
<$>
t
)
!!
i
=
f
<$>
t
!!
i
.
Proof
.
revert
i
.
induction
t
.
done
.
by
intros
[?|?|];
simpl
.
Qed
.
Fixpoint
Pto_list_raw
{
A
}
(
j
:
positive
)
(
t
:
Pmap_raw
A
)
(
acc
:
list
(
positive
*
A
))
:
list
(
positive
*
A
)
:=
match
t
with
|
PLeaf
=>
acc
|
PNode
l
o
r
=>
default
[]
o
(
λ
x
,
[(
Preverse
j
,
x
)])
++
Pto_list_raw
(
j
~
0
)
l
(
Pto_list_raw
(
j
~
1
)
r
acc
)
end
%
list
.
Lemma
Plookup_fmap
{
A
B
}
(
f
:
A
→
B
)
t
i
:
(
Pfmap_raw
f
t
)
!!
i
=
f
<$>
t
!!
i
.
Proof
.
revert
i
.
by
induction
t
;
intros
[?|?|];
simpl
.
Qed
.
Lemma
Pelem_of_to_list
{
A
}
(
t
:
Pmap_raw
A
)
j
i
acc
x
:
(
i
,
x
)
∈
Pto_list_raw
j
t
acc
↔
(
∃
i'
,
i
=
i'
++
Preverse
j
∧
t
!!
i'
=
Some
x
)
∨
(
i
,
x
)
∈
acc
.
Proof
.
split
.
{
revert
j
acc
.
induction
t
as
[|
l
IHl
[
y
|]
r
IHr
];
intros
j
acc
;
simpl
.
{
revert
j
acc
.
induction
t
as
[|
[
y
|]
l
IHl
r
IHr
];
intros
j
acc
;
simpl
.
*
by
right
.
*
rewrite
elem_of_cons
.
intros
[?|?];
simplify_equality
.
{
left
;
exists
1
.
by
rewrite
(
left_id_L
1
(
++
))
%
positive
.
}
...
...
@@ -271,10 +188,10 @@ Proof.
left
;
exists
(
i'
~
1
)
.
by
rewrite
Preverse_xI
,
(
associative_L
_)
.
}
revert
t
j
i
acc
.
assert
(
∀
t
j
i
acc
,
(
i
,
x
)
∈
acc
→
(
i
,
x
)
∈
Pto_list_raw
j
t
acc
)
as
help
.
{
intros
t
;
induction
t
as
[|
l
IHl
[
y
|]
r
IHr
];
intros
j
i
acc
;
{
intros
t
;
induction
t
as
[|
[
y
|]
l
IHl
r
IHr
];
intros
j
i
acc
;
simpl
;
rewrite
?elem_of_cons
;
auto
.
}
intros
t
j
?
acc
[(
i
&
->
&
Hi
)|?];
[|
by
auto
]
.
revert
j
i
acc
Hi
.
induction
t
as
[|
l
IHl
[
y
|]
r
IHr
];
intros
j
i
acc
?;
simpl
.
induction
t
as
[|
[
y
|]
l
IHl
r
IHr
];
intros
j
i
acc
?;
simpl
.
*
done
.
*
rewrite
elem_of_cons
.
destruct
i
as
[
i
|
i
|];
simplify_equality'
.
+
right
.
apply
help
.
specialize
(
IHr
(
j
~
1
)
i
)
.
...
...
@@ -292,7 +209,7 @@ Lemma Pto_list_nodup {A} j (t : Pmap_raw A) acc :
(
∀
i
x
,
(
i
++
Preverse
j
,
x
)
∈
acc
→
t
!!
i
=
None
)
→
NoDup
acc
→
NoDup
(
Pto_list_raw
j
t
acc
)
.
Proof
.
revert
j
acc
.
induction
t
as
[|
l
IHl
[
y
|]
r
IHr
];
simpl
;
intros
j
acc
Hin
?
.
revert
j
acc
.
induction
t
as
[|
[
y
|]
l
IHl
r
IHr
];
simpl
;
intros
j
acc
Hin
?
.
*
done
.
*
repeat
constructor
.
{
rewrite
Pelem_of_to_list
.
intros
[(
i
&
Hi
&
?)|
Hj
]
.
...
...
@@ -318,60 +235,59 @@ Proof.
apply
IHr
;
auto
.
intros
i
x
Hi
.
apply
(
Hin
(
i
~
1
)
x
)
.
by
rewrite
Preverse_xI
,
(
associative_L
_)
in
Hi
.
Qed
.
Global
Instance
Pto_list
{
A
}
:
FinMapToList
positive
A
(
Pmap
A
)
:=
λ
m
,
Pto_list_raw
1
(
pmap_car
m
)
[]
.
Instance
Pomap_raw
:
OMap
Pmap_raw
:=
λ
A
B
f
,
fix
go
t
:=
match
t
with
|
PLeaf
=>
PLeaf
|
PNode
l
o
r
=>
PNode_canon
(
go
l
)
(
o
≫=
f
)
(
go
r
)
end
.
Lemma
Pomap_wf
{
A
B
}
(
f
:
A
→
option
B
)
(
t
:
Pmap_raw
A
)
:
Pmap_wf
t
→
Pmap_wf
(
omap
f
t
)
.
Proof
.
induction
1
;
csimpl
;
auto
.
Qed
.
Local
Hint
Resolve
Pomap_wf
.
Lemma
Pomap_lookup
{
A
B
}
(
f
:
A
→
option
B
)
(
t
:
Pmap_raw
A
)
i
:
omap
f
t
!!
i
=
t
!!
i
≫=
f
.
Lemma
Pomap_lookup
{
A
B
}
(
f
:
A
→
option
B
)
t
i
:
Pomap_raw
f
t
!!
i
=
t
!!
i
≫=
f
.
Proof
.
revert
i
.
induction
t
as
[|
l
IHl
o
r
IHr
];
[
done
|]
.
intros
[?|?|];
csimpl
;
PNode_canon_rewrite
;
auto
.
revert
i
.
induction
t
as
[|
o
l
IHl
r
IHr
];
intros
[
i
|
i
|];
simpl
;
rewrite
?PNode_lookup
;
simpl
;
auto
.
Qed
.
Lemma
Pmerge_lookup
{
A
B
C
}
(
f
:
option
A
→
option
B
→
option
C
)
(
Hf
:
f
None
None
=
None
)
t1
t2
i
:
Pmerge_raw
f
t1
t2
!!
i
=
f
(
t1
!!
i
)
(
t2
!!
i
)
.
Proof
.
revert
t2
i
;
induction
t1
as
[|
o1
l1
IHl1
r1
IHr1
];
intros
t2
i
;
simpl
.
{
rewrite
Pomap_lookup
.
by
destruct
(
t2
!!
i
)
.
}
unfold
compose
,
flip
.
destruct
t2
as
[|
l2
o2
r2
];
rewrite
PNode_lookup
.
*
by
destruct
i
;
rewrite
?Pomap_lookup
;
simpl
;
rewrite
?Pomap_lookup
;
match
goal
with
|
-
?o
≫=
_
=
_
=>
destruct
o
end
.
*
destruct
i
;
rewrite
?Pomap_lookup
;
simpl
;
auto
.
Qed
.
Global
Instance
Pomap
:
OMap
Pmap
:=
λ
A
B
f
m
,
PMap'
(
omap
f
(
pmap_car
m
))
(
Pomap_wf
f
_
(
pmap_prf
m
))
.
Instance
Pmerge_raw
:
Merge
Pmap_raw
:=
fix
Pmerge_raw
A
B
C
f
t1
t2
:
Pmap_raw
C
:=
match
t1
,
t2
with
|
PLeaf
,
t2
=>
omap
(
f
None
∘
Some
)
t2
|
t1
,
PLeaf
=>
omap
(
flip
f
None
∘
Some
)
t1
|
PNode
l1
o1
r1
,
PNode
l2
o2
r2
=>
PNode_canon
(
@
merge
_
Pmerge_raw
A
B
C
f
l1
l2
)
(
f
o1
o2
)
(
@
merge
_
Pmerge_raw
A
B
C
f
r1
r2
)
end
.
Local
Arguments
omap
_
_
_
_
_
_
:
simpl
never
.
Lemma
Pmerge_wf
{
A
B
C
}
(
f
:
option
A
→
option
B
→
option
C
)
t1
t2
:
Pmap_wf
t1
→
Pmap_wf
t2
→
Pmap_wf
(
merge
f
t1
t2
)
.
Proof
.
intros
t1wf
.
revert
t2
.
induction
t1wf
;
destruct
1
;
simpl
;
auto
.
Qed
.
Global
Instance
Pmerge
:
Merge
Pmap
:=
λ
A
B
C
f
m1
m2
,
PMap'
_
(
Pmerge_wf
f
_
_
(
pmap_prf
m1
)
(
pmap_prf
m2
))
.
Lemma
Pmerge_spec
{
A
B
C
}
(
f
:
option
A
→
option
B
→
option
C
)
(
Hf
:
f
None
None
=
None
)
(
t1
:
Pmap_raw
A
)
t2
i
:
merge
f
t1
t2
!!
i
=
f
(
t1
!!
i
)
(
t2
!!
i
)
.
(** Packed version and instance of the finite map type class *)
Inductive
Pmap
(
A
:
Type
)
:
Type
:=
PMap
{
pmap_car
:
Pmap_raw
A
;
pmap_prf
:
Pmap_wf
pmap_car
}
.
Arguments
PMap
{_}
_
_
.
Arguments
pmap_car
{_}
_
.
Arguments
pmap_prf
{_}
_
.
Lemma
Pmap_eq
{
A
}
(
m1
m2
:
Pmap
A
)
:
m1
=
m2
↔
pmap_car
m1
=
pmap_car
m2
.
Proof
.
revert
t2
i
.
induction
t1
as
[|
l1
IHl1
o1
r1
IHr1
];
intros
t2
i
.
{
unfold
merge
;
simpl
.
rewrite
Pomap_lookup
.
by
destruct
(
t2
!!
i
)
.
}
destruct
t2
as
[|
l2
o2
r2
]
.
*
unfold
merge
,
Pmerge_raw
.
rewrite
Pomap_lookup
.
by
destruct
(
PNode
_
_
_
!!
i
)
.
*
destruct
i
;
simpl
;
by
PNode_canon_rewrite
.
split
;
[
by
intros
->
|
intros
];
destruct
m1
as
[
t1
?],
m2
as
[
t2
?]
.
simplify_equality'
;
f_equal
;
apply
proof_irrel
.
Qed
.
Instance
Pmap_eq_dec
`{
∀
x
y
:
A
,
Decision
(
x
=
y
)}
(
m1
m2
:
Pmap
A
)
:
Decision
(
m1
=
m2
)
:=
match
Pmap_raw_eq_dec
(
pmap_car
m1
)
(
pmap_car
m2
)
with
|
left
H
=>
left
(
proj2
(
Pmap_eq
m1
m2
)
H
)
|
right
H
=>
right
(
H
∘
proj1
(
Pmap_eq
m1
m2
))
end
.
Instance
Pempty
{
A
}
:
Empty
(
Pmap
A
)
:=
PMap
∅
I
.
Instance
Plookup
{
A
}
:
Lookup
positive
A
(
Pmap
A
)
:=
λ
i
m
,
pmap_car
m
!!
i
.
Instance
Ppartial_alter
{
A
}
:
PartialAlter
positive
A
(
Pmap
A
)
:=
λ
f
i
m
,
PMap
(
partial_alter
f
i
(
pmap_car
m
))
(
Ppartial_alter_wf
f
i
_
(
pmap_prf
m
))
.
Instance
Pfmap
:
FMap
Pmap
:=
λ
A
B
f
m
,
PMap
(
f
<$>
pmap_car
m
)
(
Pfmap_wf
f
_
(
pmap_prf
m
))
.
Instance
Pto_list
{
A
}
:
FinMapToList
positive
A
(
Pmap
A
)
:=
λ
m
,
Pto_list_raw
1
(
pmap_car
m
)
[]
.
Instance
Pomap
:
OMap
Pmap
:=
λ
A
B
f
m
,
PMap
(
omap
f
(
pmap_car
m
))
(
Pomap_wf
f
_
(
pmap_prf
m
))
.
Instance
Pmerge
:
Merge
Pmap
:=
λ
A
B
C
f
m1
m2
,
PMap
_
(
Pmerge_wf
f
_
_
(
pmap_prf
m1
)
(
pmap_prf
m2
))
.
(** * Instantiation of the finite map interface *)
Global
Instance
:
FinMap
positive
Pmap
.
Instance
Pmap_finmap
:
FinMap
positive
Pmap
.
Proof
.
split
.
*
intros
?
[
t1
?]
[
t2
?]
?
.
apply
Pmap_eq
;
simpl
.
apply
Pmap_wf_eq_get
;
trivial
;
by
apply
(
bool_decide_unpack
_)
.
*
by
intros
?
[
t1
?]
[
t2
?]
?;
apply
Pmap_eq
,
Pmap_wf_eq
.
*
by
intros
?
[]
.
*
intros
??
[??]
?
.
by
apply
Plookup_alter
.
*
intros
??
[??]
??
.
by
apply
Plookup_alter_ne
.
...
...
@@ -382,7 +298,7 @@ Proof.
rewrite
Pelem_of_to_list
,
elem_of_nil
.
split
.
by
intros
[(?
&
->
&
?)|]
.
by
left
;
exists
i
.
*
intros
??
?
[??]
?
.
by
apply
Pomap_lookup
.
*
intros
???
??
[??]
[??]
?
.
by
apply
Pmerge_
spec
.
*
intros
???
??
[??]
[??]
?
.
by
apply
Pmerge_
lookup
.
Qed
.
(** * Finite sets *)
...
...
@@ -394,12 +310,12 @@ Instance: FinMapDom positive Pmap Pset := mapset_dom_spec.
(** * Fresh numbers *)
Fixpoint
Pdepth
{
A
}
(
m
:
Pmap_raw
A
)
:
nat
:=
match
m
with
|
PLeaf
|
PNode
_
None
_
=>
O
|
PNode
l
_
_
=>
S
(
Pdepth
l
)
|
PLeaf
|
PNode
None
_
_
=>
O
|
PNode
_
l
_
=>
S
(
Pdepth
l
)
end
.
Fixpoint
Pfresh_at_depth
{
A
}
(
m
:
Pmap_raw
A
)
(
d
:
nat
)
:
option
positive
:=
match
d
,
m
with
|
O
,
(
PLeaf
|
PNode
_
None
_)
=>
Some
1
|
S
d
,
PNode
l
_
r
=>
|
O
,
(
PLeaf
|
PNode
None
_
_)
=>
Some
1
|
S
d
,
PNode
_
l
r
=>
match
Pfresh_at_depth
l
d
with
|
Some
i
=>
Some
(
i
~
0
)
|
None
=>
(
~
1
)
<$>
Pfresh_at_depth
r
d
end
...
...
@@ -423,8 +339,8 @@ Lemma Pfresh_at_depth_fresh {A} (m : Pmap_raw A) d i :
Pfresh_at_depth
m
d
=
Some
i
→
m
!!
i
=
None
.
Proof
.
revert
i
m
;
induction
d
as
[|
d
IH
]
.
{
intros
i
[|
l
[]
r
]
?;
naive_solver
.
}
intros
i
[|
l
o
r
]
?;
simplify_equality'
.
{
intros
i
[|[]
l
r
]
?;
naive_solver
.
}
intros
i
[|
o
l
r
]
?;
simplify_equality'
.
destruct
(
Pfresh_at_depth
l
d
)
as
[
i'
|]
eqn
:?,
(
Pfresh_at_depth
r
d
)
as
[
i''
|]
eqn
:?;
simplify_equality'
;
auto
.
Qed
.
...
...
@@ -436,7 +352,7 @@ Proof.
Qed
.
Lemma
Pfresh_depth
{
A
}
(
m
:
Pmap_raw
A
)
:
m
!!
Pos
.
shiftl_nat
1
(
Pdepth
m
)
=
None
.
Proof
.
induction
m
as
[|
l
IHl
[
x
|]
r
IHr
];
auto
.
Qed
.
Proof
.
induction
m
as
[|
[
x
|]
l
IHl
r
IHr
];
auto
.
Qed
.
Lemma
Pfresh_fresh
{
A
}
(
m
:
Pmap
A
)
:
m
!!
Pfresh
m
=
None
.
Proof
.
destruct
m
as
[
m
?];
unfold
lookup
,
Plookup
,
Pfresh
;
simpl
.
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment