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
c95faa0d
Commit
c95faa0d
authored
9 years ago
by
Robbert Krebbers
Browse files
Options
Downloads
Patches
Plain Diff
Finite/cofinite sets of positive binary naturals
parent
de801e30
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
theories/co_pset.v
+270
-0
270 additions, 0 deletions
theories/co_pset.v
with
270 additions
and
0 deletions
theories/co_pset.v
0 → 100644
+
270
−
0
View file @
c95faa0d
(* Copyright (c) 2012-2015, Robbert Krebbers. *)
(* This file is distributed under the terms of the BSD license. *)
(** This files implements an efficient implementation of finite/cofinite sets
of positive binary naturals [positive]. *)
Require
Export
prelude
.
collections
.
Require
Import
prelude
.
pmap
prelude
.
mapset
.
Local
Open
Scope
positive_scope
.
(** * The tree data structure *)
Inductive
coPset_raw
:=
|
coPLeaf
:
bool
→
coPset_raw
|
coPNode
:
bool
→
coPset_raw
→
coPset_raw
→
coPset_raw
.
Instance
coPset_raw_eq_dec
(
t1
t2
:
coPset_raw
)
:
Decision
(
t1
=
t2
)
.
Proof
.
solve_decision
.
Defined
.
Fixpoint
coPset_wf
(
t
:
coPset_raw
)
:
bool
:=
match
t
with
|
coPLeaf
_
=>
true
|
coPNode
true
(
coPLeaf
true
)
(
coPLeaf
true
)
=>
false
|
coPNode
false
(
coPLeaf
false
)
(
coPLeaf
false
)
=>
false
|
coPNode
b
l
r
=>
coPset_wf
l
&&
coPset_wf
r
end
.
Arguments
coPset_wf
!
_
/
:
simpl
nomatch
.
Lemma
coPNode_wf_l
b
l
r
:
coPset_wf
(
coPNode
b
l
r
)
→
coPset_wf
l
.
Proof
.
destruct
b
,
l
as
[[]|],
r
as
[[]|];
simpl
;
rewrite
?andb_True
;
tauto
.
Qed
.
Lemma
coPNode_wf_r
b
l
r
:
coPset_wf
(
coPNode
b
l
r
)
→
coPset_wf
r
.
Proof
.
destruct
b
,
l
as
[[]|],
r
as
[[]|];
simpl
;
rewrite
?andb_True
;
tauto
.
Qed
.
Local
Hint
Immediate
coPNode_wf_l
coPNode_wf_r
.
Definition
coPNode'
(
b
:
bool
)
(
l
r
:
coPset_raw
)
:
coPset_raw
:=
match
b
,
l
,
r
with
|
true
,
coPLeaf
true
,
coPLeaf
true
=>
coPLeaf
true
|
false
,
coPLeaf
false
,
coPLeaf
false
=>
coPLeaf
false
|
_,
_,
_
=>
coPNode
b
l
r
end
.
Arguments
coPNode'
_
_
_
:
simpl
never
.
Lemma
coPNode_wf
b
l
r
:
coPset_wf
l
→
coPset_wf
r
→
coPset_wf
(
coPNode'
b
l
r
)
.
Proof
.
destruct
b
,
l
as
[[]|],
r
as
[[]|];
simpl
;
auto
.
Qed
.
Hint
Resolve
coPNode_wf
.
Fixpoint
coPset_elem_of_raw
(
p
:
positive
)
(
t
:
coPset_raw
)
{
struct
t
}
:
bool
:=
match
t
,
p
with
|
coPLeaf
b
,
_
=>
b
|
coPNode
b
l
r
,
1
=>
b
|
coPNode
_
l
_,
p
~
0
=>
coPset_elem_of_raw
p
l
|
coPNode
_
_
r
,
p
~
1
=>
coPset_elem_of_raw
p
r
end
.
Local
Notation
e_of
:=
coPset_elem_of_raw
.
Arguments
coPset_elem_of_raw
_
!
_
/
:
simpl
nomatch
.
Lemma
coPset_elem_of_coPNode'
b
l
r
p
:
e_of
p
(
coPNode'
b
l
r
)
=
e_of
p
(
coPNode
b
l
r
)
.
Proof
.
by
destruct
p
,
b
,
l
as
[[]|],
r
as
[[]|]
.
Qed
.
Lemma
coPLeaf_wf
t
b
:
(
∀
p
,
e_of
p
t
=
b
)
→
coPset_wf
t
→
t
=
coPLeaf
b
.
Proof
.
induction
t
as
[
b'
|
b'
l
IHl
r
IHr
];
intros
Ht
?;
[
f_equal
;
apply
(
Ht
1
)|]
.
assert
(
b'
=
b
)
by
(
apply
(
Ht
1
));
subst
.
assert
(
l
=
coPLeaf
b
)
as
->
by
(
apply
IHl
;
try
apply
(
λ
p
,
Ht
(
p
~
0
));
eauto
)
.
assert
(
r
=
coPLeaf
b
)
as
->
by
(
apply
IHr
;
try
apply
(
λ
p
,
Ht
(
p
~
1
));
eauto
)
.
by
destruct
b
.
Qed
.
Lemma
coPset_eq
t1
t2
:
(
∀
p
,
e_of
p
t1
=
e_of
p
t2
)
→
coPset_wf
t1
→
coPset_wf
t2
→
t1
=
t2
.
Proof
.
revert
t2
.
induction
t1
as
[
b1
|
b1
l1
IHl
r1
IHr
];
intros
[
b2
|
b2
l2
r2
]
Ht
??;
simpl
in
*.
*
f_equal
;
apply
(
Ht
1
)
.
*
by
discriminate
(
coPLeaf_wf
(
coPNode
b2
l2
r2
)
b1
)
.
*
by
discriminate
(
coPLeaf_wf
(
coPNode
b1
l1
r1
)
b2
)
.
*
f_equal
;
[
apply
(
Ht
1
)|
|]
.
+
apply
IHl
;
try
apply
(
λ
x
,
Ht
(
x
~
0
));
eauto
.
+
apply
IHr
;
try
apply
(
λ
x
,
Ht
(
x
~
1
));
eauto
.
Qed
.
Fixpoint
coPset_singleton_raw
(
p
:
positive
)
:
coPset_raw
:=
match
p
with
|
1
=>
coPNode
true
(
coPLeaf
false
)
(
coPLeaf
false
)
|
p
~
0
=>
coPNode'
false
(
coPset_singleton_raw
p
)
(
coPLeaf
false
)
|
p
~
1
=>
coPNode'
false
(
coPLeaf
false
)
(
coPset_singleton_raw
p
)
end
.
Instance
coPset_union_raw
:
Union
coPset_raw
:=
fix
go
t1
t2
:=
let
_
:
Union
_
:=
@
go
in
match
t1
,
t2
with
|
coPLeaf
false
,
coPLeaf
false
=>
coPLeaf
false
|
_,
coPLeaf
true
=>
coPLeaf
true
|
coPLeaf
true
,
_
=>
coPLeaf
true
|
coPNode
b
l
r
,
coPLeaf
false
=>
coPNode'
b
l
r
|
coPLeaf
false
,
coPNode
b
l
r
=>
coPNode'
b
l
r
|
coPNode
b1
l1
r1
,
coPNode
b2
l2
r2
=>
coPNode'
(
b1
||
b2
)
(
l1
∪
l2
)
(
r1
∪
r2
)
end
.
Local
Arguments
union
_
_
!
_
!
_
/.
Instance
coPset_intersection_raw
:
Intersection
coPset_raw
:=
fix
go
t1
t2
:=
let
_
:
Intersection
_
:=
@
go
in
match
t1
,
t2
with
|
coPLeaf
true
,
coPLeaf
true
=>
coPLeaf
true
|
_,
coPLeaf
false
=>
coPLeaf
false
|
coPLeaf
false
,
_
=>
coPLeaf
false
|
coPNode
b
l
r
,
coPLeaf
true
=>
coPNode'
b
l
r
|
coPLeaf
true
,
coPNode
b
l
r
=>
coPNode'
b
l
r
|
coPNode
b1
l1
r1
,
coPNode
b2
l2
r2
=>
coPNode'
(
b1
&&
b2
)
(
l1
∩
l2
)
(
r1
∩
r2
)
end
.
Local
Arguments
intersection
_
_
!
_
!
_
/.
Fixpoint
coPset_opp_raw
(
t
:
coPset_raw
)
:
coPset_raw
:=
match
t
with
|
coPLeaf
b
=>
coPLeaf
(
negb
b
)
|
coPNode
b
l
r
=>
coPNode'
(
negb
b
)
(
coPset_opp_raw
l
)
(
coPset_opp_raw
r
)
end
.
Lemma
coPset_singleton_wf
p
:
coPset_wf
(
coPset_singleton_raw
p
)
.
Proof
.
induction
p
;
simpl
;
eauto
.
Qed
.
Lemma
coPset_union_wf
t1
t2
:
coPset_wf
t1
→
coPset_wf
t2
→
coPset_wf
(
t1
∪
t2
)
.
Proof
.
revert
t2
;
induction
t1
as
[[]|[]];
intros
[[]|[]
??];
simpl
;
eauto
.
Qed
.
Lemma
coPset_intersection_wf
t1
t2
:
coPset_wf
t1
→
coPset_wf
t2
→
coPset_wf
(
t1
∩
t2
)
.
Proof
.
revert
t2
;
induction
t1
as
[[]|[]];
intros
[[]|[]
??];
simpl
;
eauto
.
Qed
.
Lemma
coPset_opp_wf
t
:
coPset_wf
(
coPset_opp_raw
t
)
.
Proof
.
induction
t
as
[[]|[]];
simpl
;
eauto
.
Qed
.
Lemma
elem_of_coPset_singleton
p
q
:
e_of
p
(
coPset_singleton_raw
q
)
↔
p
=
q
.
Proof
.
split
;
[|
by
intros
<-
;
induction
p
;
simpl
;
rewrite
?coPset_elem_of_coPNode'
]
.
by
revert
q
;
induction
p
;
intros
[?|?|];
simpl
;
rewrite
?coPset_elem_of_coPNode'
;
intros
;
f_equal'
;
auto
.
Qed
.
Lemma
elem_of_coPset_union
t1
t2
p
:
e_of
p
(
t1
∪
t2
)
=
e_of
p
t1
||
e_of
p
t2
.
Proof
.
by
revert
t2
p
;
induction
t1
as
[[]|[]];
intros
[[]|[]
??]
[?|?|];
simpl
;
rewrite
?coPset_elem_of_coPNode'
;
simpl
;
rewrite
?orb_true_l
,
?orb_false_l
,
?orb_true_r
,
?orb_false_r
.
Qed
.
Lemma
elem_of_coPset_intersection
t1
t2
p
:
e_of
p
(
t1
∩
t2
)
=
e_of
p
t1
&&
e_of
p
t2
.
Proof
.
by
revert
t2
p
;
induction
t1
as
[[]|[]];
intros
[[]|[]
??]
[?|?|];
simpl
;
rewrite
?coPset_elem_of_coPNode'
;
simpl
;
rewrite
?andb_true_l
,
?andb_false_l
,
?andb_true_r
,
?andb_false_r
.
Qed
.
Lemma
elem_of_coPset_opp
t
p
:
e_of
p
(
coPset_opp_raw
t
)
=
negb
(
e_of
p
t
)
.
Proof
.
by
revert
p
;
induction
t
as
[[]|[]];
intros
[?|?|];
simpl
;
rewrite
?coPset_elem_of_coPNode'
;
simpl
.
Qed
.
(** * Packed together + set operations *)
Definition
coPset
:=
{
t
|
coPset_wf
t
}
.
Instance
coPset_singleton
:
Singleton
positive
coPset
:=
λ
p
,
coPset_singleton_raw
p
↾
coPset_singleton_wf
_
.
Instance
coPset_elem_of
:
ElemOf
positive
coPset
:=
λ
p
X
,
e_of
p
(
`
X
)
.
Instance
coPset_empty
:
Empty
coPset
:=
coPLeaf
false
↾
I
.
Definition
coPset_all
:
coPset
:=
coPLeaf
true
↾
I
.
Instance
coPset_union
:
Union
coPset
:=
λ
X
Y
,
(
`
X
∪
`
Y
)
↾
coPset_union_wf
_
_
(
proj2_sig
X
)
(
proj2_sig
Y
)
.
Instance
coPset_intersection
:
Intersection
coPset
:=
λ
X
Y
,
(
`
X
∩
`
Y
)
↾
coPset_intersection_wf
_
_
(
proj2_sig
X
)
(
proj2_sig
Y
)
.
Instance
coPset_difference
:
Difference
coPset
:=
λ
X
Y
,
(
`
X
∩
coPset_opp_raw
(
`
Y
))
↾
coPset_intersection_wf
_
_
(
proj2_sig
X
)
(
coPset_opp_wf
_)
.
Instance
coPset_elem_of_dec
(
p
:
positive
)
(
X
:
coPset
)
:
Decision
(
p
∈
X
)
:=
_
.
Instance
coPset_collection
:
Collection
positive
coPset
.
Proof
.
split
;
[
split
|
|]
.
*
by
intros
??
.
*
intros
p
q
.
apply
elem_of_coPset_singleton
.
*
intros
X
Y
p
;
unfold
elem_of
,
coPset_elem_of
,
coPset_union
;
simpl
.
by
rewrite
elem_of_coPset_union
,
orb_True
.
*
intros
X
Y
p
;
unfold
elem_of
,
coPset_elem_of
,
coPset_intersection
;
simpl
.
by
rewrite
elem_of_coPset_intersection
,
andb_True
.
*
intros
X
Y
p
;
unfold
elem_of
,
coPset_elem_of
,
coPset_difference
;
simpl
.
by
rewrite
elem_of_coPset_intersection
,
elem_of_coPset_opp
,
andb_True
,
negb_True
.
Qed
.
Instance
coPset_leibniz
:
LeibnizEquiv
coPset
.
Proof
.
intros
X
Y
;
split
;
[
rewrite
elem_of_equiv
;
intros
HXY
|
by
intros
->
]
.
apply
(
sig_eq_pi
_),
coPset_eq
;
try
apply
proj2_sig
.
intros
p
;
apply
eq_bool_prop_intro
,
(
HXY
p
)
.
Qed
.
(** Infinite sets *)
Fixpoint
coPset_infinite_raw
(
t
:
coPset_raw
)
:
bool
:=
match
t
with
|
coPLeaf
b
=>
b
|
coPNode
b
l
r
=>
coPset_infinite_raw
l
||
coPset_infinite_raw
r
end
.
Definition
coPset_infinite
(
t
:
coPset
)
:
bool
:=
coPset_infinite_raw
(
`
t
)
.
Lemma
coPset_infinite_coPNode
b
l
r
:
coPset_infinite_raw
(
coPNode'
b
l
r
)
=
coPset_infinite_raw
(
coPNode
b
l
r
)
.
Proof
.
by
destruct
b
,
l
as
[[]|],
r
as
[[]|]
.
Qed
.
(** Splitting of infinite sets *)
Fixpoint
coPset_l_raw
(
t
:
coPset_raw
)
:
coPset_raw
:=
match
t
with
|
coPLeaf
false
=>
coPLeaf
false
|
coPLeaf
true
=>
coPNode
true
(
coPLeaf
true
)
(
coPLeaf
false
)
|
coPNode
b
l
r
=>
coPNode'
b
(
coPset_l_raw
l
)
(
coPset_l_raw
r
)
end
.
Fixpoint
coPset_r_raw
(
t
:
coPset_raw
)
:
coPset_raw
:=
match
t
with
|
coPLeaf
false
=>
coPLeaf
false
|
coPLeaf
true
=>
coPNode
false
(
coPLeaf
false
)
(
coPLeaf
true
)
|
coPNode
b
l
r
=>
coPNode'
false
(
coPset_r_raw
l
)
(
coPset_r_raw
r
)
end
.
Lemma
coPset_l_wf
t
:
coPset_wf
(
coPset_l_raw
t
)
.
Proof
.
induction
t
as
[[]|];
simpl
;
auto
.
Qed
.
Lemma
coPset_r_wf
t
:
coPset_wf
(
coPset_r_raw
t
)
.
Proof
.
induction
t
as
[[]|];
simpl
;
auto
.
Qed
.
Definition
coPset_l
(
X
:
coPset
)
:
coPset
:=
coPset_l_raw
(
`
X
)
↾
coPset_l_wf
_
.
Definition
coPset_r
(
X
:
coPset
)
:
coPset
:=
coPset_r_raw
(
`
X
)
↾
coPset_r_wf
_
.
Lemma
coPset_lr_disjoint
X
:
coPset_l
X
∩
coPset_r
X
=
∅.
Proof
.
apply
elem_of_equiv_empty_L
;
intros
p
;
apply
Is_true_false
.
destruct
X
as
[
t
Ht
];
simpl
;
clear
Ht
;
rewrite
elem_of_coPset_intersection
.
revert
p
;
induction
t
as
[[]|[]];
intros
[?|?|];
simpl
;
rewrite
?coPset_elem_of_coPNode'
;
simpl
;
rewrite
?orb_true_l
,
?orb_false_l
,
?orb_true_r
,
?orb_false_r
;
auto
.
Qed
.
Lemma
coPset_lr_union
X
:
coPset_l
X
∪
coPset_r
X
=
X
.
Proof
.
apply
elem_of_equiv_L
;
intros
p
;
apply
eq_bool_prop_elim
.
destruct
X
as
[
t
Ht
];
simpl
;
clear
Ht
;
rewrite
elem_of_coPset_union
.
revert
p
;
induction
t
as
[[]|[]];
intros
[?|?|];
simpl
;
rewrite
?coPset_elem_of_coPNode'
;
simpl
;
rewrite
?orb_true_l
,
?orb_false_l
,
?orb_true_r
,
?orb_false_r
;
auto
.
Qed
.
Lemma
coPset_l_infinite
X
:
coPset_infinite
X
→
coPset_infinite
(
coPset_l
X
)
.
Proof
.
destruct
X
as
[
t
Ht
];
unfold
coPset_infinite
;
simpl
;
clear
Ht
.
induction
t
as
[[]|];
simpl
;
rewrite
?coPset_infinite_coPNode
;
simpl
;
rewrite
?orb_True
;
tauto
.
Qed
.
Lemma
coPset_r_infinite
X
:
coPset_infinite
X
→
coPset_infinite
(
coPset_r
X
)
.
Proof
.
destruct
X
as
[
t
Ht
];
unfold
coPset_infinite
;
simpl
;
clear
Ht
.
induction
t
as
[[]|];
simpl
;
rewrite
?coPset_infinite_coPNode
;
simpl
;
rewrite
?orb_True
;
tauto
.
Qed
.
(** Conversion from psets *)
Fixpoint
to_coPset_raw
(
t
:
Pmap_raw
())
:
coPset_raw
:=
match
t
with
|
PLeaf
=>
coPLeaf
false
|
PNode
None
l
r
=>
coPNode
false
(
to_coPset_raw
l
)
(
to_coPset_raw
r
)
|
PNode
(
Some
_)
l
r
=>
coPNode
true
(
to_coPset_raw
l
)
(
to_coPset_raw
r
)
end
.
Lemma
to_coPset_raw_wf
t
:
Pmap_wf
t
→
coPset_wf
(
to_coPset_raw
t
)
.
Proof
.
induction
t
as
[|[]
l
IHl
r
IHr
];
simpl
;
rewrite
?andb_True
;
auto
.
*
intros
[??];
destruct
l
as
[|[]],
r
as
[|[]];
simpl
in
*
;
auto
.
*
destruct
l
as
[|[]],
r
as
[|[]];
simpl
in
*
;
rewrite
?andb_true_r
;
rewrite
?andb_True
;
rewrite
?andb_True
in
IHl
,
IHr
;
intuition
.
Qed
.
Definition
to_coPset
(
X
:
Pset
)
:
coPset
:=
to_coPset_raw
(
pmap_car
(
mapset_car
X
))
↾
to_coPset_raw_wf
_
(
pmap_prf
_)
.
Lemma
elem_of_to_coPset
X
i
:
i
∈
to_coPset
X
↔
i
∈
X
.
Proof
.
destruct
X
as
[[
t
Ht
]];
change
(
e_of
i
(
to_coPset_raw
t
)
↔
t
!!
i
=
Some
())
.
clear
Ht
;
revert
i
.
induction
t
as
[|[[]|]
l
IHl
r
IHr
];
intros
[
i
|
i
|];
simpl
;
auto
;
by
split
.
Qed
.
Instance
Pmap_dom_Pset
{
A
}
:
Dom
(
Pmap
A
)
coPset
:=
λ
m
,
to_coPset
(
dom
_
m
)
.
Instance
Pmap_dom_coPset
:
FinMapDom
positive
Pmap
coPset
.
Proof
.
split
;
try
apply
_;
intros
A
m
i
;
unfold
dom
,
Pmap_dom_Pset
.
by
rewrite
elem_of_to_coPset
,
elem_of_dom
.
Qed
.
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