(************************************************************************) (* v * The Coq Proof Assistant / The Coq Development Team *) (* y" := (y < x) (only parsing) : bigN_scope. Notation "x >= y" := (y <= x) (only parsing) : bigN_scope. Notation "x < y < z" := (x BigN.succ (BigN.pred q) == q. Proof. intros; apply BigN.succ_pred. intro H'; rewrite H' in H; discriminate. Qed. (** [BigN] is a semi-ring *) Lemma BigNring : semi_ring_theory 0 1 BigN.add BigN.mul BigN.eq. Proof. constructor. exact BigN.add_0_l. exact BigN.add_comm. exact BigN.add_assoc. exact BigN.mul_1_l. exact BigN.mul_0_l. exact BigN.mul_comm. exact BigN.mul_assoc. exact BigN.mul_add_distr_r. Qed. Lemma BigNeqb_correct : forall x y, (x =? y) = true -> x==y. Proof. now apply BigN.eqb_eq. Qed. Lemma BigNpower : power_theory 1 BigN.mul BigN.eq BigN.of_N BigN.pow. Proof. constructor. intros. red. rewrite BigN.spec_pow, BigN.spec_of_N. rewrite Zpower_theory.(rpow_pow_N). destruct n; simpl. reflexivity. induction p; simpl; intros; BigN.zify; rewrite ?IHp; auto. Qed. Lemma BigNdiv : div_theory BigN.eq BigN.add BigN.mul (@id _) (fun a b => if b =? 0 then (0,a) else BigN.div_eucl a b). Proof. constructor. unfold id. intros a b. BigN.zify. case Z.eqb_spec. BigN.zify. auto with zarith. intros NEQ. generalize (BigN.spec_div_eucl a b). generalize (Z_div_mod_full [a] [b] NEQ). destruct BigN.div_eucl as (q,r), Z.div_eucl as (q',r'). intros (EQ,_). injection 1. intros EQr EQq. BigN.zify. rewrite EQr, EQq; auto. Qed. (** Detection of constants *) Ltac isStaticWordCst t := match t with | W0 => constr:true | WW ?t1 ?t2 => match isStaticWordCst t1 with | false => constr:false | true => isStaticWordCst t2 end | _ => isInt31cst t end. Ltac isBigNcst t := match t with | BigN.N0 ?t => isStaticWordCst t | BigN.N1 ?t => isStaticWordCst t | BigN.N2 ?t => isStaticWordCst t | BigN.N3 ?t => isStaticWordCst t | BigN.N4 ?t => isStaticWordCst t | BigN.N5 ?t => isStaticWordCst t | BigN.N6 ?t => isStaticWordCst t | BigN.Nn ?n ?t => match isnatcst n with | true => isStaticWordCst t | false => constr:false end | BigN.zero => constr:true | BigN.one => constr:true | BigN.two => constr:true | _ => constr:false end. Ltac BigNcst t := match isBigNcst t with | true => constr:t | false => constr:NotConstant end. Ltac BigN_to_N t := match isBigNcst t with | true => eval vm_compute in (BigN.to_N t) | false => constr:NotConstant end. Ltac Ncst t := match isNcst t with | true => constr:t | false => constr:NotConstant end. (** Registration for the "ring" tactic *) Add Ring BigNr : BigNring (decidable BigNeqb_correct, constants [BigNcst], power_tac BigNpower [BigN_to_N], div BigNdiv). Section TestRing. Let test : forall x y, 1 + x*y^1 + x^2 + 1 == 1*1 + 1 + y*x + 1*x*x. intros. ring_simplify. reflexivity. Qed. End TestRing. (** We benefit also from an "order" tactic *) Ltac bigN_order := BigN.order. Section TestOrder. Let test : forall x y : bigN, x<=y -> y<=x -> x==y. Proof. bigN_order. Qed. End TestOrder. (** We can use at least a bit of (r)omega by translating to [Z]. *) Section TestOmega. Let test : forall x y : bigN, x<=y -> y<=x -> x==y. Proof. intros x y. BigN.zify. omega. Qed. End TestOmega. (** Todo: micromega *)