Library Stdlib.ZArith.Zcong
From
Stdlib
Require
Import
BinInt
.
From
Stdlib
Require
Import
ZArithRing
.
From
Stdlib
Require
Import
Zdiv
.
From
Stdlib
Require
Import
Zdivisibility
.
Local Open
Scope
Z_scope
.
Module
Z
.
Solving congruences
Lemma
cong_mul_cancel_r_coprime
a
b
m
(
Hm
:
m
<>
0) (
Hb
:
Z.coprime
b
m
)
(
H
:
(
a
*
b
)
mod
m
=
0) :
a
mod
m
=
0.
Definition
invmod
a
m
:=
fst
(
fst
(
Z.extgcd
(
a
mod
m
)
m
))
mod
m
.
Lemma
invmod_0_l
m
:
invmod
0
m
=
0.
Lemma
invmod_0_r
a
:
invmod
a
0
=
Z.sgn
a
.
Lemma
invmod_ok
a
m
:
invmod
a
m
*
a
mod
m
=
Z.gcd
a
m
mod
m
.
Lemma
mod_invmod
m
a
:
invmod
a
m
mod
m
=
invmod
a
m
.
Lemma
invmod_coprime'
a
m
(
H
:
Z.coprime
a
m
) :
invmod
a
m
*
a
mod
m
=
1
mod
m
.
Lemma
invmod_coprime
a
m
(
Hm
: 2
<=
m
) (
H
:
Z.coprime
a
m
) :
invmod
a
m
*
a
mod
m
=
1.
Lemma
invmod_prime
a
m
(
Hm
:
Z.prime
m
) (
H
:
a
mod
m
<>
0) :
invmod
a
m
*
a
mod
m
=
1.
Lemma
invmod_1_l
m
:
invmod
1
m
=
1
mod
m
.
Lemma
invmod_mod_l
a
m
:
invmod
(
a
mod
m
)
m
=
invmod
a
m
.
Lemma
coprime_invmod
a
m
(
H
:
Z.coprime
a
m
) :
Z.coprime
(
invmod
a
m
)
m
.
Chinese Remainder Theorem
Definition
combinecong
(
m1
m2
r1
r2
:
Z
) :=
let
'
(
u
,
v
,
d
)
:=
Z.extgcd
m1
m2
in
if
Z.eq_dec
(
r1
mod
d
) (
r2
mod
d
)
then
if
Z.eq_dec
d
0
then
r1
else
(
v
*
m2
*
r1
+
u
*
m1
*
r2
)
/
d
mod
Z.abs
(
m1
*(
m2
/
d
)
)
else
0.
Lemma
mod_combinecong_lcm
m1
m2
r1
r2
:
combinecong
m1
m2
r1
r2
mod
Z.lcm
m1
m2
=
combinecong
m1
m2
r1
r2
.
Lemma
combinecong_sound
m1
m2
r1
r2
(
H
:
r1
mod
Z.gcd
m1
m2
=
r2
mod
Z.gcd
m1
m2
)
(
x
:=
combinecong
m1
m2
r1
r2
) :
x
mod
m1
=
r1
mod
m1
/\
x
mod
m2
=
r2
mod
m2
.
Lemma
combinecong_complete'
a
m1
m2
r1
r2
(
H1
:
a
mod
m1
=
r1
mod
m1
) (
H2
:
a
mod
m2
=
r2
mod
m2
) :
r1
mod
Z.gcd
m1
m2
=
r2
mod
Z.gcd
m1
m2
.
Lemma
combinecong_complete
a
m1
m2
r1
r2
(
H1
:
a
mod
m1
=
r1
mod
m1
) (
H2
:
a
mod
m2
=
r2
mod
m2
) :
a
mod
Z.lcm
m1
m2
=
combinecong
m1
m2
r1
r2
.
Lemma
combinecong_contradiction
m1
m2
r1
r2
:
r1
mod
Z.gcd
m1
m2
<>
r2
mod
Z.gcd
m1
m2
->
combinecong
m1
m2
r1
r2
=
0.
Lemma
combinecong_sound_coprime
m1
m2
r1
r2
(
H
:
Z.coprime
m1
m2
)
(
x
:=
combinecong
m1
m2
r1
r2
) :
x
mod
m1
=
r1
mod
m1
/\
x
mod
m2
=
r2
mod
m2
.
Lemma
combinecong_complete_coprime_abs
a
m1
m2
r1
r2
(
H
:
Z.coprime
m1
m2
)
(
H1
:
a
mod
m1
=
r1
mod
m1
) (
H2
:
a
mod
m2
=
r2
mod
m2
) :
a
mod
Z.abs
(
m1
*
m2
)
=
combinecong
m1
m2
r1
r2
.
Lemma
combinecong_complete_coprime_nonneg
a
m1
m2
r1
r2
(
H
:
Z.coprime
m1
m2
)
(
H1
:
a
mod
m1
=
r1
mod
m1
) (
H2
:
a
mod
m2
=
r2
mod
m2
) (
Hm
: 0
<=
m1
*
m2
) :
a
mod
(
m1
*
m2
)
=
combinecong
m1
m2
r1
r2
.
Lemma
combinecong_complete_coprime_nonneg_nonneg
a
m1
m2
r1
r2
(
H
:
Z.coprime
m1
m2
)
(
H1
:
a
mod
m1
=
r1
mod
m1
) (
H2
:
a
mod
m2
=
r2
mod
m2
) (
Hm1
: 0
<=
m1
) (
Hm2
: 0
<=
m2
) :
a
mod
(
m1
*
m2
)
=
combinecong
m1
m2
r1
r2
.
Lemma
combinecong_comm
m1
m2
r1
r2
:
combinecong
m1
m2
r1
r2
=
combinecong
m2
m1
r2
r1
.
Lemma
combinecong_mod_l
m1
m2
r1
r2
:
combinecong
m1
m2
(
r1
mod
m1
)
r2
=
combinecong
m1
m2
r1
r2
.
Lemma
combinecong_mod_r
m1
m2
r1
r2
:
combinecong
m1
m2
r1
(
r2
mod
m2
)
=
combinecong
m1
m2
r1
r2
.
Lemma
combinecong_opp_opp
(
m1
m2
r1
r2
:
Z
) :
combinecong
m1
m2
(
-
r1
) (
-
r2
)
=
-
combinecong
m1
m2
r1
r2
mod
Z.lcm
m1
m2
.
End
Z
.