|
| 1 | +(** * MetaCoq *) |
| 2 | + |
| 3 | +Load MetaCoqPrelude. |
| 4 | + |
| 5 | +Print term. |
| 6 | + |
| 7 | +Check $quote (fun x : nat => x). |
| 8 | + |
| 9 | +Check $unquote (tLam "y" ($quote bool) ($quote (fun x : nat => x))). |
| 10 | + |
| 11 | +Definition tNat := $quote nat. |
| 12 | + |
| 13 | +Definition idNat := $unquote |
| 14 | + (tLam "x" tNat (tRel 0)). |
| 15 | +Print idNat. |
| 16 | + |
| 17 | +Check $unquote (tLam "x" ($quote nat) (tRel 0)). |
| 18 | + |
| 19 | +#[bypass_check(guard)] |
| 20 | +Fixpoint Mpower' (n : nat) : term := |
| 21 | + match n with |
| 22 | + | 0 => $quote 1 |
| 23 | + | 1 => tRel 0 |
| 24 | + | 2 => tApp ($quote mult) [tRel 0; tRel 0] |
| 25 | + | S n' as n => if n mod 2 =? 0 then |
| 26 | + tLet "p" ($quote nat) (Mpower' (div n 2)) |
| 27 | + (tApp ($quote mult) [tRel 0 ; tRel 0]) |
| 28 | + else tApp ($quote mult) [Mpower' n' ; tRel 0] |
| 29 | + end. |
| 30 | + |
| 31 | +Print Mpower'. |
| 32 | + |
| 33 | +Definition Mpower (n : nat) := |
| 34 | + tLam "x" ($quote nat) (Mpower' n). |
| 35 | + |
| 36 | +Compute Mpower' 3. |
| 37 | + |
| 38 | +Definition power3 := ($unquote (Mpower 3)). |
| 39 | +Print power3. |
| 40 | + |
| 41 | +Definition power13 := ($unquote (Mpower 13)). |
| 42 | +Print power13. |
| 43 | +Print Assumptions power13. |
| 44 | + |
| 45 | +Inductive arith := |
| 46 | +| aPlus : arith -> arith -> arith |
| 47 | +| aConst : nat -> arith. |
| 48 | + |
| 49 | +Fixpoint reify (x : term) := |
| 50 | + match x with |
| 51 | + | tApp c [u; v] => |
| 52 | + if c == $quote plus |
| 53 | + then tApp ($quote aPlus) [reify u; reify v] |
| 54 | + else tApp ($quote aConst) [x] |
| 55 | + | n => tApp ($quote aConst) [x] |
| 56 | + end. |
| 57 | + |
| 58 | +Goal 4 + (3 + 1) = 2. |
| 59 | +Proof. |
| 60 | + match goal with |
| 61 | + | [ |- ?L = _ ] => pose ($unquote (reify ($quote L))) |
| 62 | + end. |
| 63 | +Abort. |
| 64 | + |
| 65 | +(** ** Advanced *) |
| 66 | +(** Write automation that unfolds and reduces all constants c in a term, *unless* c : Type, or c : P where P : Prop. |
| 67 | + It suffices to change the tConst case of the function below. Use the auxiliary function defined and checked below. |
| 68 | +*) |
| 69 | + |
| 70 | +Definition reduce Σ t := match reduce_opt RedFlags.default Σ [] default_fuel t with Some res => res | _ => t end. |
| 71 | +Definition infer_type Σ t := infer (cf := config.default_checker_flags) (F := default_fuel) Σ init_graph [] t. |
| 72 | + |
| 73 | +Check lookup_constant. |
| 74 | +Check Universe.is_prop. |
| 75 | + |
| 76 | +Require Import List. |
| 77 | + |
| 78 | +Section fix_Sigma. |
| 79 | + |
| 80 | +Variable Σ : global_env. |
| 81 | + |
| 82 | +Fixpoint simplify_consts (t : term) := |
| 83 | + match t with |
| 84 | + | tRel n => tRel n |
| 85 | + | tVar id => tVar id |
| 86 | + | tEvar ev args => tEvar ev (map simplify_consts args) |
| 87 | + | tSort s => tSort s |
| 88 | + | tCast t kind v => tCast (simplify_consts t) kind (simplify_consts v) |
| 89 | + | tProd na ty body => tProd na (simplify_consts ty) (simplify_consts body) |
| 90 | + | tLambda na ty body => tLambda na (simplify_consts ty) (simplify_consts body) |
| 91 | + | tLetIn na def def_ty body => tLetIn na (simplify_consts def) (simplify_consts def_ty) (simplify_consts body) |
| 92 | + | tApp f args => tApp (simplify_consts f) (map simplify_consts args) |
| 93 | + | tConst c u => |
| 94 | + match infer_type Σ (tConst c u) with |
| 95 | + | Checked (tSort _) => tConst c u |
| 96 | + | Checked A => |
| 97 | + match infer_type Σ A with |
| 98 | + | Checked (tSort univ) => if Universe.is_prop univ then |
| 99 | + tConst c u |
| 100 | + else |
| 101 | + match lookup_constant Σ c with |
| 102 | + | Some {| cst_body := Some b |} => reduce Σ b |
| 103 | + | _ => tConst c u |
| 104 | + end |
| 105 | + | Checked K => match lookup_constant Σ c with |
| 106 | + | Some {| cst_body := Some b |} => reduce Σ b |
| 107 | + | _ => tConst c u |
| 108 | + end |
| 109 | + | TypeError E => tConst c u |
| 110 | + end |
| 111 | + | TypeError E => tConst c u |
| 112 | + end |
| 113 | + | tInd ind u => tInd ind u |
| 114 | + | tConstruct ind idx u => tConstruct ind idx u |
| 115 | + | tCase ind p discr brs => |
| 116 | + let p' := map_predicate id simplify_consts simplify_consts p in |
| 117 | + let brs' := map_branches simplify_consts brs in |
| 118 | + tCase ind p' (simplify_consts discr) brs' |
| 119 | + | tProj proj t => tProj proj (simplify_consts t) |
| 120 | + | tFix mfix idx => tFix (map (map_def simplify_consts simplify_consts) mfix) idx |
| 121 | + | tCoFix mfix idx => tCoFix (map (map_def simplify_consts simplify_consts) mfix) idx |
| 122 | + | tInt i => tInt i |
| 123 | + | tFloat f => tFloat f |
| 124 | + end. |
| 125 | + |
| 126 | +End fix_Sigma. |
| 127 | + |
| 128 | +Definition unfold_comp (p : program) := |
| 129 | + simplify_consts p.1 p.2. |
| 130 | + |
| 131 | +Definition dont := nat. |
| 132 | +Definition alsodont := conj I (fun x : False => x). |
| 133 | +Definition do := 3 + 1. |
| 134 | + |
| 135 | +Check $unquote (unfold_comp ($quote_rec (dont, alsodont, do))). |
| 136 | +(* expected output: (dont, alsodont, 4) *) |
0 commit comments