aboutsummaryrefslogtreecommitdiff
path: root/src/Reflection
diff options
context:
space:
mode:
authorGravatar Jason Gross <jgross@mit.edu>2017-03-28 20:58:36 -0400
committerGravatar Jason Gross <jgross@mit.edu>2017-03-28 20:58:36 -0400
commit0df9bc47e1374a24c0446ac005decc6b56f8c1d7 (patch)
tree5f0f98c3eed3f8a965f0f615240e20bbf79b9a06 /src/Reflection
parente04a4621687b2d22d6ea7211b3679f1f6a1cbce8 (diff)
Add FoldTypes
Diffstat (limited to 'src/Reflection')
-rw-r--r--src/Reflection/FoldTypes.v45
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.