val divide_antisym (a b:int) : Lemma
  (requires a `divides` b /\ b `divides` a)
  (ensures  a = b \/ a = -b)
let divide_antisym a b =
  if a <> 0 then
    Classical.exists_elim (a = b \/ a = -b) (Squash.get_proof (exists q1. b = q1 * a))
      (fun q1 ->
        Classical.exists_elim (a = b \/ a = -b) (Squash.get_proof (exists q2. a = q2 * b))
          (fun q2 ->
            assert (b = q1 * a);
            assert (a = q2 * b);
            assert (b = q1 * (q2 * b));
            paren_mul_right q1 q2 b;
            eq_mult_left b (q1 * q2);
            eq_mult_one q1 q2))
val divide_antisym (a b:int) : Lemma
  (requires a `divides` b /\ b `divides` a)
  (ensures  a = b \/ a = -b)
let divide_antisym a b =
if a <> 0
then
  Classical.exists_elim (a = b \/ a = - b)
    (Squash.get_proof (exists q1. b = q1 * a))
    (fun q1 ->
        Classical.exists_elim (a = b \/ a = - b)
          (Squash.get_proof (exists q2. a = q2 * b))
          (fun q2 ->
              assert (b = q1 * a);
              assert (a = q2 * b);
              assert (b = q1 * (q2 * b));
              paren_mul_right q1 q2 b;
              eq_mult_left b (q1 * q2);
              eq_mult_one q1 q2))
FStar.Math.Euclid.fst.checked
prims.fst.checked FStar.Tactics.Effect.fsti.checked FStar.Tactics.Canon.fst.checked FStar.Squash.fsti.checked FStar.Pervasives.Native.fst.checked FStar.Pervasives.fsti.checked FStar.Mul.fst.checked FStar.Math.Lemmas.fst.checked FStar.Classical.Sugar.fsti.checked FStar.Classical.fsti.checked FStar.Calc.fsti.checked
FStar.Math.Euclid.fst
Prims.int Prims.op_disEquality FStar.Classical.exists_elim Prims.l_or Prims.b2t Prims.op_Equality Prims.op_Minus FStar.Mul.op_Star FStar.Squash.get_proof Prims.l_Exists FStar.Math.Euclid.eq_mult_one Prims.unit FStar.Math.Euclid.eq_mult_left FStar.Math.Lemmas.paren_mul_right Prims._assert Prims.squash Prims.bool
module FStar.Math.Euclid

open FStar.Mul
open FStar.Math.Lemmas

///
/// Auxiliary lemmas
///

val eq_mult_left (a b:int) : Lemma (requires a = b * a) (ensures a = 0 \/ b = 1)
let eq_mult_left a b = ()

val eq_mult_one (a b:int) : Lemma
  (requires a * b = 1)
  (ensures (a = 1 /\ b = 1) \/ (a = -1 /\ b = -1))
let eq_mult_one a b = ()

val opp_idempotent (a:int) : Lemma (-(-a) == a)
let opp_idempotent a = ()

val add_sub_l (a b:int) : Lemma (a - b + b = a)
let add_sub_l a b = ()

val add_sub_r (a b:int) : Lemma (a + b - b = a)
let add_sub_r a b = ()

///
/// Divides relation
///

let divides_reflexive a =
  Classical.exists_intro (fun q -> a = q * a) 1

let divides_transitive a b c =
  eliminate exists q1. b == q1 * a
  returns a `divides` c
  with _pf. 
    eliminate exists q2. c == q2 * b
    returns _
    with _pf2.
         introduce exists q. c == q * a
	 with (q1 * q2)
	 and ()
val divide_antisym (a b:int) : Lemma
  (requires a `divides` b /\ b `divides` a)
  (ensures  a = b \/ a = -b)
a: Prims.int -> b: Prims.int
  -> FStar.Pervasives.Lemma
      (requires FStar.Math.Euclid.divides a b /\ FStar.Math.Euclid.divides b a)
      (ensures a = b \/ a = - b)