From 2dce7f242f44e6d09c499de0d874def169a4b049 Mon Sep 17 00:00:00 2001 From: Regis Blanc <regwblanc@gmail.com> Date: Thu, 23 Jul 2015 15:04:03 +0200 Subject: [PATCH] document generic transform --- src/main/scala/leon/purescala/ExprOps.scala | 77 +++++++++++++-------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/src/main/scala/leon/purescala/ExprOps.scala b/src/main/scala/leon/purescala/ExprOps.scala index 0766f017f..684dfce59 100644 --- a/src/main/scala/leon/purescala/ExprOps.scala +++ b/src/main/scala/leon/purescala/ExprOps.scala @@ -17,17 +17,18 @@ import solvers._ * This object provides a few generic operations on Leon expressions, * as well as some common operations. * - * The generic operations enable to apply an operation on a whole tree + * The generic operations lets you apply operations on a whole tree * expression. You can look at: - * - [[ExprOps.foldRight]] - * - [[ExprOps.preTraversal]] - * - [[ExprOps.postTraversal]] - * - [[ExprOps.preMap]] - * - [[ExprOps.postMap]] + * - [[ExprOps.foldRight foldRight]] + * - [[ExprOps.preTraversal preTraversal]] + * - [[ExprOps.postTraversal postTraversal]] + * - [[ExprOps.preMap preMap]] + * - [[ExprOps.postMap postMap]] + * - [[ExprOps.genericTransform genericTransform]] * * These operations usually take a higher order function that gets apply to the * expression tree in some strategy. They provide an expressive way to build complex - * operation on Leon expressions. + * operations on Leon expressions. * */ object ExprOps { @@ -212,6 +213,47 @@ object ExprOps { } + + /** Applies functions and combines results in a generic way + * + * Start with an initial value, and apply functions to nodes before + * and after the recursion in the children. Combine the results of + * all children and apply a final function on the resulting node. + * + * @param pre a function applied on a node before doing a recursion in the children + * @param post a function applied to the node built from the recursive application to + all children + * @param combiner a function to combine the resulting values from all children with + the current node + * @param init the initial value + * @param expr the expression on which to apply the transform + * + * @see [[simpleTransform]] + * @see [[simplePreTransform]] + * @see [[simplePostTransform]] + */ + def genericTransform[C](pre: (Expr, C) => (Expr, C), + post: (Expr, C) => (Expr, C), + combiner: (Expr, Seq[C]) => C)(init: C)(expr: Expr) = { + + def rec(eIn: Expr, cIn: C): (Expr, C) = { + + val (expr, ctx) = pre(eIn, cIn) + val Operator(es, builder) = expr + val (newExpr, newC) = { + val (nes, cs) = es.map{ rec(_, ctx)}.unzip + val newE = builder(nes).copiedFrom(expr) + + (newE, combiner(newE, cs)) + } + + post(newExpr, newC) + } + + rec(expr, init) + } + + /* * ============= * Auxiliary API @@ -997,27 +1039,6 @@ object ExprOps { postMap(transform, applyRec = true)(expr) } - def genericTransform[C](pre: (Expr, C) => (Expr, C), - post: (Expr, C) => (Expr, C), - combiner: (Expr, Seq[C]) => C)(init: C)(expr: Expr) = { - - def rec(eIn: Expr, cIn: C): (Expr, C) = { - - val (expr, ctx) = pre(eIn, cIn) - val Operator(es, builder) = expr - val (newExpr, newC) = { - val (nes, cs) = es.map{ rec(_, ctx)}.unzip - val newE = builder(nes).copiedFrom(expr) - - (newE, combiner(newE, cs)) - } - - post(newExpr, newC) - } - - rec(expr, init) - } - private def noCombiner(e: Expr, subCs: Seq[Unit]) = () private def noTransformer[C](e: Expr, c: C) = (e, c) -- GitLab