40 lines
921 B
Coq
40 lines
921 B
Coq
Require Import ZArith.
|
|
|
|
Inductive Exp : N -> Type :=
|
|
| Const : forall M, N -> Exp M
|
|
| Add : forall M, Exp M -> Exp M -> Exp M
|
|
| Mul : forall M, Exp M -> Exp M -> Exp M
|
|
| Mod : forall M, Exp M -> Exp M.
|
|
|
|
Arguments Const {M}.
|
|
Arguments Add {M}.
|
|
Arguments Mul {M}.
|
|
Arguments Mod {M}.
|
|
|
|
Infix "+" := Add.
|
|
Infix "*" := Mul.
|
|
|
|
Fixpoint eval {M}(e : Exp M) : N :=
|
|
match e with
|
|
| Const x => x
|
|
| Add e1 e2 => eval e1 + eval e2
|
|
| Mul e1 e2 => eval e1 * eval e2
|
|
| Mod ep => eval ep mod M
|
|
end.
|
|
|
|
Ltac reify e M :=
|
|
match e with
|
|
| (?e1 + ?e2)%N =>
|
|
let e1p := reify constr:(e1) M in
|
|
let e2p := reify constr:(e2) M in
|
|
constr:(Add (M:=M) e1p e2p)
|
|
| (?e1 * ?e2)%N =>
|
|
let e1p := reify constr:(e1) M in
|
|
let e2p := reify constr:(e2) M in
|
|
constr:(Mul (M:=M) e1p e2p)
|
|
| (?ep mod ?M)%N =>
|
|
let epp := reify ep M in
|
|
constr:(Mod (M:=M) epp)
|
|
| _ => constr:(Const (M:=M) e)
|
|
end.
|