Module Ring_polynom_AddOn
Adapter of Ring_polynom for VPL needs. - We instantiate polynomials on Z - We introduce an alternative definition of evaluation closer to our needs.
Require
Coq.setoid_ring.Cring
.
Require
Export
Coq.setoid_ring.Ring_polynom
.
Require
Export
ZArith
.
Require
Import
Equivalence
.
Open
Scope
Z_scope
.
Instance
Zops
: (@
Ncring.Ring_ops
Z
0%
Z
1%
Z
Zplus
Zmult
Zminus
Zopp
(@
eq
Z
)).
Instance
Qri
: (
Ncring.Ring
(
Ro
:=
Zops
)).
constructor
;
try
Morphisms.solve_proper
.
-
exact
eq_equivalence
.
-
exact
Zplus_comm
.
-
exact
Zplus_assoc
.
-
exact
Zmult_1_l
.
-
exact
Zmult_1_r
.
-
exact
Zmult_assoc
.
-
exact
Zmult_plus_distr_l
.
-
intros
;
apply
Zmult_plus_distr_r
.
-
exact
Zplus_opp_r
.
Defined.
Instance
Zcri
: (
Cring.Cring
(
R
:=
Z
)).
-
exact
Zmult_comm
.
Defined.
Definition
Zpower
:
Z
->
N
->
Z
:=
pow_N
1
Zmult
.
Definition
PExpr
:=
PExpr
Z
.
Definition
Pol
:=
Pol
Z
.
Definition
PEeval
(
l
:
list
Z
) (
p
:
PExpr
):
Z
:=
PEeval
0
Zplus
Zmult
Zminus
Zopp
(
fun
x
=>
x
) (
fun
x
=>
x
)
Zpower
l
p
.
Definition
Pphi
(
l
:
list
Z
) (
p
:
Pol
):
Z
:=
Pphi
0
Zplus
Zmult
(
fun
x
=>
x
)
l
p
.
Definition
norm
(
pe
:
PExpr
):
Pol
:=
norm_aux
0 1
Zplus
Zmult
Zminus
Zopp
Zeq_bool
pe
.
Definition
Peq
(
p1
p2
:
Pol
) :
bool
:=
Peq
Zeq_bool
p1
p2
.
Definition
PExpr_eq
(
pe1
pe2
:
PExpr
):
bool
:=
Peq
(
norm
pe1
) (
norm
pe2
).
Extraction
Inline
PExpr_eq
Peq
norm
.
Fixpoint
PEsem
(
pe
:
PExpr
) (
m
:
positive
->
Z
):
Z
:=
match
pe
with
|
PEc
c
=>
c
|
PEX
j
=>
m
j
|
PEadd
pe1
pe2
=>
Zplus
(
PEsem
pe1
m
) (
PEsem
pe2
m
)
|
PEsub
pe1
pe2
=>
Zminus
(
PEsem
pe1
m
) (
PEsem
pe2
m
)
|
PEmul
pe1
pe2
=>
Zmult
(
PEsem
pe1
m
) (
PEsem
pe2
m
)
|
PEopp
pe1
=>
Zopp
(
PEsem
pe1
m
)
|
PEpow
pe1
n
=>
Zpower
(
PEsem
pe1
m
)
n
end
.
Require
Import
Coq.setoid_ring.BinList
.
Lemma
jump_iter_tl_aux
{
A
} (
n
:
nat
):
forall
(
l
:
list
A
),
jump
(
Pos.of_nat
(
S
n
))
l
=
nat_iter
(
S
n
) (@
tl
_
)
l
.
Proof.
simpl
;
induction
n
;
simpl
;
auto
.
intros
;
rewrite
<-
IHn
.
rewrite
jump_succ
.
simpl
;
auto
.
Qed.
Lemma
jump_iter_tl
{
A
} (
p
:
positive
) (
l
:
list
A
):
jump
p
l
=
nat_iter
(
Pos.to_nat
p
) (@
tl
_
)
l
.
Proof.
rewrite
<- (
Pos2Nat.id
p
)
at
1.
generalize
(
Pos2Nat.is_pos
p
).
generalize
(
Pos.to_nat
p
).
intros
n
;
case
n
.
-
intros
H
;
inversion
H
.
-
intros
n0
H
;
clear
H
.
apply
jump_iter_tl_aux
.
Qed.
Lemma
nth_positive_nat_iter
{
A
} (
p
:
positive
):
forall
(
l
:
list
A
)
d
,
nth
d
p
l
=
hd
d
(
nat_iter
(
pred
(
Pos.to_nat
p
)) (@
tl
_
)
l
).
Proof.
induction
p
;
auto
.
-
intros
;
simpl
;
rewrite
IHp
;
simpl
.
rewrite
jump_iter_tl
.
rewrite
<-
nat_iter_plus
.
rewrite
<-
nat_iter_succ_r
.
cutrewrite
((
S
(
pred
(
Pos.to_nat
p
) +
Pos.to_nat
p
))=(
Pos.to_nat
p
~0)).
simpl
;
auto
.
rewrite
Pos2Nat.inj_xO
.
generalize
(
Pos2Nat.is_pos
p
).
omega
.
-
intros
;
simpl
;
rewrite
IHp
;
simpl
.
rewrite
jump_iter_tl
.
rewrite
<-
nat_iter_plus
.
cutrewrite
(((
pred
(
Pos.to_nat
p
)) +
Pos.to_nat
p
)%
nat
=
pred
(
Pos.to_nat
p
~0)).
simpl
;
auto
.
rewrite
Pos2Nat.inj_xO
.
generalize
(
Pos2Nat.is_pos
p
).
omega
.
Qed.
Lemma
List_nth_hd_iter_tl
{
A
} (
n
:
nat
):
forall
(
l
:
list
A
) (
d
:
A
),
List.nth
n
l
d
=
hd
d
(
nat_iter
n
(@
tl
_
)
l
).
Proof.
induction
n
.
-
destruct
l
;
simpl
;
auto
.
-
intros
;
rewrite
nat_iter_succ_r
.
rewrite
<-
IHn
.
destruct
l
;
simpl
;
auto
.
destruct
n
;
simpl
;
auto
.
Qed.
Lemma
nth_positive_nat
{
A
} (
p
:
positive
) (
l
:
list
A
)
d
:
nth
d
p
l
=
List.nth
(
pred
(
Pos.to_nat
p
))
l
d
.
Proof.
intros
;
rewrite
List_nth_hd_iter_tl
,
nth_positive_nat_iter
.
auto
.
Qed.
Definition
mkMemoryList
{
A
} (
bound
:
positive
) (
mem
:
positive
->
A
)
:=
List.map
(
fun
n
=>
mem
(
Pos.of_nat
n
)) (
List.seq
(
S
O
) (
Pos.to_nat
bound
)).
Lemma
nth_mkMemoryList
{
A
}
p
bnd
(
mem
:
positive
->
A
)
d
:
(
p
<=
bnd
)%
positive
->
nth
d
p
(
mkMemoryList
bnd
mem
) =
mem
p
.
Proof.
unfold
mkMemoryList
.
intros
;
assert
(
Y
:(
pred
(
Pos.to_nat
p
) <
Pos.to_nat
bnd
)%
nat
).
assert
(
X
:
forall
(
n
m
:
nat
), (0 <
n
)%
nat
-> (
n
<=
m
)%
nat
-> (
pred
n
<
m
)%
nat
).
intros
;
omega
.
apply
X
.
apply
Pos2Nat.is_pos
.
rewrite
<-
Pos2Nat.inj_le
.
auto
.
clear
H
;
rewrite
nth_positive_nat
;
erewrite
nth_indep
.
-
rewrite
List.map_nth
,
seq_nth
.
apply
f_equal
.
assert
(
X
:
forall
(
n
:
nat
), (0 <
n
)%
nat
-> (1 +
pred
n
)%
nat
=
n
).
+
intros
;
omega
.
+
rewrite
X
.
apply
Pos2Nat.id
.
apply
Pos2Nat.is_pos
.
+
auto
.
-
intros
;
autorewrite
with
list
;
auto
.
Grab
Existential
Variables
.
apply
O
.
Qed.
Fixpoint
bound
(
pe
:
PExpr
):
positive
:=
match
pe
with
|
PEX
x
=>
x
|
PEadd
pe1
pe2
=>
Pmax
(
bound
pe1
) (
bound
pe2
)
|
PEsub
pe1
pe2
=>
Pmax
(
bound
pe1
) (
bound
pe2
)
|
PEmul
pe1
pe2
=>
Pmax
(
bound
pe1
) (
bound
pe2
)
|
PEopp
pe
=>
bound
pe
|
PEpow
pe
_
=>
bound
pe
|
_
=>
xH
end
.
Local
Hint
Resolve
Pos.max_lub_l
Pos.max_lub_r
Pos.le_max_l
Pos.le_max_r
.
Theorem
PEsem_Eval
(
pe
:
PExpr
) (
m
:
positive
->
Z
)
bnd
:
((
bound
pe
) <=
bnd
)%
positive
->
PEsem
pe
m
=
PEeval
(
mkMemoryList
bnd
m
)
pe
.
Proof.
induction
pe
;
simpl
;
auto
;
try
(
intros
;
rewrite
IHpe
||
rewrite
IHpe1
,
IHpe2
;
eauto
).
intros
;
rewrite
nth_mkMemoryList
;
auto
.
Qed.
Local
Hint
Resolve
Zeq_bool_eq
.
Theorem
PEnorm_correct
(
pe
:
PExpr
) (
m
:
positive
->
Z
)
bnd
:
((
bound
pe
) <=
bnd
)%
positive
->
PEsem
pe
m
=
Pphi
(
mkMemoryList
bnd
m
) (
norm
pe
).
Proof.
intros
;
erewrite
PEsem_Eval
;
eauto
.
unfold
PEeval
,
Pphi
,
norm
;
eapply
norm_aux_spec
.
-
apply
Eqsth
.
-
eapply
Cring.cring_eq_ext
;
eauto
.
-
eapply
Cring.cring_almost_ring_theory
;
eauto
.
-
eapply
mkmorph
;
eauto
.
-
apply
Cring.cring_power_theory
;
eauto
.
Qed.
Theorem
PExpr_eq_correct
(
pe1
pe2
:
PExpr
) (
m
:
positive
->
Z
):
PExpr_eq
pe1
pe2
=
true
->
PEsem
pe1
m
=
PEsem
pe2
m
.
Proof.
unfold
PExpr_eq
,
Peq
.
intro
H
;
rewrite
!
PEnorm_correct
with
(
bnd
:=
Pmax
(
bound
pe1
) (
bound
pe2
));
auto
.
unfold
Pphi
.
refine
(
Peq_ok
_
_
_
_
_
H
_
).
-
eapply
Cring.cring_eq_ext
;
eauto
.
-
eapply
mkmorph
;
eauto
.
Grab
Existential
Variables
.
apply
Zplus
.
apply
0.
Qed.