public void BottomUpRewriter_NumToArith_Partial_FallbackWithPredicate() { var logger = new StringWriter(); var burw = new BottomUpRewriter <NumExpr, NumNodeType, ArithExpr, NumWildcardFactory> { // Leaf nodes Leaves = { { (Val c) => new Const(c.Value), 1 }, }, // Tree patterns Rules = { { (l, r) => new Plus(l, r), (l, r) => new Add(l, r), 2 }, { (a, b, c) => new TimesPlus(a, b, c), (a, b, c) => new Add(new Mul(a, b), c), 2}, { x => new Inc(x), x => new Add(x, new Const(1)), 2 }, }, // Fallback rules Fallbacks = { { n => new Const(((Times)n).Let(t => t.Left.Eval() * t.Right.Eval())), n => n.Value == NumNodeType.Times, 1 }, }, Log = logger }; // Internal tables var debugView = burw.DebugView; Assert.IsTrue(!string.IsNullOrEmpty(debugView)); var e = new TimesPlus( new Inc( new Times( new Val(2), new Val(3) ) ), new Times( new Val(4), new Val(5) ), new Val(6) ); var res = burw.Rewrite(e); Assert.AreEqual("Add(Mul(Add(Const(6), Const(1)), Const(20)), Const(6))", res.ToString()); Assert.AreEqual(e.Eval(), res.Eval()); }
public void BottomUpRewriter_NumToArith_Partial_FallbackUnconditional() { var logger = new StringWriter(); var burw = new BottomUpRewriter <NumExpr, NumNodeType, ArithExpr, NumWildcardFactory> { // Leaf nodes Leaves = { { (Val c) => new Const(c.Value), 1 }, }, // Tree patterns Rules = { { (l, r) => new Plus(l, r), (l, r) => new Add(l, r), 2 }, { (a, b, c) => new TimesPlus(a, b, c), (a, b, c) => new Add(new Mul(a, b), c), 2}, { x => new Inc(x), x => new Add(x, new Const(1)), 2 }, }, // Fallback rules Fallbacks = { { n => new Lazy(() => n.Eval()), 1 }, }, Log = logger }; // Internal tables var debugView = burw.DebugView; Assert.IsTrue(!string.IsNullOrEmpty(debugView)); var e = new TimesPlus( new Inc( new Times( new Val(2), new Val(3) ) ), new Times( new Val(4), new Val(5) ), new Val(6) ); var res = burw.Rewrite(e); Assert.IsTrue(res.ToString().Contains("Lazy")); Assert.AreEqual(e.Eval(), res.Eval()); }
public void BottomUpRewriter_ArithToNum() { var logger = new StringWriter(); var burw = new BottomUpRewriter <ArithExpr, ArithNodeType, NumExpr, ArithWildcardFactory> { // Leaf nodes Leaves = { { (Const c) => new Val(c.Value), 1 }, }, // Tree patterns Rules = { { (l, r) => new Add(l, r), (l, r) => new Plus(l, r), 2 }, { (l, r) => new Mul(l, r), (l, r) => new Times(l, r), 3 }, { (a, b, c) => new Add(new Mul(a, b), c), (a, b, c) => new TimesPlus(a, b, c), 4}, { x => new Add(x, new Const(1)), x => new Inc(x), 1 }, }, Log = logger }; // Internal tables var debugView = burw.DebugView; Assert.IsTrue(!string.IsNullOrEmpty(debugView)); var e = new Add( new Mul( new Add( new Mul( new Const(2), new Const(3) ), new Const(1) ), new Mul( new Const(4), new Const(5) ) ), new Const(6) ); var res = burw.Rewrite(e); Assert.AreEqual("TimesPlus(Inc(Times(2, 3)), Times(4, 5), 6)", res.ToString()); Assert.AreEqual(e.Eval(), res.Eval()); }
private static BottomUpRewriter <NumTree, Num, NumTree, NumWildcards> GetNumOptimizer() { var burs = new BottomUpRewriter <NumTree, Num, NumTree, NumWildcards>(); burs.Leaves.Add <ConstNumTree>(c => c, 1); burs.Leaves.Add <ConstNumTree>(c => c, c => c.Value > 0, 1); burs.Rules.Add(() => new UnaryNumTree(NumKind.Negate, ConstNumTree.Zero), () => ConstNumTree.Zero, 1); burs.Rules.Add(n => new BinaryNumTree(NumKind.Add, n, ConstNumTree.Zero), n => n, 1); burs.Rules.Add(n => new BinaryNumTree(NumKind.Add, ConstNumTree.Zero, n), n => n, 1); burs.Rules.Add(n => new BinaryNumTree(NumKind.Multiply, n, ConstNumTree.One), n => n, 1); burs.Rules.Add(n => new BinaryNumTree(NumKind.Multiply, ConstNumTree.One, n), n => n, 1); return(burs); }
public void BottomUpRewriter_ArgumentChecking() { #pragma warning disable IDE0034 // Simplify 'default' expression (illustrative of method signature) AssertEx.ThrowsException <ArgumentNullException>(() => new BottomUpRewriter <ITree <Bar>, Bar, ITree <Foo>, BarWildcards>(sourceNodeComparer: null), ex => Assert.AreEqual("sourceNodeComparer", ex.ParamName)); var burs = new BottomUpRewriter <ITree <Bar>, Bar, ITree <Foo>, BarWildcards>(); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Leaves.Add(default(Expression <Func <ITree <Bar>, ITree <Foo> > >), 1), ex => Assert.AreEqual("convert", ex.ParamName)); AssertEx.ThrowsException <ArgumentOutOfRangeException>(() => burs.Leaves.Add((ITree <Bar> b) => null, -1), ex => Assert.AreEqual("cost", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Leaves.Add(default(Expression <Func <ITree <Bar>, ITree <Foo> > >), (ITree <Bar> b) => true, 1), ex => Assert.AreEqual("convert", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Leaves.Add((ITree <Bar> b) => null, default(Expression <Func <ITree <Bar>, bool> >), 1), ex => Assert.AreEqual("predicate", ex.ParamName)); AssertEx.ThrowsException <ArgumentOutOfRangeException>(() => burs.Leaves.Add((ITree <Bar> b) => null, (ITree <Bar> b) => true, -1), ex => Assert.AreEqual("cost", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Rules.Add(pattern: null, () => null, 1), ex => Assert.AreEqual("pattern", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Rules.Add(() => null, goal: null, 1), ex => Assert.AreEqual("goal", ex.ParamName)); AssertEx.ThrowsException <ArgumentOutOfRangeException>(() => burs.Rules.Add(() => null, () => null, -1), ex => Assert.AreEqual("cost", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Rules.Add(pattern: null, (f1) => f1, 1), ex => Assert.AreEqual("pattern", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Rules.Add((b1) => b1, goal: null, 1), ex => Assert.AreEqual("goal", ex.ParamName)); AssertEx.ThrowsException <ArgumentOutOfRangeException>(() => burs.Rules.Add((b1) => b1, (f1) => f1, -1), ex => Assert.AreEqual("cost", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Rules.Add(pattern: null, (f1, f2) => f1, 1), ex => Assert.AreEqual("pattern", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Rules.Add((b1, b2) => b1, goal: null, 1), ex => Assert.AreEqual("goal", ex.ParamName)); AssertEx.ThrowsException <ArgumentOutOfRangeException>(() => burs.Rules.Add((b1, b2) => b1, (f1, f2) => f1, -1), ex => Assert.AreEqual("cost", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Rules.Add(pattern: null, (f1, f2, f3) => f1, 1), ex => Assert.AreEqual("pattern", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Rules.Add((b1, b2, b3) => b1, goal: null, 1), ex => Assert.AreEqual("goal", ex.ParamName)); AssertEx.ThrowsException <ArgumentOutOfRangeException>(() => burs.Rules.Add((b1, b2, b3) => b1, (f1, f2, f3) => f1, -1), ex => Assert.AreEqual("cost", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Fallbacks.Add(default(Expression <Func <ITree <Bar>, ITree <Foo> > >), 1), ex => Assert.AreEqual("convert", ex.ParamName)); AssertEx.ThrowsException <ArgumentOutOfRangeException>(() => burs.Fallbacks.Add((ITree <Bar> b) => null, -1), ex => Assert.AreEqual("cost", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Fallbacks.Add(default(Expression <Func <ITree <Bar>, ITree <Foo> > >), (ITree <Bar> b) => true, 1), ex => Assert.AreEqual("convert", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => burs.Fallbacks.Add((ITree <Bar> b) => null, default(Expression <Func <ITree <Bar>, bool> >), 1), ex => Assert.AreEqual("predicate", ex.ParamName)); AssertEx.ThrowsException <ArgumentOutOfRangeException>(() => burs.Fallbacks.Add((ITree <Bar> b) => null, (ITree <Bar> b) => true, -1), ex => Assert.AreEqual("cost", ex.ParamName)); #pragma warning restore IDE0034 // Simplify 'default' expression var mb = new MyBurs(); mb.Fallbacks.Add(b => null, 1); mb.Leaves.Add <ITree <Bar> >(b => null, 1); mb.Rules.Add(b => null, f => null, 1); Assert.AreEqual(3, mb.Count); }
public void BottomUpRewriter_NumToArith_Partial_Irreducible() { var logger = new StringWriter(); var burw = new BottomUpRewriter <NumExpr, NumNodeType, ArithExpr, NumWildcardFactory> { // Leaf nodes Leaves = { { (Val c) => new Const(c.Value), 1 }, }, // Tree patterns Rules = { { (l, r) => new Plus(l, r), (l, r) => new Add(l, r), 2 }, { (a, b, c) => new TimesPlus(a, b, c), (a, b, c) => new Add(new Mul(a, b), c), 2}, { x => new Inc(x), x => new Add(x, new Const(1)), 2 }, }, Log = logger }; // Internal tables var debugView = burw.DebugView; Assert.IsTrue(!string.IsNullOrEmpty(debugView)); var e = new TimesPlus( new Inc( new Times( new Val(2), new Val(3) ) ), new Times( new Val(4), new Val(5) ), new Val(6) ); Assert.ThrowsException <InvalidOperationException>(() => burw.Rewrite(e)); }
public void BottomUpRewriter_UnusedWildcard() { var burs = new BottomUpRewriter <NumTree, Num, NumTree, NumWildcards>(); Assert.ThrowsException <InvalidOperationException>(() => burs.Rules.Add((a, b, c) => new BinaryNumTree(NumKind.Add, a, b), (a, b, c) => a, 1)); }