diff options
author | Jason Gross <jgross@mit.edu> | 2017-03-28 20:58:36 -0400 |
---|---|---|
committer | Jason Gross <jgross@mit.edu> | 2017-03-28 20:58:36 -0400 |
commit | 0df9bc47e1374a24c0446ac005decc6b56f8c1d7 (patch) | |
tree | 5f0f98c3eed3f8a965f0f615240e20bbf79b9a06 /src/Reflection | |
parent | e04a4621687b2d22d6ea7211b3679f1f6a1cbce8 (diff) |
Add FoldTypes
Diffstat (limited to 'src/Reflection')
-rw-r--r-- | src/Reflection/FoldTypes.v | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/Reflection/FoldTypes.v b/src/Reflection/FoldTypes.v new file mode 100644 index 000000000..d5d62a3aa --- /dev/null +++ b/src/Reflection/FoldTypes.v @@ -0,0 +1,45 @@ +Require Import Crypto.Reflection.Syntax. +Require Import Crypto.Reflection.ExprInversion. +Require Import Crypto.Reflection.SmartMap. + +Section language. + Context {base_type_code} {op : flat_type base_type_code -> flat_type base_type_code -> Type}. + + Section generic_type. + Context {A} + (process : base_type_code -> A) + (fold : A -> A -> A). + + Section with_var. + Context {var : base_type_code -> Type} + (init : A) + (dummy : forall t, var t). + + Fixpoint fold_flat_type (t : flat_type base_type_code) : A + := match t with + | Tbase T => process T + | Unit => init + | Prod A B => fold (fold_flat_type A) (fold_flat_type B) + end. + + Fixpoint type_foldf {t} (e : @exprf base_type_code op var t) : A + := match e with + | TT => init + | Var t v => process t + | Op t tR opc args + => fold (@type_foldf t args) (fold_flat_type tR) + | LetIn tx ex tC eC + => fold (@type_foldf tx ex) + (@type_foldf tC (eC (SmartValf _ dummy _))) + | Pair tx ex ty ey + => fold (@type_foldf tx ex) (@type_foldf ty ey) + end. + + Definition type_fold {t} (e : @expr base_type_code op var t) : A + := fold (fold_flat_type (domain t)) (type_foldf (invert_Abs e (SmartValf _ dummy _))). + End with_var. + + Definition TypeFold (init : A) {t} (e : Expr base_type_code op t) : A + := type_fold init (fun _ => tt) (e (fun _ => unit)). + End generic_type. +End language. |