Module ListDom
Require
Import
Coqlib
Lia
.
Require
Import
List
.
Definition
dom
(
B
:
positive
) :
list
positive
:=
map
(
Pos.of_nat
) (
seq
1 (
Pos.to_nat
B
- 1))%
nat
.
Lemma
dom_spec_rec
:
forall
B
,
dom
(
Pos.succ
B
) = (
dom
B
) ++
B
::
nil
.
Proof.
intro
.
unfold
dom
.
rewrite
Pos2Nat.inj_succ
.
pose
proof
(
Pos2Nat.is_pos
B
)
as
POS
.
remember
(
Pos.to_nat
B
)
as
N
.
assert
(
B
=
Pos.of_nat
N
).
subst
.
rewrite
Pos2Nat.id
;
auto
.
rewrite
H
.
clear
B
HeqN
H
.
assert
(
forall
s
, 0 <
N
->
seq
s
(
S
N
- 1) =
seq
s
(
N
- 1) ++ (
s
+ (
N
- 1)) ::
nil
)%
nat
.
{
clear
.
induction
N
.
intros
.
omega
.
destruct
N
;
simpl
in
*.
intro
.
rewrite
Nat.add_0_r
.
auto
.
intros
.
rewrite
(
IHN
(
S
s
));[|
omega
].
simpl
.
repeat
f_equal
;
omega
. }
rewrite
H
;
auto
.
rewrite
map_app
.
replace
(1 + (
N
- 1))%
nat
with
N
by
omega
.
simpl
.
auto
.
Qed.
Lemma
dom_length
:
forall
B
,
length
(
dom
B
) = (
Pos.to_nat
B
- 1)%
nat
.
Proof.
intro
.
unfold
dom
.
rewrite
map_length
,
seq_length
;
auto
. Qed.
Lemma
dom_correct
:
forall
B
b
,
Plt
b
B
<->
In
b
(
dom
B
).
Proof.
intros
.
split
;
intros
.
unfold
dom
.
rewrite
<- (
Pos2Nat.id
b
).
apply
in_map
.
auto
.
apply
in_seq
.
pose
proof
(
Pos2Nat.is_pos
b
);
pose
proof
(
Pos2Nat.is_pos
B
).
rewrite
Nat.add_sub_assoc
,
minus_plus
;
try
split
;
try
omega
.
apply
Pos2Nat.inj_lt
;
auto
.
unfold
dom
in
H
.
apply
in_map_iff
in
H
.
destruct
H
as
[
x
[
Hb
IN
]].
apply
in_seq
in
IN
.
pose
proof
(
Pos2Nat.is_pos
B
).
rewrite
Nat.add_sub_assoc
,
minus_plus
in
IN
;
try
omega
.
assert
(
Pos.to_nat
b
=
x
).
rewrite
<-
Hb
.
apply
Nat2Pos.id
.
omega
.
rewrite
<-
H0
in
IN
.
destruct
IN
as
[
_
IN
].
destruct
(
plt
b
B
);
auto
.
apply
Pos2Nat.inj_lt
in
IN
.
congruence
.
Qed.
Lemma
incl_length_lt
:
forall
B
pl
,
(
forall
p
,
In
p
pl
->
Plt
p
B
) ->
NoDup
pl
->
(
length
pl
<
Pos.to_nat
B
)%
nat
.
Proof.
intros
.
cut
(
length
pl
<=
Pos.to_nat
B
- 1)%
nat
.
lia
.
rewrite
<-
dom_length
.
apply
NoDup_incl_length
;
auto
.
unfold
incl
.
intros
.
apply
H
in
H1
.
apply
dom_correct
;
auto
.
Qed.