From 1fa10b3463575aa49196e827d5b90406970dd56d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=20Sinan=20K=C3=B6ksal?= <alisinan@gmail.com> Date: Mon, 9 May 2011 11:52:02 +0000 Subject: [PATCH] Automatically generate all code depending on a specific arity of terms --- src/cp/Converter.scala | 31 +- src/cp/Definitions.scala | 7 + src/cp/Terms.scala | 1453 ++++++++++++++++++++++++++++++++++---- src/cp/Utils.scala | 213 +++++- 4 files changed, 1555 insertions(+), 149 deletions(-) diff --git a/src/cp/Converter.scala b/src/cp/Converter.scala index 559308e34..05c14b73a 100644 --- a/src/cp/Converter.scala +++ b/src/cp/Converter.scala @@ -5,12 +5,31 @@ import purescala.Trees._ /** A converter has functions for converting FunCheck expressions into Scala * values */ class Converter(expr2scala : (Expr => Any)) { - def exprSeq2scala1[A](exprs: Seq[Expr]) : A = - expr2scala(exprs(0)).asInstanceOf[A] + def exprSeq2scala1[T1](exprs : Seq[Expr]) : (T1) = + (expr2scala(exprs(0)).asInstanceOf[T1]) - def exprSeq2scala2[A,B](exprs: Seq[Expr]) : (A,B) = - (expr2scala(exprs(0)).asInstanceOf[A], expr2scala(exprs(1)).asInstanceOf[B]) + def exprSeq2scala2[T1,T2](exprs : Seq[Expr]) : (T1,T2) = + (expr2scala(exprs(0)).asInstanceOf[T1],expr2scala(exprs(1)).asInstanceOf[T2]) + + def exprSeq2scala3[T1,T2,T3](exprs : Seq[Expr]) : (T1,T2,T3) = + (expr2scala(exprs(0)).asInstanceOf[T1],expr2scala(exprs(1)).asInstanceOf[T2],expr2scala(exprs(2)).asInstanceOf[T3]) + + def exprSeq2scala4[T1,T2,T3,T4](exprs : Seq[Expr]) : (T1,T2,T3,T4) = + (expr2scala(exprs(0)).asInstanceOf[T1],expr2scala(exprs(1)).asInstanceOf[T2],expr2scala(exprs(2)).asInstanceOf[T3],expr2scala(exprs(3)).asInstanceOf[T4]) + + def exprSeq2scala5[T1,T2,T3,T4,T5](exprs : Seq[Expr]) : (T1,T2,T3,T4,T5) = + (expr2scala(exprs(0)).asInstanceOf[T1],expr2scala(exprs(1)).asInstanceOf[T2],expr2scala(exprs(2)).asInstanceOf[T3],expr2scala(exprs(3)).asInstanceOf[T4],expr2scala(exprs(4)).asInstanceOf[T5]) + + def exprSeq2scala6[T1,T2,T3,T4,T5,T6](exprs : Seq[Expr]) : (T1,T2,T3,T4,T5,T6) = + (expr2scala(exprs(0)).asInstanceOf[T1],expr2scala(exprs(1)).asInstanceOf[T2],expr2scala(exprs(2)).asInstanceOf[T3],expr2scala(exprs(3)).asInstanceOf[T4],expr2scala(exprs(4)).asInstanceOf[T5],expr2scala(exprs(5)).asInstanceOf[T6]) + + def exprSeq2scala7[T1,T2,T3,T4,T5,T6,T7](exprs : Seq[Expr]) : (T1,T2,T3,T4,T5,T6,T7) = + (expr2scala(exprs(0)).asInstanceOf[T1],expr2scala(exprs(1)).asInstanceOf[T2],expr2scala(exprs(2)).asInstanceOf[T3],expr2scala(exprs(3)).asInstanceOf[T4],expr2scala(exprs(4)).asInstanceOf[T5],expr2scala(exprs(5)).asInstanceOf[T6],expr2scala(exprs(6)).asInstanceOf[T7]) + + def exprSeq2scala8[T1,T2,T3,T4,T5,T6,T7,T8](exprs : Seq[Expr]) : (T1,T2,T3,T4,T5,T6,T7,T8) = + (expr2scala(exprs(0)).asInstanceOf[T1],expr2scala(exprs(1)).asInstanceOf[T2],expr2scala(exprs(2)).asInstanceOf[T3],expr2scala(exprs(3)).asInstanceOf[T4],expr2scala(exprs(4)).asInstanceOf[T5],expr2scala(exprs(5)).asInstanceOf[T6],expr2scala(exprs(6)).asInstanceOf[T7],expr2scala(exprs(7)).asInstanceOf[T8]) + + def exprSeq2scala9[T1,T2,T3,T4,T5,T6,T7,T8,T9](exprs : Seq[Expr]) : (T1,T2,T3,T4,T5,T6,T7,T8,T9) = + (expr2scala(exprs(0)).asInstanceOf[T1],expr2scala(exprs(1)).asInstanceOf[T2],expr2scala(exprs(2)).asInstanceOf[T3],expr2scala(exprs(3)).asInstanceOf[T4],expr2scala(exprs(4)).asInstanceOf[T5],expr2scala(exprs(5)).asInstanceOf[T6],expr2scala(exprs(6)).asInstanceOf[T7],expr2scala(exprs(7)).asInstanceOf[T8],expr2scala(exprs(8)).asInstanceOf[T9]) - def exprSeq2scala3[A,B,C](exprs: Seq[Expr]) : (A,B,C) = - (expr2scala(exprs(0)).asInstanceOf[A], expr2scala(exprs(1)).asInstanceOf[B], expr2scala(exprs(2)).asInstanceOf[C]) } diff --git a/src/cp/Definitions.scala b/src/cp/Definitions.scala index 3ed534056..0210fa093 100644 --- a/src/cp/Definitions.scala +++ b/src/cp/Definitions.scala @@ -12,6 +12,13 @@ object Definitions { implicit def func2term1[T1,R](func : T1 => R) : Term1[T1,R] = throw new NotImplementedException implicit def func2term2[T1,T2,R](func : (T1,T2) => R) : Term2[T1,T2,R] = throw new NotImplementedException + implicit def func2term3[T1,T2,T3,R](func : (T1,T2,T3) => R) : Term3[T1,T2,T3,R] = throw new NotImplementedException + implicit def func2term4[T1,T2,T3,T4,R](func : (T1,T2,T3,T4) => R) : Term4[T1,T2,T3,T4,R] = throw new NotImplementedException + implicit def func2term5[T1,T2,T3,T4,T5,R](func : (T1,T2,T3,T4,T5) => R) : Term5[T1,T2,T3,T4,T5,R] = throw new NotImplementedException + implicit def func2term6[T1,T2,T3,T4,T5,T6,R](func : (T1,T2,T3,T4,T5,T6) => R) : Term6[T1,T2,T3,T4,T5,T6,R] = throw new NotImplementedException + implicit def func2term7[T1,T2,T3,T4,T5,T6,T7,R](func : (T1,T2,T3,T4,T5,T6,T7) => R) : Term7[T1,T2,T3,T4,T5,T6,T7,R] = throw new NotImplementedException + implicit def func2term8[T1,T2,T3,T4,T5,T6,T7,T8,R](func : (T1,T2,T3,T4,T5,T6,T7,T8) => R) : Term8[T1,T2,T3,T4,T5,T6,T7,T8,R] = throw new NotImplementedException + implicit def func2term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R](func : (T1,T2,T3,T4,T5,T6,T7,T8,T9) => R) : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R] = throw new NotImplementedException def distinct[A](args: A*) : Boolean = { args.toList.distinct.size == args.size diff --git a/src/cp/Terms.scala b/src/cp/Terms.scala index 3bcc32d94..5faf87ddb 100644 --- a/src/cp/Terms.scala +++ b/src/cp/Terms.scala @@ -35,211 +35,621 @@ object Terms { } } - /** Terms with one argument */ - sealed trait Term1[T1,R] extends Term[T1,R] { + /** Contains helper methods for constructing base terms */ + object Term { + def processArgs(converter : Converter, serializedProg : Serialized, serializedInputVars : Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) : (Converter,Program,Expr,Seq[TypeTree]) = { + val program : Program = deserialize[Program](serializedProg) + val inputVars : Seq[Variable] = deserialize[Seq[Variable]](serializedInputVars) + val outputVars : Seq[Identifier] = deserialize[Seq[Identifier]](serializedOutputVars) + val initialExpr : Expr = deserialize[Expr](serializedExpr) + + val env : Map[Expr,Expr] = (inputVars zip inputVarValues).toMap + val deBruijnIndices: Seq[DeBruijnIndex] = outputVars.zipWithIndex.map{ case (v, idx) => DeBruijnIndex(idx).setType(v.getType) } + val exprWithIndices: Expr = replace(((outputVars map (Variable(_))) zip deBruijnIndices).toMap, initialExpr) + + val expr : Expr = replace(env, exprWithIndices) + val types : Seq[TypeTree] = outputVars.map(_.getType) + (converter, program, expr, types) + } + } + + /* this is for Constraint2[A,B] + def proj0 : Constraint1[A] = this.asInstanceOf[Constraint] match { + case BaseTerm(conv,pr,ex,ts) => { + val deBruijnIndices = ts.zipWithIndex.map{ case (t,idx) => DeBruijnIndex(idx).setType(t) } + val freshIDs = deBruijnIndices.tail.zipWithIndex.map{ case (dbi, i) => FreshIdentifier("x" + i).setType(dbi.getType) } + val subst = deBruijnIndices.tail.zip(freshIDs map (Variable)).toMap[Expr,Expr] + new BaseTerm[Boolean](conv, pr, replace(subst, ex), ts.take(1)) with Constraint1[A] + } + case NotConstraint2(c) => NotConstraint1[A](c.asInstanceOf[Constraint2[A,B]].proj0) + case OrConstraint2(cs) => OrConstraint1[A](cs map (c => c.asInstanceOf[Constraint2[A,B]].proj0)) + case AndConstraint2(cs) => AndConstraint1[A](cs map (c => c.asInstanceOf[Constraint2[A,B]].proj0)) + case _ => error("Cannot reach this") + } + */ + + /** A constraint is just a term with Boolean range */ + type Constraint[T] = Term[T,Boolean] + type Constraint1[T1] = Term1[T1,Boolean] + type Constraint2[T1,T2] = Term2[T1,T2,Boolean] + type Constraint3[T1,T2,T3] = Term3[T1,T2,T3,Boolean] + type Constraint4[T1,T2,T3,T4] = Term4[T1,T2,T3,T4,Boolean] + type Constraint5[T1,T2,T3,T4,T5] = Term5[T1,T2,T3,T4,T5,Boolean] + type Constraint6[T1,T2,T3,T4,T5,T6] = Term6[T1,T2,T3,T4,T5,T6,Boolean] + type Constraint7[T1,T2,T3,T4,T5,T6,T7] = Term7[T1,T2,T3,T4,T5,T6,T7,Boolean] + type Constraint8[T1,T2,T3,T4,T5,T6,T7,T8] = Term8[T1,T2,T3,T4,T5,T6,T7,T8,Boolean] + type Constraint9[T1,T2,T3,T4,T5,T6,T7,T8,T9] = Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Boolean] + type IntTerm[T] = Term[T,Int] + type IntTerm1[T1] = Term1[T1,Int] + type IntTerm2[T1,T2] = Term2[T1,T2,Int] + type IntTerm3[T1,T2,T3] = Term3[T1,T2,T3,Int] + type IntTerm4[T1,T2,T3,T4] = Term4[T1,T2,T3,T4,Int] + type IntTerm5[T1,T2,T3,T4,T5] = Term5[T1,T2,T3,T4,T5,Int] + type IntTerm6[T1,T2,T3,T4,T5,T6] = Term6[T1,T2,T3,T4,T5,T6,Int] + type IntTerm7[T1,T2,T3,T4,T5,T6,T7] = Term7[T1,T2,T3,T4,T5,T6,T7,Int] + type IntTerm8[T1,T2,T3,T4,T5,T6,T7,T8] = Term8[T1,T2,T3,T4,T5,T6,T7,T8,Int] + type IntTerm9[T1,T2,T3,T4,T5,T6,T7,T8,T9] = Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Int] + + sealed trait Term1[T1,R] extends Term[(T1),R] { val convertingFunction = converterOf(this).exprSeq2scala1[T1] _ type t2c = (Term1[T1,R]) => Term1[T1,Boolean] + + def ||(other : Term1[T1,Boolean])(implicit asConstraint : t2c) : Term1[T1,Boolean] = OrConstraint1[T1](this, other) - def minimizing(minFunc : IntTerm1[T1])(implicit asConstraint: t2c) : MinConstraint1[T1] = { - MinConstraint1[T1](asConstraint(this), minFunc) - } - - def ||(other : Constraint1[T1])(implicit asConstraint: t2c) : Constraint1[T1] = OrConstraint1[T1](asConstraint(this), other) + def &&(other : Term1[T1,Boolean])(implicit asConstraint : t2c) : Term1[T1,Boolean] = AndConstraint1[T1](this, other) - def &&(other : Constraint1[T1])(implicit asConstraint: t2c) : Constraint1[T1] = AndConstraint1[T1](asConstraint(this), other) + def unary_!(implicit asConstraint : t2c) : Term1[T1,Boolean] = NotConstraint1[T1](this) - def unary_!(implicit asConstraint: t2c) : Constraint1[T1] = NotConstraint1[T1](asConstraint(this)) + def minimizing(minFunc : Term1[T1,Int])(implicit asConstraint : t2c) : MinConstraint1[T1] = { + MinConstraint1[T1](asConstraint(this), minFunc) + } - /** function composition this ∘ other */ - def compose0[A](other : Term1[A,T1]) : Term1[A,R] = compose_0_1_1(other, this) - def compose0[A,B](other : Term2[A,B,T1]) : Term2[A,B,R] = compose_0_2_1(other, this) + def compose0[A1](other : Term1[A1,T1]) : Term1[A1,R] = compose_0_1_1(other, this) + def compose0[A1,A2](other : Term2[A1,A2,T1]) : Term2[A1,A2,R] = compose_0_2_1(other, this) + def compose0[A1,A2,A3](other : Term3[A1,A2,A3,T1]) : Term3[A1,A2,A3,R] = compose_0_3_1(other, this) + def compose0[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T1]) : Term4[A1,A2,A3,A4,R] = compose_0_4_1(other, this) + def compose0[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T1]) : Term5[A1,A2,A3,A4,A5,R] = compose_0_5_1(other, this) + def compose0[A1,A2,A3,A4,A5,A6](other : Term6[A1,A2,A3,A4,A5,A6,T1]) : Term6[A1,A2,A3,A4,A5,A6,R] = compose_0_6_1(other, this) + def compose0[A1,A2,A3,A4,A5,A6,A7](other : Term7[A1,A2,A3,A4,A5,A6,A7,T1]) : Term7[A1,A2,A3,A4,A5,A6,A7,R] = compose_0_7_1(other, this) + def compose0[A1,A2,A3,A4,A5,A6,A7,A8](other : Term8[A1,A2,A3,A4,A5,A6,A7,A8,T1]) : Term8[A1,A2,A3,A4,A5,A6,A7,A8,R] = compose_0_8_1(other, this) + def compose0[A1,A2,A3,A4,A5,A6,A7,A8,A9](other : Term9[A1,A2,A3,A4,A5,A6,A7,A8,A9,T1]) : Term9[A1,A2,A3,A4,A5,A6,A7,A8,A9,R] = compose_0_9_1(other, this) } - /** Terms with two arguments */ sealed trait Term2[T1,T2,R] extends Term[(T1,T2),R] { val convertingFunction = converterOf(this).exprSeq2scala2[T1,T2] _ type t2c = (Term2[T1,T2,R]) => Term2[T1,T2,Boolean] + + def ||(other : Term2[T1,T2,Boolean])(implicit asConstraint : t2c) : Term2[T1,T2,Boolean] = OrConstraint2[T1,T2](this, other) - def minimizing(minFunc : IntTerm2[T1,T2])(implicit asConstraint: t2c) : MinConstraint2[T1,T2] = - MinConstraint2[T1,T2](asConstraint(this), minFunc) - - def ||(other : Constraint2[T1,T2])(implicit asConstraint: t2c) : Constraint2[T1,T2] = OrConstraint2[T1,T2](this, other) + def &&(other : Term2[T1,T2,Boolean])(implicit asConstraint : t2c) : Term2[T1,T2,Boolean] = AndConstraint2[T1,T2](this, other) - def &&(other : Constraint2[T1,T2])(implicit asConstraint: t2c) : Constraint2[T1,T2] = AndConstraint2[T1,T2](this, other) + def unary_!(implicit asConstraint : t2c) : Term2[T1,T2,Boolean] = NotConstraint2[T1,T2](this) - def unary_!(implicit asConstraint: t2c) : Constraint2[T1,T2] = NotConstraint2[T1,T2](this) + def minimizing(minFunc : Term2[T1,T2,Int])(implicit asConstraint : t2c) : MinConstraint2[T1,T2] = { + MinConstraint2[T1,T2](asConstraint(this), minFunc) + } - def compose0[A](other : Term1[A, T1]) : Term2[A,T2,R] = compose_0_1_2(other, this) - def compose1[A](other : Term1[A, T2]) : Term2[T1,A,R] = compose_1_1_2(other, this) + def compose0[A1](other : Term1[A1,T1]) : Term2[A1,T2,R] = compose_0_1_2(other, this) + def compose1[A1](other : Term1[A1,T2]) : Term2[T1,A1,R] = compose_1_1_2(other, this) + def compose0[A1,A2](other : Term2[A1,A2,T1]) : Term3[A1,A2,T2,R] = compose_0_2_2(other, this) + def compose1[A1,A2](other : Term2[A1,A2,T2]) : Term3[T1,A1,A2,R] = compose_1_2_2(other, this) + def compose0[A1,A2,A3](other : Term3[A1,A2,A3,T1]) : Term4[A1,A2,A3,T2,R] = compose_0_3_2(other, this) + def compose1[A1,A2,A3](other : Term3[A1,A2,A3,T2]) : Term4[T1,A1,A2,A3,R] = compose_1_3_2(other, this) + def compose0[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T1]) : Term5[A1,A2,A3,A4,T2,R] = compose_0_4_2(other, this) + def compose1[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T2]) : Term5[T1,A1,A2,A3,A4,R] = compose_1_4_2(other, this) + def compose0[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T1]) : Term6[A1,A2,A3,A4,A5,T2,R] = compose_0_5_2(other, this) + def compose1[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T2]) : Term6[T1,A1,A2,A3,A4,A5,R] = compose_1_5_2(other, this) + def compose0[A1,A2,A3,A4,A5,A6](other : Term6[A1,A2,A3,A4,A5,A6,T1]) : Term7[A1,A2,A3,A4,A5,A6,T2,R] = compose_0_6_2(other, this) + def compose1[A1,A2,A3,A4,A5,A6](other : Term6[A1,A2,A3,A4,A5,A6,T2]) : Term7[T1,A1,A2,A3,A4,A5,A6,R] = compose_1_6_2(other, this) + def compose0[A1,A2,A3,A4,A5,A6,A7](other : Term7[A1,A2,A3,A4,A5,A6,A7,T1]) : Term8[A1,A2,A3,A4,A5,A6,A7,T2,R] = compose_0_7_2(other, this) + def compose1[A1,A2,A3,A4,A5,A6,A7](other : Term7[A1,A2,A3,A4,A5,A6,A7,T2]) : Term8[T1,A1,A2,A3,A4,A5,A6,A7,R] = compose_1_7_2(other, this) + def compose0[A1,A2,A3,A4,A5,A6,A7,A8](other : Term8[A1,A2,A3,A4,A5,A6,A7,A8,T1]) : Term9[A1,A2,A3,A4,A5,A6,A7,A8,T2,R] = compose_0_8_2(other, this) + def compose1[A1,A2,A3,A4,A5,A6,A7,A8](other : Term8[A1,A2,A3,A4,A5,A6,A7,A8,T2]) : Term9[T1,A1,A2,A3,A4,A5,A6,A7,A8,R] = compose_1_8_2(other, this) } - /** Terms with three arguments */ sealed trait Term3[T1,T2,T3,R] extends Term[(T1,T2,T3),R] { val convertingFunction = converterOf(this).exprSeq2scala3[T1,T2,T3] _ type t2c = (Term3[T1,T2,T3,R]) => Term3[T1,T2,T3,Boolean] + + def ||(other : Term3[T1,T2,T3,Boolean])(implicit asConstraint : t2c) : Term3[T1,T2,T3,Boolean] = OrConstraint3[T1,T2,T3](this, other) - def minimizing(minFunc : IntTerm3[T1,T2,T3])(implicit asConstraint: t2c) : MinConstraint3[T1,T2,T3] = + def &&(other : Term3[T1,T2,T3,Boolean])(implicit asConstraint : t2c) : Term3[T1,T2,T3,Boolean] = AndConstraint3[T1,T2,T3](this, other) + + def unary_!(implicit asConstraint : t2c) : Term3[T1,T2,T3,Boolean] = NotConstraint3[T1,T2,T3](this) + + def minimizing(minFunc : Term3[T1,T2,T3,Int])(implicit asConstraint : t2c) : MinConstraint3[T1,T2,T3] = { MinConstraint3[T1,T2,T3](asConstraint(this), minFunc) - - def ||(other : Constraint3[T1,T2,T3])(implicit asConstraint: t2c) : Constraint3[T1,T2,T3] = OrConstraint3[T1,T2,T3](this, other) + } + + def compose0[A1](other : Term1[A1,T1]) : Term3[A1,T2,T3,R] = compose_0_1_3(other, this) + def compose1[A1](other : Term1[A1,T2]) : Term3[T1,A1,T3,R] = compose_1_1_3(other, this) + def compose2[A1](other : Term1[A1,T3]) : Term3[T1,T2,A1,R] = compose_2_1_3(other, this) + def compose0[A1,A2](other : Term2[A1,A2,T1]) : Term4[A1,A2,T2,T3,R] = compose_0_2_3(other, this) + def compose1[A1,A2](other : Term2[A1,A2,T2]) : Term4[T1,A1,A2,T3,R] = compose_1_2_3(other, this) + def compose2[A1,A2](other : Term2[A1,A2,T3]) : Term4[T1,T2,A1,A2,R] = compose_2_2_3(other, this) + def compose0[A1,A2,A3](other : Term3[A1,A2,A3,T1]) : Term5[A1,A2,A3,T2,T3,R] = compose_0_3_3(other, this) + def compose1[A1,A2,A3](other : Term3[A1,A2,A3,T2]) : Term5[T1,A1,A2,A3,T3,R] = compose_1_3_3(other, this) + def compose2[A1,A2,A3](other : Term3[A1,A2,A3,T3]) : Term5[T1,T2,A1,A2,A3,R] = compose_2_3_3(other, this) + def compose0[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T1]) : Term6[A1,A2,A3,A4,T2,T3,R] = compose_0_4_3(other, this) + def compose1[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T2]) : Term6[T1,A1,A2,A3,A4,T3,R] = compose_1_4_3(other, this) + def compose2[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T3]) : Term6[T1,T2,A1,A2,A3,A4,R] = compose_2_4_3(other, this) + def compose0[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T1]) : Term7[A1,A2,A3,A4,A5,T2,T3,R] = compose_0_5_3(other, this) + def compose1[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T2]) : Term7[T1,A1,A2,A3,A4,A5,T3,R] = compose_1_5_3(other, this) + def compose2[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T3]) : Term7[T1,T2,A1,A2,A3,A4,A5,R] = compose_2_5_3(other, this) + def compose0[A1,A2,A3,A4,A5,A6](other : Term6[A1,A2,A3,A4,A5,A6,T1]) : Term8[A1,A2,A3,A4,A5,A6,T2,T3,R] = compose_0_6_3(other, this) + def compose1[A1,A2,A3,A4,A5,A6](other : Term6[A1,A2,A3,A4,A5,A6,T2]) : Term8[T1,A1,A2,A3,A4,A5,A6,T3,R] = compose_1_6_3(other, this) + def compose2[A1,A2,A3,A4,A5,A6](other : Term6[A1,A2,A3,A4,A5,A6,T3]) : Term8[T1,T2,A1,A2,A3,A4,A5,A6,R] = compose_2_6_3(other, this) + def compose0[A1,A2,A3,A4,A5,A6,A7](other : Term7[A1,A2,A3,A4,A5,A6,A7,T1]) : Term9[A1,A2,A3,A4,A5,A6,A7,T2,T3,R] = compose_0_7_3(other, this) + def compose1[A1,A2,A3,A4,A5,A6,A7](other : Term7[A1,A2,A3,A4,A5,A6,A7,T2]) : Term9[T1,A1,A2,A3,A4,A5,A6,A7,T3,R] = compose_1_7_3(other, this) + def compose2[A1,A2,A3,A4,A5,A6,A7](other : Term7[A1,A2,A3,A4,A5,A6,A7,T3]) : Term9[T1,T2,A1,A2,A3,A4,A5,A6,A7,R] = compose_2_7_3(other, this) + } + + sealed trait Term4[T1,T2,T3,T4,R] extends Term[(T1,T2,T3,T4),R] { + val convertingFunction = converterOf(this).exprSeq2scala4[T1,T2,T3,T4] _ + type t2c = (Term4[T1,T2,T3,T4,R]) => Term4[T1,T2,T3,T4,Boolean] + + def ||(other : Term4[T1,T2,T3,T4,Boolean])(implicit asConstraint : t2c) : Term4[T1,T2,T3,T4,Boolean] = OrConstraint4[T1,T2,T3,T4](this, other) + + def &&(other : Term4[T1,T2,T3,T4,Boolean])(implicit asConstraint : t2c) : Term4[T1,T2,T3,T4,Boolean] = AndConstraint4[T1,T2,T3,T4](this, other) - def &&(other : Constraint3[T1,T2,T3])(implicit asConstraint: t2c) : Constraint3[T1,T2,T3] = AndConstraint3[T1,T2,T3](this, other) + def unary_!(implicit asConstraint : t2c) : Term4[T1,T2,T3,T4,Boolean] = NotConstraint4[T1,T2,T3,T4](this) - def unary_!(implicit asConstraint: t2c) : Constraint3[T1,T2,T3] = NotConstraint3[T1,T2,T3](this) + def minimizing(minFunc : Term4[T1,T2,T3,T4,Int])(implicit asConstraint : t2c) : MinConstraint4[T1,T2,T3,T4] = { + MinConstraint4[T1,T2,T3,T4](asConstraint(this), minFunc) + } + + def compose0[A1](other : Term1[A1,T1]) : Term4[A1,T2,T3,T4,R] = compose_0_1_4(other, this) + def compose1[A1](other : Term1[A1,T2]) : Term4[T1,A1,T3,T4,R] = compose_1_1_4(other, this) + def compose2[A1](other : Term1[A1,T3]) : Term4[T1,T2,A1,T4,R] = compose_2_1_4(other, this) + def compose3[A1](other : Term1[A1,T4]) : Term4[T1,T2,T3,A1,R] = compose_3_1_4(other, this) + def compose0[A1,A2](other : Term2[A1,A2,T1]) : Term5[A1,A2,T2,T3,T4,R] = compose_0_2_4(other, this) + def compose1[A1,A2](other : Term2[A1,A2,T2]) : Term5[T1,A1,A2,T3,T4,R] = compose_1_2_4(other, this) + def compose2[A1,A2](other : Term2[A1,A2,T3]) : Term5[T1,T2,A1,A2,T4,R] = compose_2_2_4(other, this) + def compose3[A1,A2](other : Term2[A1,A2,T4]) : Term5[T1,T2,T3,A1,A2,R] = compose_3_2_4(other, this) + def compose0[A1,A2,A3](other : Term3[A1,A2,A3,T1]) : Term6[A1,A2,A3,T2,T3,T4,R] = compose_0_3_4(other, this) + def compose1[A1,A2,A3](other : Term3[A1,A2,A3,T2]) : Term6[T1,A1,A2,A3,T3,T4,R] = compose_1_3_4(other, this) + def compose2[A1,A2,A3](other : Term3[A1,A2,A3,T3]) : Term6[T1,T2,A1,A2,A3,T4,R] = compose_2_3_4(other, this) + def compose3[A1,A2,A3](other : Term3[A1,A2,A3,T4]) : Term6[T1,T2,T3,A1,A2,A3,R] = compose_3_3_4(other, this) + def compose0[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T1]) : Term7[A1,A2,A3,A4,T2,T3,T4,R] = compose_0_4_4(other, this) + def compose1[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T2]) : Term7[T1,A1,A2,A3,A4,T3,T4,R] = compose_1_4_4(other, this) + def compose2[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T3]) : Term7[T1,T2,A1,A2,A3,A4,T4,R] = compose_2_4_4(other, this) + def compose3[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T4]) : Term7[T1,T2,T3,A1,A2,A3,A4,R] = compose_3_4_4(other, this) + def compose0[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T1]) : Term8[A1,A2,A3,A4,A5,T2,T3,T4,R] = compose_0_5_4(other, this) + def compose1[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T2]) : Term8[T1,A1,A2,A3,A4,A5,T3,T4,R] = compose_1_5_4(other, this) + def compose2[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T3]) : Term8[T1,T2,A1,A2,A3,A4,A5,T4,R] = compose_2_5_4(other, this) + def compose3[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T4]) : Term8[T1,T2,T3,A1,A2,A3,A4,A5,R] = compose_3_5_4(other, this) + def compose0[A1,A2,A3,A4,A5,A6](other : Term6[A1,A2,A3,A4,A5,A6,T1]) : Term9[A1,A2,A3,A4,A5,A6,T2,T3,T4,R] = compose_0_6_4(other, this) + def compose1[A1,A2,A3,A4,A5,A6](other : Term6[A1,A2,A3,A4,A5,A6,T2]) : Term9[T1,A1,A2,A3,A4,A5,A6,T3,T4,R] = compose_1_6_4(other, this) + def compose2[A1,A2,A3,A4,A5,A6](other : Term6[A1,A2,A3,A4,A5,A6,T3]) : Term9[T1,T2,A1,A2,A3,A4,A5,A6,T4,R] = compose_2_6_4(other, this) + def compose3[A1,A2,A3,A4,A5,A6](other : Term6[A1,A2,A3,A4,A5,A6,T4]) : Term9[T1,T2,T3,A1,A2,A3,A4,A5,A6,R] = compose_3_6_4(other, this) } - /* this is for Constraint2[A,B] - def proj0 : Constraint1[A] = this.asInstanceOf[Constraint] match { - case BaseTerm(conv,pr,ex,ts) => { - val deBruijnIndices = ts.zipWithIndex.map{ case (t,idx) => DeBruijnIndex(idx).setType(t) } - val freshIDs = deBruijnIndices.tail.zipWithIndex.map{ case (dbi, i) => FreshIdentifier("x" + i).setType(dbi.getType) } - val subst = deBruijnIndices.tail.zip(freshIDs map (Variable)).toMap[Expr,Expr] - new BaseTerm[Boolean](conv, pr, replace(subst, ex), ts.take(1)) with Constraint1[A] - } - case NotConstraint2(c) => NotConstraint1[A](c.asInstanceOf[Constraint2[A,B]].proj0) - case OrConstraint2(cs) => OrConstraint1[A](cs map (c => c.asInstanceOf[Constraint2[A,B]].proj0)) - case AndConstraint2(cs) => AndConstraint1[A](cs map (c => c.asInstanceOf[Constraint2[A,B]].proj0)) - case _ => error("Cannot reach this") + sealed trait Term5[T1,T2,T3,T4,T5,R] extends Term[(T1,T2,T3,T4,T5),R] { + val convertingFunction = converterOf(this).exprSeq2scala5[T1,T2,T3,T4,T5] _ + type t2c = (Term5[T1,T2,T3,T4,T5,R]) => Term5[T1,T2,T3,T4,T5,Boolean] + + def ||(other : Term5[T1,T2,T3,T4,T5,Boolean])(implicit asConstraint : t2c) : Term5[T1,T2,T3,T4,T5,Boolean] = OrConstraint5[T1,T2,T3,T4,T5](this, other) + + def &&(other : Term5[T1,T2,T3,T4,T5,Boolean])(implicit asConstraint : t2c) : Term5[T1,T2,T3,T4,T5,Boolean] = AndConstraint5[T1,T2,T3,T4,T5](this, other) + + def unary_!(implicit asConstraint : t2c) : Term5[T1,T2,T3,T4,T5,Boolean] = NotConstraint5[T1,T2,T3,T4,T5](this) + + def minimizing(minFunc : Term5[T1,T2,T3,T4,T5,Int])(implicit asConstraint : t2c) : MinConstraint5[T1,T2,T3,T4,T5] = { + MinConstraint5[T1,T2,T3,T4,T5](asConstraint(this), minFunc) } - */ - /** Contains helper methods for constructing base terms */ - object Term { - def processArgs(converter : Converter, serializedProg : Serialized, serializedInputVars : Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) : (Converter,Program,Expr,Seq[TypeTree]) = { - val program : Program = deserialize[Program](serializedProg) - val inputVars : Seq[Variable] = deserialize[Seq[Variable]](serializedInputVars) - val outputVars : Seq[Identifier] = deserialize[Seq[Identifier]](serializedOutputVars) - val initialExpr : Expr = deserialize[Expr](serializedExpr) + def compose0[A1](other : Term1[A1,T1]) : Term5[A1,T2,T3,T4,T5,R] = compose_0_1_5(other, this) + def compose1[A1](other : Term1[A1,T2]) : Term5[T1,A1,T3,T4,T5,R] = compose_1_1_5(other, this) + def compose2[A1](other : Term1[A1,T3]) : Term5[T1,T2,A1,T4,T5,R] = compose_2_1_5(other, this) + def compose3[A1](other : Term1[A1,T4]) : Term5[T1,T2,T3,A1,T5,R] = compose_3_1_5(other, this) + def compose4[A1](other : Term1[A1,T5]) : Term5[T1,T2,T3,T4,A1,R] = compose_4_1_5(other, this) + def compose0[A1,A2](other : Term2[A1,A2,T1]) : Term6[A1,A2,T2,T3,T4,T5,R] = compose_0_2_5(other, this) + def compose1[A1,A2](other : Term2[A1,A2,T2]) : Term6[T1,A1,A2,T3,T4,T5,R] = compose_1_2_5(other, this) + def compose2[A1,A2](other : Term2[A1,A2,T3]) : Term6[T1,T2,A1,A2,T4,T5,R] = compose_2_2_5(other, this) + def compose3[A1,A2](other : Term2[A1,A2,T4]) : Term6[T1,T2,T3,A1,A2,T5,R] = compose_3_2_5(other, this) + def compose4[A1,A2](other : Term2[A1,A2,T5]) : Term6[T1,T2,T3,T4,A1,A2,R] = compose_4_2_5(other, this) + def compose0[A1,A2,A3](other : Term3[A1,A2,A3,T1]) : Term7[A1,A2,A3,T2,T3,T4,T5,R] = compose_0_3_5(other, this) + def compose1[A1,A2,A3](other : Term3[A1,A2,A3,T2]) : Term7[T1,A1,A2,A3,T3,T4,T5,R] = compose_1_3_5(other, this) + def compose2[A1,A2,A3](other : Term3[A1,A2,A3,T3]) : Term7[T1,T2,A1,A2,A3,T4,T5,R] = compose_2_3_5(other, this) + def compose3[A1,A2,A3](other : Term3[A1,A2,A3,T4]) : Term7[T1,T2,T3,A1,A2,A3,T5,R] = compose_3_3_5(other, this) + def compose4[A1,A2,A3](other : Term3[A1,A2,A3,T5]) : Term7[T1,T2,T3,T4,A1,A2,A3,R] = compose_4_3_5(other, this) + def compose0[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T1]) : Term8[A1,A2,A3,A4,T2,T3,T4,T5,R] = compose_0_4_5(other, this) + def compose1[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T2]) : Term8[T1,A1,A2,A3,A4,T3,T4,T5,R] = compose_1_4_5(other, this) + def compose2[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T3]) : Term8[T1,T2,A1,A2,A3,A4,T4,T5,R] = compose_2_4_5(other, this) + def compose3[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T4]) : Term8[T1,T2,T3,A1,A2,A3,A4,T5,R] = compose_3_4_5(other, this) + def compose4[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T5]) : Term8[T1,T2,T3,T4,A1,A2,A3,A4,R] = compose_4_4_5(other, this) + def compose0[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T1]) : Term9[A1,A2,A3,A4,A5,T2,T3,T4,T5,R] = compose_0_5_5(other, this) + def compose1[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T2]) : Term9[T1,A1,A2,A3,A4,A5,T3,T4,T5,R] = compose_1_5_5(other, this) + def compose2[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T3]) : Term9[T1,T2,A1,A2,A3,A4,A5,T4,T5,R] = compose_2_5_5(other, this) + def compose3[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T4]) : Term9[T1,T2,T3,A1,A2,A3,A4,A5,T5,R] = compose_3_5_5(other, this) + def compose4[A1,A2,A3,A4,A5](other : Term5[A1,A2,A3,A4,A5,T5]) : Term9[T1,T2,T3,T4,A1,A2,A3,A4,A5,R] = compose_4_5_5(other, this) + } - val env : Map[Expr,Expr] = (inputVars zip inputVarValues).toMap - val deBruijnIndices: Seq[DeBruijnIndex] = outputVars.zipWithIndex.map{ case (v, idx) => DeBruijnIndex(idx).setType(v.getType) } - val exprWithIndices: Expr = replace(((outputVars map (Variable(_))) zip deBruijnIndices).toMap, initialExpr) + sealed trait Term6[T1,T2,T3,T4,T5,T6,R] extends Term[(T1,T2,T3,T4,T5,T6),R] { + val convertingFunction = converterOf(this).exprSeq2scala6[T1,T2,T3,T4,T5,T6] _ + type t2c = (Term6[T1,T2,T3,T4,T5,T6,R]) => Term6[T1,T2,T3,T4,T5,T6,Boolean] + + def ||(other : Term6[T1,T2,T3,T4,T5,T6,Boolean])(implicit asConstraint : t2c) : Term6[T1,T2,T3,T4,T5,T6,Boolean] = OrConstraint6[T1,T2,T3,T4,T5,T6](this, other) - val expr : Expr = replace(env, exprWithIndices) - val types : Seq[TypeTree] = outputVars.map(_.getType) - (converter, program, expr, types) + def &&(other : Term6[T1,T2,T3,T4,T5,T6,Boolean])(implicit asConstraint : t2c) : Term6[T1,T2,T3,T4,T5,T6,Boolean] = AndConstraint6[T1,T2,T3,T4,T5,T6](this, other) + + def unary_!(implicit asConstraint : t2c) : Term6[T1,T2,T3,T4,T5,T6,Boolean] = NotConstraint6[T1,T2,T3,T4,T5,T6](this) + + def minimizing(minFunc : Term6[T1,T2,T3,T4,T5,T6,Int])(implicit asConstraint : t2c) : MinConstraint6[T1,T2,T3,T4,T5,T6] = { + MinConstraint6[T1,T2,T3,T4,T5,T6](asConstraint(this), minFunc) + } + + def compose0[A1](other : Term1[A1,T1]) : Term6[A1,T2,T3,T4,T5,T6,R] = compose_0_1_6(other, this) + def compose1[A1](other : Term1[A1,T2]) : Term6[T1,A1,T3,T4,T5,T6,R] = compose_1_1_6(other, this) + def compose2[A1](other : Term1[A1,T3]) : Term6[T1,T2,A1,T4,T5,T6,R] = compose_2_1_6(other, this) + def compose3[A1](other : Term1[A1,T4]) : Term6[T1,T2,T3,A1,T5,T6,R] = compose_3_1_6(other, this) + def compose4[A1](other : Term1[A1,T5]) : Term6[T1,T2,T3,T4,A1,T6,R] = compose_4_1_6(other, this) + def compose5[A1](other : Term1[A1,T6]) : Term6[T1,T2,T3,T4,T5,A1,R] = compose_5_1_6(other, this) + def compose0[A1,A2](other : Term2[A1,A2,T1]) : Term7[A1,A2,T2,T3,T4,T5,T6,R] = compose_0_2_6(other, this) + def compose1[A1,A2](other : Term2[A1,A2,T2]) : Term7[T1,A1,A2,T3,T4,T5,T6,R] = compose_1_2_6(other, this) + def compose2[A1,A2](other : Term2[A1,A2,T3]) : Term7[T1,T2,A1,A2,T4,T5,T6,R] = compose_2_2_6(other, this) + def compose3[A1,A2](other : Term2[A1,A2,T4]) : Term7[T1,T2,T3,A1,A2,T5,T6,R] = compose_3_2_6(other, this) + def compose4[A1,A2](other : Term2[A1,A2,T5]) : Term7[T1,T2,T3,T4,A1,A2,T6,R] = compose_4_2_6(other, this) + def compose5[A1,A2](other : Term2[A1,A2,T6]) : Term7[T1,T2,T3,T4,T5,A1,A2,R] = compose_5_2_6(other, this) + def compose0[A1,A2,A3](other : Term3[A1,A2,A3,T1]) : Term8[A1,A2,A3,T2,T3,T4,T5,T6,R] = compose_0_3_6(other, this) + def compose1[A1,A2,A3](other : Term3[A1,A2,A3,T2]) : Term8[T1,A1,A2,A3,T3,T4,T5,T6,R] = compose_1_3_6(other, this) + def compose2[A1,A2,A3](other : Term3[A1,A2,A3,T3]) : Term8[T1,T2,A1,A2,A3,T4,T5,T6,R] = compose_2_3_6(other, this) + def compose3[A1,A2,A3](other : Term3[A1,A2,A3,T4]) : Term8[T1,T2,T3,A1,A2,A3,T5,T6,R] = compose_3_3_6(other, this) + def compose4[A1,A2,A3](other : Term3[A1,A2,A3,T5]) : Term8[T1,T2,T3,T4,A1,A2,A3,T6,R] = compose_4_3_6(other, this) + def compose5[A1,A2,A3](other : Term3[A1,A2,A3,T6]) : Term8[T1,T2,T3,T4,T5,A1,A2,A3,R] = compose_5_3_6(other, this) + def compose0[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T1]) : Term9[A1,A2,A3,A4,T2,T3,T4,T5,T6,R] = compose_0_4_6(other, this) + def compose1[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T2]) : Term9[T1,A1,A2,A3,A4,T3,T4,T5,T6,R] = compose_1_4_6(other, this) + def compose2[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T3]) : Term9[T1,T2,A1,A2,A3,A4,T4,T5,T6,R] = compose_2_4_6(other, this) + def compose3[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T4]) : Term9[T1,T2,T3,A1,A2,A3,A4,T5,T6,R] = compose_3_4_6(other, this) + def compose4[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T5]) : Term9[T1,T2,T3,T4,A1,A2,A3,A4,T6,R] = compose_4_4_6(other, this) + def compose5[A1,A2,A3,A4](other : Term4[A1,A2,A3,A4,T6]) : Term9[T1,T2,T3,T4,T5,A1,A2,A3,A4,R] = compose_5_4_6(other, this) + } + + sealed trait Term7[T1,T2,T3,T4,T5,T6,T7,R] extends Term[(T1,T2,T3,T4,T5,T6,T7),R] { + val convertingFunction = converterOf(this).exprSeq2scala7[T1,T2,T3,T4,T5,T6,T7] _ + type t2c = (Term7[T1,T2,T3,T4,T5,T6,T7,R]) => Term7[T1,T2,T3,T4,T5,T6,T7,Boolean] + + def ||(other : Term7[T1,T2,T3,T4,T5,T6,T7,Boolean])(implicit asConstraint : t2c) : Term7[T1,T2,T3,T4,T5,T6,T7,Boolean] = OrConstraint7[T1,T2,T3,T4,T5,T6,T7](this, other) + + def &&(other : Term7[T1,T2,T3,T4,T5,T6,T7,Boolean])(implicit asConstraint : t2c) : Term7[T1,T2,T3,T4,T5,T6,T7,Boolean] = AndConstraint7[T1,T2,T3,T4,T5,T6,T7](this, other) + + def unary_!(implicit asConstraint : t2c) : Term7[T1,T2,T3,T4,T5,T6,T7,Boolean] = NotConstraint7[T1,T2,T3,T4,T5,T6,T7](this) + + def minimizing(minFunc : Term7[T1,T2,T3,T4,T5,T6,T7,Int])(implicit asConstraint : t2c) : MinConstraint7[T1,T2,T3,T4,T5,T6,T7] = { + MinConstraint7[T1,T2,T3,T4,T5,T6,T7](asConstraint(this), minFunc) + } + + def compose0[A1](other : Term1[A1,T1]) : Term7[A1,T2,T3,T4,T5,T6,T7,R] = compose_0_1_7(other, this) + def compose1[A1](other : Term1[A1,T2]) : Term7[T1,A1,T3,T4,T5,T6,T7,R] = compose_1_1_7(other, this) + def compose2[A1](other : Term1[A1,T3]) : Term7[T1,T2,A1,T4,T5,T6,T7,R] = compose_2_1_7(other, this) + def compose3[A1](other : Term1[A1,T4]) : Term7[T1,T2,T3,A1,T5,T6,T7,R] = compose_3_1_7(other, this) + def compose4[A1](other : Term1[A1,T5]) : Term7[T1,T2,T3,T4,A1,T6,T7,R] = compose_4_1_7(other, this) + def compose5[A1](other : Term1[A1,T6]) : Term7[T1,T2,T3,T4,T5,A1,T7,R] = compose_5_1_7(other, this) + def compose6[A1](other : Term1[A1,T7]) : Term7[T1,T2,T3,T4,T5,T6,A1,R] = compose_6_1_7(other, this) + def compose0[A1,A2](other : Term2[A1,A2,T1]) : Term8[A1,A2,T2,T3,T4,T5,T6,T7,R] = compose_0_2_7(other, this) + def compose1[A1,A2](other : Term2[A1,A2,T2]) : Term8[T1,A1,A2,T3,T4,T5,T6,T7,R] = compose_1_2_7(other, this) + def compose2[A1,A2](other : Term2[A1,A2,T3]) : Term8[T1,T2,A1,A2,T4,T5,T6,T7,R] = compose_2_2_7(other, this) + def compose3[A1,A2](other : Term2[A1,A2,T4]) : Term8[T1,T2,T3,A1,A2,T5,T6,T7,R] = compose_3_2_7(other, this) + def compose4[A1,A2](other : Term2[A1,A2,T5]) : Term8[T1,T2,T3,T4,A1,A2,T6,T7,R] = compose_4_2_7(other, this) + def compose5[A1,A2](other : Term2[A1,A2,T6]) : Term8[T1,T2,T3,T4,T5,A1,A2,T7,R] = compose_5_2_7(other, this) + def compose6[A1,A2](other : Term2[A1,A2,T7]) : Term8[T1,T2,T3,T4,T5,T6,A1,A2,R] = compose_6_2_7(other, this) + def compose0[A1,A2,A3](other : Term3[A1,A2,A3,T1]) : Term9[A1,A2,A3,T2,T3,T4,T5,T6,T7,R] = compose_0_3_7(other, this) + def compose1[A1,A2,A3](other : Term3[A1,A2,A3,T2]) : Term9[T1,A1,A2,A3,T3,T4,T5,T6,T7,R] = compose_1_3_7(other, this) + def compose2[A1,A2,A3](other : Term3[A1,A2,A3,T3]) : Term9[T1,T2,A1,A2,A3,T4,T5,T6,T7,R] = compose_2_3_7(other, this) + def compose3[A1,A2,A3](other : Term3[A1,A2,A3,T4]) : Term9[T1,T2,T3,A1,A2,A3,T5,T6,T7,R] = compose_3_3_7(other, this) + def compose4[A1,A2,A3](other : Term3[A1,A2,A3,T5]) : Term9[T1,T2,T3,T4,A1,A2,A3,T6,T7,R] = compose_4_3_7(other, this) + def compose5[A1,A2,A3](other : Term3[A1,A2,A3,T6]) : Term9[T1,T2,T3,T4,T5,A1,A2,A3,T7,R] = compose_5_3_7(other, this) + def compose6[A1,A2,A3](other : Term3[A1,A2,A3,T7]) : Term9[T1,T2,T3,T4,T5,T6,A1,A2,A3,R] = compose_6_3_7(other, this) + } + + sealed trait Term8[T1,T2,T3,T4,T5,T6,T7,T8,R] extends Term[(T1,T2,T3,T4,T5,T6,T7,T8),R] { + val convertingFunction = converterOf(this).exprSeq2scala8[T1,T2,T3,T4,T5,T6,T7,T8] _ + type t2c = (Term8[T1,T2,T3,T4,T5,T6,T7,T8,R]) => Term8[T1,T2,T3,T4,T5,T6,T7,T8,Boolean] + + def ||(other : Term8[T1,T2,T3,T4,T5,T6,T7,T8,Boolean])(implicit asConstraint : t2c) : Term8[T1,T2,T3,T4,T5,T6,T7,T8,Boolean] = OrConstraint8[T1,T2,T3,T4,T5,T6,T7,T8](this, other) + + def &&(other : Term8[T1,T2,T3,T4,T5,T6,T7,T8,Boolean])(implicit asConstraint : t2c) : Term8[T1,T2,T3,T4,T5,T6,T7,T8,Boolean] = AndConstraint8[T1,T2,T3,T4,T5,T6,T7,T8](this, other) + + def unary_!(implicit asConstraint : t2c) : Term8[T1,T2,T3,T4,T5,T6,T7,T8,Boolean] = NotConstraint8[T1,T2,T3,T4,T5,T6,T7,T8](this) + + def minimizing(minFunc : Term8[T1,T2,T3,T4,T5,T6,T7,T8,Int])(implicit asConstraint : t2c) : MinConstraint8[T1,T2,T3,T4,T5,T6,T7,T8] = { + MinConstraint8[T1,T2,T3,T4,T5,T6,T7,T8](asConstraint(this), minFunc) + } + + def compose0[A1](other : Term1[A1,T1]) : Term8[A1,T2,T3,T4,T5,T6,T7,T8,R] = compose_0_1_8(other, this) + def compose1[A1](other : Term1[A1,T2]) : Term8[T1,A1,T3,T4,T5,T6,T7,T8,R] = compose_1_1_8(other, this) + def compose2[A1](other : Term1[A1,T3]) : Term8[T1,T2,A1,T4,T5,T6,T7,T8,R] = compose_2_1_8(other, this) + def compose3[A1](other : Term1[A1,T4]) : Term8[T1,T2,T3,A1,T5,T6,T7,T8,R] = compose_3_1_8(other, this) + def compose4[A1](other : Term1[A1,T5]) : Term8[T1,T2,T3,T4,A1,T6,T7,T8,R] = compose_4_1_8(other, this) + def compose5[A1](other : Term1[A1,T6]) : Term8[T1,T2,T3,T4,T5,A1,T7,T8,R] = compose_5_1_8(other, this) + def compose6[A1](other : Term1[A1,T7]) : Term8[T1,T2,T3,T4,T5,T6,A1,T8,R] = compose_6_1_8(other, this) + def compose7[A1](other : Term1[A1,T8]) : Term8[T1,T2,T3,T4,T5,T6,T7,A1,R] = compose_7_1_8(other, this) + def compose0[A1,A2](other : Term2[A1,A2,T1]) : Term9[A1,A2,T2,T3,T4,T5,T6,T7,T8,R] = compose_0_2_8(other, this) + def compose1[A1,A2](other : Term2[A1,A2,T2]) : Term9[T1,A1,A2,T3,T4,T5,T6,T7,T8,R] = compose_1_2_8(other, this) + def compose2[A1,A2](other : Term2[A1,A2,T3]) : Term9[T1,T2,A1,A2,T4,T5,T6,T7,T8,R] = compose_2_2_8(other, this) + def compose3[A1,A2](other : Term2[A1,A2,T4]) : Term9[T1,T2,T3,A1,A2,T5,T6,T7,T8,R] = compose_3_2_8(other, this) + def compose4[A1,A2](other : Term2[A1,A2,T5]) : Term9[T1,T2,T3,T4,A1,A2,T6,T7,T8,R] = compose_4_2_8(other, this) + def compose5[A1,A2](other : Term2[A1,A2,T6]) : Term9[T1,T2,T3,T4,T5,A1,A2,T7,T8,R] = compose_5_2_8(other, this) + def compose6[A1,A2](other : Term2[A1,A2,T7]) : Term9[T1,T2,T3,T4,T5,T6,A1,A2,T8,R] = compose_6_2_8(other, this) + def compose7[A1,A2](other : Term2[A1,A2,T8]) : Term9[T1,T2,T3,T4,T5,T6,T7,A1,A2,R] = compose_7_2_8(other, this) + } + + sealed trait Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R] extends Term[(T1,T2,T3,T4,T5,T6,T7,T8,T9),R] { + val convertingFunction = converterOf(this).exprSeq2scala9[T1,T2,T3,T4,T5,T6,T7,T8,T9] _ + type t2c = (Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R]) => Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Boolean] + + def ||(other : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Boolean])(implicit asConstraint : t2c) : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Boolean] = OrConstraint9[T1,T2,T3,T4,T5,T6,T7,T8,T9](this, other) + + def &&(other : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Boolean])(implicit asConstraint : t2c) : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Boolean] = AndConstraint9[T1,T2,T3,T4,T5,T6,T7,T8,T9](this, other) + + def unary_!(implicit asConstraint : t2c) : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Boolean] = NotConstraint9[T1,T2,T3,T4,T5,T6,T7,T8,T9](this) + + def minimizing(minFunc : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Int])(implicit asConstraint : t2c) : MinConstraint9[T1,T2,T3,T4,T5,T6,T7,T8,T9] = { + MinConstraint9[T1,T2,T3,T4,T5,T6,T7,T8,T9](asConstraint(this), minFunc) } + + def compose0[A1](other : Term1[A1,T1]) : Term9[A1,T2,T3,T4,T5,T6,T7,T8,T9,R] = compose_0_1_9(other, this) + def compose1[A1](other : Term1[A1,T2]) : Term9[T1,A1,T3,T4,T5,T6,T7,T8,T9,R] = compose_1_1_9(other, this) + def compose2[A1](other : Term1[A1,T3]) : Term9[T1,T2,A1,T4,T5,T6,T7,T8,T9,R] = compose_2_1_9(other, this) + def compose3[A1](other : Term1[A1,T4]) : Term9[T1,T2,T3,A1,T5,T6,T7,T8,T9,R] = compose_3_1_9(other, this) + def compose4[A1](other : Term1[A1,T5]) : Term9[T1,T2,T3,T4,A1,T6,T7,T8,T9,R] = compose_4_1_9(other, this) + def compose5[A1](other : Term1[A1,T6]) : Term9[T1,T2,T3,T4,T5,A1,T7,T8,T9,R] = compose_5_1_9(other, this) + def compose6[A1](other : Term1[A1,T7]) : Term9[T1,T2,T3,T4,T5,T6,A1,T8,T9,R] = compose_6_1_9(other, this) + def compose7[A1](other : Term1[A1,T8]) : Term9[T1,T2,T3,T4,T5,T6,T7,A1,T9,R] = compose_7_1_9(other, this) + def compose8[A1](other : Term1[A1,T9]) : Term9[T1,T2,T3,T4,T5,T6,T7,T8,A1,R] = compose_8_1_9(other, this) } object Term1 { - def apply[T1,R](conv : Converter, serializedProg : Serialized, serializedInputVars : Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { + def apply[T1,R](conv : Converter, serializedProg : Serialized, serializedInputVars: Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { val (converter, program, expr, types) = Term.processArgs(conv, serializedProg, serializedInputVars, serializedOutputVars, serializedExpr, inputVarValues) - new Term[T1,R](program, expr, types, converter) with Term1[T1,R] + new Term[(T1),R](program, expr, types, converter) with Term1[T1,R] } - + def apply[T1,R](program : Program, expr : Expr, types : Seq[TypeTree], converter : Converter) = - new Term[T1,R](program, expr, types, converter) with Term1[T1,R] + new Term[(T1),R](program, expr, types, converter) with Term1[T1,R] + } + + object OrConstraint1 { + def apply[T1](l : Term[(T1),Boolean], r : Term[(T1),Boolean]) : Term1[T1,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term1(p1,Or(ex1,ex2),ts1,conv1) + } + } + + object AndConstraint1 { + def apply[T1](l : Term[(T1),Boolean], r : Term[(T1),Boolean]) : Term1[T1,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term1(p1,And(ex1,ex2),ts1,conv1) + } + } + + object NotConstraint1 { + def apply[T1](c : Term[(T1),Boolean]) : Term1[T1,Boolean] = c match { + case Term(p,ex,ts,conv) => Term1(p,Not(ex),ts,conv) + } } object Term2 { - def apply[T1,T2,R](conv : Converter, serializedProg : Serialized, serializedInputVars : Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { + def apply[T1,T2,R](conv : Converter, serializedProg : Serialized, serializedInputVars: Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { val (converter, program, expr, types) = Term.processArgs(conv, serializedProg, serializedInputVars, serializedOutputVars, serializedExpr, inputVarValues) new Term[(T1,T2),R](program, expr, types, converter) with Term2[T1,T2,R] } - + def apply[T1,T2,R](program : Program, expr : Expr, types : Seq[TypeTree], converter : Converter) = new Term[(T1,T2),R](program, expr, types, converter) with Term2[T1,T2,R] } + object OrConstraint2 { + def apply[T1,T2](l : Term[(T1,T2),Boolean], r : Term[(T1,T2),Boolean]) : Term2[T1,T2,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term2(p1,Or(ex1,ex2),ts1,conv1) + } + } + + object AndConstraint2 { + def apply[T1,T2](l : Term[(T1,T2),Boolean], r : Term[(T1,T2),Boolean]) : Term2[T1,T2,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term2(p1,And(ex1,ex2),ts1,conv1) + } + } + + object NotConstraint2 { + def apply[T1,T2](c : Term[(T1,T2),Boolean]) : Term2[T1,T2,Boolean] = c match { + case Term(p,ex,ts,conv) => Term2(p,Not(ex),ts,conv) + } + } + object Term3 { - def apply[T1,T2,T3,R](conv : Converter, serializedProg : Serialized, serializedInputVars : Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { + def apply[T1,T2,T3,R](conv : Converter, serializedProg : Serialized, serializedInputVars: Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { val (converter, program, expr, types) = Term.processArgs(conv, serializedProg, serializedInputVars, serializedOutputVars, serializedExpr, inputVarValues) new Term[(T1,T2,T3),R](program, expr, types, converter) with Term3[T1,T2,T3,R] } - + def apply[T1,T2,T3,R](program : Program, expr : Expr, types : Seq[TypeTree], converter : Converter) = new Term[(T1,T2,T3),R](program, expr, types, converter) with Term3[T1,T2,T3,R] } - /** A constraint is just a term with Boolean range */ - type Constraint[T] = Term[T,Boolean] - type Constraint1[T1] = Term1[T1,Boolean] - type Constraint2[T1,T2] = Term2[T1,T2,Boolean] - type Constraint3[T1,T2,T3] = Term3[T1,T2,T3,Boolean] + object OrConstraint3 { + def apply[T1,T2,T3](l : Term[(T1,T2,T3),Boolean], r : Term[(T1,T2,T3),Boolean]) : Term3[T1,T2,T3,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term3(p1,Or(ex1,ex2),ts1,conv1) + } + } - object OrConstraint1 { - def apply[A](l : Constraint[A], r : Constraint[A]) : Constraint1[A] = (l, r) match { - case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term1(p1,Or(ex1,ex2),ts1,conv1) + object AndConstraint3 { + def apply[T1,T2,T3](l : Term[(T1,T2,T3),Boolean], r : Term[(T1,T2,T3),Boolean]) : Term3[T1,T2,T3,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term3(p1,And(ex1,ex2),ts1,conv1) } + } - def apply[A](cs : Seq[Constraint[A]]) : Constraint1[A] = cs match { - case s @ Seq(Term(p,ex,ts,conv), _*) => Term1(p, Or(s.map(_.expr)), ts, conv) + object NotConstraint3 { + def apply[T1,T2,T3](c : Term[(T1,T2,T3),Boolean]) : Term3[T1,T2,T3,Boolean] = c match { + case Term(p,ex,ts,conv) => Term3(p,Not(ex),ts,conv) } } - object OrConstraint2 { - def apply[A,B](l : Constraint[(A,B)], r : Constraint[(A,B)]) : Constraint2[A,B] = (l, r) match { - case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term2(p1,Or(ex1,ex2),ts1,conv1) + object Term4 { + def apply[T1,T2,T3,T4,R](conv : Converter, serializedProg : Serialized, serializedInputVars: Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { + val (converter, program, expr, types) = Term.processArgs(conv, serializedProg, serializedInputVars, serializedOutputVars, serializedExpr, inputVarValues) + new Term[(T1,T2,T3,T4),R](program, expr, types, converter) with Term4[T1,T2,T3,T4,R] } + + def apply[T1,T2,T3,T4,R](program : Program, expr : Expr, types : Seq[TypeTree], converter : Converter) = + new Term[(T1,T2,T3,T4),R](program, expr, types, converter) with Term4[T1,T2,T3,T4,R] + } - def apply[A,B](cs : Seq[Constraint[(A,B)]]) : Constraint2[A,B] = cs match { - case s @ Seq(Term(p,ex,ts,conv), _*) => Term2(p, Or(s.map(_.expr)), ts, conv) + object OrConstraint4 { + def apply[T1,T2,T3,T4](l : Term[(T1,T2,T3,T4),Boolean], r : Term[(T1,T2,T3,T4),Boolean]) : Term4[T1,T2,T3,T4,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term4(p1,Or(ex1,ex2),ts1,conv1) } } - object OrConstraint3 { - def apply[A,B,C](l : Constraint[(A,B,C)], r : Constraint[(A,B,C)]) : Constraint3[A,B,C] = (l, r) match { - case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term3(p1,Or(ex1,ex2),ts1,conv1) + object AndConstraint4 { + def apply[T1,T2,T3,T4](l : Term[(T1,T2,T3,T4),Boolean], r : Term[(T1,T2,T3,T4),Boolean]) : Term4[T1,T2,T3,T4,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term4(p1,And(ex1,ex2),ts1,conv1) } + } - def apply[A,B,C](cs : Seq[Constraint[(A,B,C)]]) : Constraint3[A,B,C] = cs match { - case s @ Seq(Term(p,ex,ts,conv), _*) => Term3(p, Or(s.map(_.expr)), ts, conv) + object NotConstraint4 { + def apply[T1,T2,T3,T4](c : Term[(T1,T2,T3,T4),Boolean]) : Term4[T1,T2,T3,T4,Boolean] = c match { + case Term(p,ex,ts,conv) => Term4(p,Not(ex),ts,conv) } } - object AndConstraint1 { - def apply[A](l : Constraint[A], r : Constraint[A]) : Constraint1[A] = (l, r) match { - case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term1(p1,And(ex1,ex2),ts1,conv1) + object Term5 { + def apply[T1,T2,T3,T4,T5,R](conv : Converter, serializedProg : Serialized, serializedInputVars: Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { + val (converter, program, expr, types) = Term.processArgs(conv, serializedProg, serializedInputVars, serializedOutputVars, serializedExpr, inputVarValues) + new Term[(T1,T2,T3,T4,T5),R](program, expr, types, converter) with Term5[T1,T2,T3,T4,T5,R] } + + def apply[T1,T2,T3,T4,T5,R](program : Program, expr : Expr, types : Seq[TypeTree], converter : Converter) = + new Term[(T1,T2,T3,T4,T5),R](program, expr, types, converter) with Term5[T1,T2,T3,T4,T5,R] + } - def apply[A](cs : Seq[Constraint[A]]) : Constraint1[A] = cs match { - case s @ Seq(Term(p,ex,ts,conv), _*) => Term1(p, And(s.map(_.expr)), ts, conv) + object OrConstraint5 { + def apply[T1,T2,T3,T4,T5](l : Term[(T1,T2,T3,T4,T5),Boolean], r : Term[(T1,T2,T3,T4,T5),Boolean]) : Term5[T1,T2,T3,T4,T5,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term5(p1,Or(ex1,ex2),ts1,conv1) } } - object AndConstraint2 { - def apply[A,B](l : Constraint[(A,B)], r : Constraint[(A,B)]) : Constraint2[A,B] = (l, r) match { - case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term2(p1,And(ex1,ex2),ts1,conv1) + object AndConstraint5 { + def apply[T1,T2,T3,T4,T5](l : Term[(T1,T2,T3,T4,T5),Boolean], r : Term[(T1,T2,T3,T4,T5),Boolean]) : Term5[T1,T2,T3,T4,T5,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term5(p1,And(ex1,ex2),ts1,conv1) } + } - def apply[A,B](cs : Seq[Constraint[(A,B)]]) : Constraint2[A,B] = cs match { - case s @ Seq(Term(p,ex,ts,conv), _*) => Term2(p, And(s.map(_.expr)), ts, conv) + object NotConstraint5 { + def apply[T1,T2,T3,T4,T5](c : Term[(T1,T2,T3,T4,T5),Boolean]) : Term5[T1,T2,T3,T4,T5,Boolean] = c match { + case Term(p,ex,ts,conv) => Term5(p,Not(ex),ts,conv) } } - object AndConstraint3 { - def apply[A,B,C](l : Constraint[(A,B,C)], r : Constraint[(A,B,C)]) : Constraint3[A,B,C] = (l, r) match { - case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term3(p1,And(ex1,ex2),ts1,conv1) + object Term6 { + def apply[T1,T2,T3,T4,T5,T6,R](conv : Converter, serializedProg : Serialized, serializedInputVars: Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { + val (converter, program, expr, types) = Term.processArgs(conv, serializedProg, serializedInputVars, serializedOutputVars, serializedExpr, inputVarValues) + new Term[(T1,T2,T3,T4,T5,T6),R](program, expr, types, converter) with Term6[T1,T2,T3,T4,T5,T6,R] } + + def apply[T1,T2,T3,T4,T5,T6,R](program : Program, expr : Expr, types : Seq[TypeTree], converter : Converter) = + new Term[(T1,T2,T3,T4,T5,T6),R](program, expr, types, converter) with Term6[T1,T2,T3,T4,T5,T6,R] + } - def apply[A,B,C](cs : Seq[Constraint[(A,B,C)]]) : Constraint3[A,B,C] = cs match { - case s @ Seq(Term(p,ex,ts,conv), _*) => Term3(p, And(s.map(_.expr)), ts, conv) + object OrConstraint6 { + def apply[T1,T2,T3,T4,T5,T6](l : Term[(T1,T2,T3,T4,T5,T6),Boolean], r : Term[(T1,T2,T3,T4,T5,T6),Boolean]) : Term6[T1,T2,T3,T4,T5,T6,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term6(p1,Or(ex1,ex2),ts1,conv1) } } - object NotConstraint1 { - def apply[A](c : Constraint[A]) : Constraint1[A] = c match { - case Term(p,ex,ts,conv) => Term1(p,Not(ex),ts,conv) + object AndConstraint6 { + def apply[T1,T2,T3,T4,T5,T6](l : Term[(T1,T2,T3,T4,T5,T6),Boolean], r : Term[(T1,T2,T3,T4,T5,T6),Boolean]) : Term6[T1,T2,T3,T4,T5,T6,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term6(p1,And(ex1,ex2),ts1,conv1) } } - object NotConstraint2 { - def apply[A,B](c : Constraint[(A,B)]) : Constraint2[A,B] = c match { - case Term(p,ex,ts,conv) => Term2(p,Not(ex),ts,conv) + object NotConstraint6 { + def apply[T1,T2,T3,T4,T5,T6](c : Term[(T1,T2,T3,T4,T5,T6),Boolean]) : Term6[T1,T2,T3,T4,T5,T6,Boolean] = c match { + case Term(p,ex,ts,conv) => Term6(p,Not(ex),ts,conv) } } - object NotConstraint3 { - def apply[A,B,C](c : Constraint[(A,B,C)]) : Constraint3[A,B,C] = c match { - case Term(p,ex,ts,conv) => Term3(p,Not(ex),ts,conv) + object Term7 { + def apply[T1,T2,T3,T4,T5,T6,T7,R](conv : Converter, serializedProg : Serialized, serializedInputVars: Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { + val (converter, program, expr, types) = Term.processArgs(conv, serializedProg, serializedInputVars, serializedOutputVars, serializedExpr, inputVarValues) + new Term[(T1,T2,T3,T4,T5,T6,T7),R](program, expr, types, converter) with Term7[T1,T2,T3,T4,T5,T6,T7,R] } + + def apply[T1,T2,T3,T4,T5,T6,T7,R](program : Program, expr : Expr, types : Seq[TypeTree], converter : Converter) = + new Term[(T1,T2,T3,T4,T5,T6,T7),R](program, expr, types, converter) with Term7[T1,T2,T3,T4,T5,T6,T7,R] } - type IntTerm[T] = Term[T,Int] - type IntTerm1[T1] = Term1[T1,Int] - type IntTerm2[T1,T2] = Term2[T1,T2,Int] - type IntTerm3[T1,T2,T3] = Term3[T1,T2,T3,Int] + object OrConstraint7 { + def apply[T1,T2,T3,T4,T5,T6,T7](l : Term[(T1,T2,T3,T4,T5,T6,T7),Boolean], r : Term[(T1,T2,T3,T4,T5,T6,T7),Boolean]) : Term7[T1,T2,T3,T4,T5,T6,T7,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term7(p1,Or(ex1,ex2),ts1,conv1) + } + } + + object AndConstraint7 { + def apply[T1,T2,T3,T4,T5,T6,T7](l : Term[(T1,T2,T3,T4,T5,T6,T7),Boolean], r : Term[(T1,T2,T3,T4,T5,T6,T7),Boolean]) : Term7[T1,T2,T3,T4,T5,T6,T7,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term7(p1,And(ex1,ex2),ts1,conv1) + } + } + + object NotConstraint7 { + def apply[T1,T2,T3,T4,T5,T6,T7](c : Term[(T1,T2,T3,T4,T5,T6,T7),Boolean]) : Term7[T1,T2,T3,T4,T5,T6,T7,Boolean] = c match { + case Term(p,ex,ts,conv) => Term7(p,Not(ex),ts,conv) + } + } + + object Term8 { + def apply[T1,T2,T3,T4,T5,T6,T7,T8,R](conv : Converter, serializedProg : Serialized, serializedInputVars: Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { + val (converter, program, expr, types) = Term.processArgs(conv, serializedProg, serializedInputVars, serializedOutputVars, serializedExpr, inputVarValues) + new Term[(T1,T2,T3,T4,T5,T6,T7,T8),R](program, expr, types, converter) with Term8[T1,T2,T3,T4,T5,T6,T7,T8,R] + } + + def apply[T1,T2,T3,T4,T5,T6,T7,T8,R](program : Program, expr : Expr, types : Seq[TypeTree], converter : Converter) = + new Term[(T1,T2,T3,T4,T5,T6,T7,T8),R](program, expr, types, converter) with Term8[T1,T2,T3,T4,T5,T6,T7,T8,R] + } + + object OrConstraint8 { + def apply[T1,T2,T3,T4,T5,T6,T7,T8](l : Term[(T1,T2,T3,T4,T5,T6,T7,T8),Boolean], r : Term[(T1,T2,T3,T4,T5,T6,T7,T8),Boolean]) : Term8[T1,T2,T3,T4,T5,T6,T7,T8,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term8(p1,Or(ex1,ex2),ts1,conv1) + } + } + + object AndConstraint8 { + def apply[T1,T2,T3,T4,T5,T6,T7,T8](l : Term[(T1,T2,T3,T4,T5,T6,T7,T8),Boolean], r : Term[(T1,T2,T3,T4,T5,T6,T7,T8),Boolean]) : Term8[T1,T2,T3,T4,T5,T6,T7,T8,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term8(p1,And(ex1,ex2),ts1,conv1) + } + } + + object NotConstraint8 { + def apply[T1,T2,T3,T4,T5,T6,T7,T8](c : Term[(T1,T2,T3,T4,T5,T6,T7,T8),Boolean]) : Term8[T1,T2,T3,T4,T5,T6,T7,T8,Boolean] = c match { + case Term(p,ex,ts,conv) => Term8(p,Not(ex),ts,conv) + } + } + + object Term9 { + def apply[T1,T2,T3,T4,T5,T6,T7,T8,T9,R](conv : Converter, serializedProg : Serialized, serializedInputVars: Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { + val (converter, program, expr, types) = Term.processArgs(conv, serializedProg, serializedInputVars, serializedOutputVars, serializedExpr, inputVarValues) + new Term[(T1,T2,T3,T4,T5,T6,T7,T8,T9),R](program, expr, types, converter) with Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R] + } + + def apply[T1,T2,T3,T4,T5,T6,T7,T8,T9,R](program : Program, expr : Expr, types : Seq[TypeTree], converter : Converter) = + new Term[(T1,T2,T3,T4,T5,T6,T7,T8,T9),R](program, expr, types, converter) with Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R] + } + + object OrConstraint9 { + def apply[T1,T2,T3,T4,T5,T6,T7,T8,T9](l : Term[(T1,T2,T3,T4,T5,T6,T7,T8,T9),Boolean], r : Term[(T1,T2,T3,T4,T5,T6,T7,T8,T9),Boolean]) : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term9(p1,Or(ex1,ex2),ts1,conv1) + } + } + object AndConstraint9 { + def apply[T1,T2,T3,T4,T5,T6,T7,T8,T9](l : Term[(T1,T2,T3,T4,T5,T6,T7,T8,T9),Boolean], r : Term[(T1,T2,T3,T4,T5,T6,T7,T8,T9),Boolean]) : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Boolean] = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term9(p1,And(ex1,ex2),ts1,conv1) + } + } + + object NotConstraint9 { + def apply[T1,T2,T3,T4,T5,T6,T7,T8,T9](c : Term[(T1,T2,T3,T4,T5,T6,T7,T8,T9),Boolean]) : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Boolean] = c match { + case Term(p,ex,ts,conv) => Term9(p,Not(ex),ts,conv) + } + } /** This construct represents a constraint with an expression to minimize */ abstract class MinConstraint[T](cons : Constraint[_], minFunc : IntTerm[_]) { val convertingFunction : (Seq[Expr] => T) @@ -262,18 +672,42 @@ object Terms { } } - case class MinConstraint1[T](cons : Constraint1[T], minFunc : IntTerm1[T]) extends MinConstraint[T](cons, minFunc) { - val convertingFunction = converterOf(cons).exprSeq2scala1[T] _ + case class MinConstraint1[T1](cons : Term1[T1,Boolean], minFunc : Term1[T1,Int]) extends MinConstraint[(T1)](cons, minFunc) { + val convertingFunction = converterOf(cons).exprSeq2scala1[T1] _ } - case class MinConstraint2[T1,T2](cons : Constraint2[T1,T2], minFunc : IntTerm2[T1,T2]) extends MinConstraint[(T1,T2)](cons, minFunc) { + case class MinConstraint2[T1,T2](cons : Term2[T1,T2,Boolean], minFunc : Term2[T1,T2,Int]) extends MinConstraint[(T1,T2)](cons, minFunc) { val convertingFunction = converterOf(cons).exprSeq2scala2[T1,T2] _ } - case class MinConstraint3[T1,T2,T3](cons : Constraint3[T1,T2,T3], minFunc : IntTerm3[T1,T2,T3]) extends MinConstraint[(T1,T2,T3)](cons, minFunc) { + case class MinConstraint3[T1,T2,T3](cons : Term3[T1,T2,T3,Boolean], minFunc : Term3[T1,T2,T3,Int]) extends MinConstraint[(T1,T2,T3)](cons, minFunc) { val convertingFunction = converterOf(cons).exprSeq2scala3[T1,T2,T3] _ } + case class MinConstraint4[T1,T2,T3,T4](cons : Term4[T1,T2,T3,T4,Boolean], minFunc : Term4[T1,T2,T3,T4,Int]) extends MinConstraint[(T1,T2,T3,T4)](cons, minFunc) { + val convertingFunction = converterOf(cons).exprSeq2scala4[T1,T2,T3,T4] _ + } + + case class MinConstraint5[T1,T2,T3,T4,T5](cons : Term5[T1,T2,T3,T4,T5,Boolean], minFunc : Term5[T1,T2,T3,T4,T5,Int]) extends MinConstraint[(T1,T2,T3,T4,T5)](cons, minFunc) { + val convertingFunction = converterOf(cons).exprSeq2scala5[T1,T2,T3,T4,T5] _ + } + + case class MinConstraint6[T1,T2,T3,T4,T5,T6](cons : Term6[T1,T2,T3,T4,T5,T6,Boolean], minFunc : Term6[T1,T2,T3,T4,T5,T6,Int]) extends MinConstraint[(T1,T2,T3,T4,T5,T6)](cons, minFunc) { + val convertingFunction = converterOf(cons).exprSeq2scala6[T1,T2,T3,T4,T5,T6] _ + } + + case class MinConstraint7[T1,T2,T3,T4,T5,T6,T7](cons : Term7[T1,T2,T3,T4,T5,T6,T7,Boolean], minFunc : Term7[T1,T2,T3,T4,T5,T6,T7,Int]) extends MinConstraint[(T1,T2,T3,T4,T5,T6,T7)](cons, minFunc) { + val convertingFunction = converterOf(cons).exprSeq2scala7[T1,T2,T3,T4,T5,T6,T7] _ + } + + case class MinConstraint8[T1,T2,T3,T4,T5,T6,T7,T8](cons : Term8[T1,T2,T3,T4,T5,T6,T7,T8,Boolean], minFunc : Term8[T1,T2,T3,T4,T5,T6,T7,T8,Int]) extends MinConstraint[(T1,T2,T3,T4,T5,T6,T7,T8)](cons, minFunc) { + val convertingFunction = converterOf(cons).exprSeq2scala8[T1,T2,T3,T4,T5,T6,T7,T8] _ + } + + case class MinConstraint9[T1,T2,T3,T4,T5,T6,T7,T8,T9](cons : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Boolean], minFunc : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,Int]) extends MinConstraint[(T1,T2,T3,T4,T5,T6,T7,T8,T9)](cons, minFunc) { + val convertingFunction = converterOf(cons).exprSeq2scala9[T1,T2,T3,T4,T5,T6,T7,T8,T9] _ + } + /********** TERM METHODS **********/ /** compose_i_j_k will compose f (of arity j) and g (of arity k) as "g∘f" by * inserting arguments of f in place of argument i of g */ @@ -292,6 +726,36 @@ object Terms { Term3(f.program, newExpr, newTypes, f.converter) } + private def compose_0_4_1[A1,A2,A3,A4,R1,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(R1),R2]) : Term4[A1,A2,A3,A4,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 4, 1) + Term4(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_5_1[A1,A2,A3,A4,A5,R1,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(R1),R2]) : Term5[A1,A2,A3,A4,A5,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 5, 1) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_6_1[A1,A2,A3,A4,A5,A6,R1,R2](f : Term[(A1,A2,A3,A4,A5,A6),R1], g : Term[(R1),R2]) : Term6[A1,A2,A3,A4,A5,A6,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 6, 1) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_7_1[A1,A2,A3,A4,A5,A6,A7,R1,R2](f : Term[(A1,A2,A3,A4,A5,A6,A7),R1], g : Term[(R1),R2]) : Term7[A1,A2,A3,A4,A5,A6,A7,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 7, 1) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_8_1[A1,A2,A3,A4,A5,A6,A7,A8,R1,R2](f : Term[(A1,A2,A3,A4,A5,A6,A7,A8),R1], g : Term[(R1),R2]) : Term8[A1,A2,A3,A4,A5,A6,A7,A8,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 8, 1) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_9_1[A1,A2,A3,A4,A5,A6,A7,A8,A9,R1,R2](f : Term[(A1,A2,A3,A4,A5,A6,A7,A8,A9),R1], g : Term[(R1),R2]) : Term9[A1,A2,A3,A4,A5,A6,A7,A8,A9,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 9, 1) + Term9(f.program, newExpr, newTypes, f.converter) + } + private def compose_0_1_2[A1,R1,B2,R2](f : Term[(A1),R1], g : Term[(R1,B2),R2]) : Term2[A1,B2,R2] = { val (newExpr, newTypes) = compose(f, g, 0, 1, 2) Term2(f.program, newExpr, newTypes, f.converter) @@ -312,19 +776,764 @@ object Terms { Term3(f.program, newExpr, newTypes, f.converter) } - private def compose_0_1_3[A1,R1,B2,B3,R2](f : Term[(A1),R1], g : Term[(R1,B2,B3),R2]) : Term3[A1,B2,B3,R2] = { - val (newExpr, newTypes) = compose(f, g, 0, 1, 3) - Term3(f.program, newExpr, newTypes, f.converter) + private def compose_0_3_2[A1,A2,A3,R1,B2,R2](f : Term[(A1,A2,A3),R1], g : Term[(R1,B2),R2]) : Term4[A1,A2,A3,B2,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 3, 2) + Term4(f.program, newExpr, newTypes, f.converter) } - private def compose_1_1_3[A1,R1,B1,B3,R2](f : Term[(A1),R1], g : Term[(B1,R1,B3),R2]) : Term3[B1,A1,B3,R2] = { - val (newExpr, newTypes) = compose(f, g, 1, 1, 3) - Term3(f.program, newExpr, newTypes, f.converter) + private def compose_1_3_2[A1,A2,A3,R1,B1,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,R1),R2]) : Term4[B1,A1,A2,A3,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 3, 2) + Term4(f.program, newExpr, newTypes, f.converter) } - private def compose_2_1_3[A1,R1,B1,B2,R2](f : Term[(A1),R1], g : Term[(B1,B2,R1),R2]) : Term3[B1,B2,A1,R2] = { - val (newExpr, newTypes) = compose(f, g, 2, 1, 3) - Term3(f.program, newExpr, newTypes, f.converter) + private def compose_0_4_2[A1,A2,A3,A4,R1,B2,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(R1,B2),R2]) : Term5[A1,A2,A3,A4,B2,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 4, 2) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_4_2[A1,A2,A3,A4,R1,B1,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,R1),R2]) : Term5[B1,A1,A2,A3,A4,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 4, 2) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_5_2[A1,A2,A3,A4,A5,R1,B2,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(R1,B2),R2]) : Term6[A1,A2,A3,A4,A5,B2,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 5, 2) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_5_2[A1,A2,A3,A4,A5,R1,B1,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(B1,R1),R2]) : Term6[B1,A1,A2,A3,A4,A5,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 5, 2) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_6_2[A1,A2,A3,A4,A5,A6,R1,B2,R2](f : Term[(A1,A2,A3,A4,A5,A6),R1], g : Term[(R1,B2),R2]) : Term7[A1,A2,A3,A4,A5,A6,B2,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 6, 2) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_6_2[A1,A2,A3,A4,A5,A6,R1,B1,R2](f : Term[(A1,A2,A3,A4,A5,A6),R1], g : Term[(B1,R1),R2]) : Term7[B1,A1,A2,A3,A4,A5,A6,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 6, 2) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_7_2[A1,A2,A3,A4,A5,A6,A7,R1,B2,R2](f : Term[(A1,A2,A3,A4,A5,A6,A7),R1], g : Term[(R1,B2),R2]) : Term8[A1,A2,A3,A4,A5,A6,A7,B2,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 7, 2) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_7_2[A1,A2,A3,A4,A5,A6,A7,R1,B1,R2](f : Term[(A1,A2,A3,A4,A5,A6,A7),R1], g : Term[(B1,R1),R2]) : Term8[B1,A1,A2,A3,A4,A5,A6,A7,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 7, 2) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_8_2[A1,A2,A3,A4,A5,A6,A7,A8,R1,B2,R2](f : Term[(A1,A2,A3,A4,A5,A6,A7,A8),R1], g : Term[(R1,B2),R2]) : Term9[A1,A2,A3,A4,A5,A6,A7,A8,B2,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 8, 2) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_8_2[A1,A2,A3,A4,A5,A6,A7,A8,R1,B1,R2](f : Term[(A1,A2,A3,A4,A5,A6,A7,A8),R1], g : Term[(B1,R1),R2]) : Term9[B1,A1,A2,A3,A4,A5,A6,A7,A8,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 8, 2) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_1_3[A1,R1,B2,B3,R2](f : Term[(A1),R1], g : Term[(R1,B2,B3),R2]) : Term3[A1,B2,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 1, 3) + Term3(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_1_3[A1,R1,B1,B3,R2](f : Term[(A1),R1], g : Term[(B1,R1,B3),R2]) : Term3[B1,A1,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 1, 3) + Term3(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_1_3[A1,R1,B1,B2,R2](f : Term[(A1),R1], g : Term[(B1,B2,R1),R2]) : Term3[B1,B2,A1,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 1, 3) + Term3(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_2_3[A1,A2,R1,B2,B3,R2](f : Term[(A1,A2),R1], g : Term[(R1,B2,B3),R2]) : Term4[A1,A2,B2,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 2, 3) + Term4(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_2_3[A1,A2,R1,B1,B3,R2](f : Term[(A1,A2),R1], g : Term[(B1,R1,B3),R2]) : Term4[B1,A1,A2,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 2, 3) + Term4(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_2_3[A1,A2,R1,B1,B2,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,R1),R2]) : Term4[B1,B2,A1,A2,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 2, 3) + Term4(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_3_3[A1,A2,A3,R1,B2,B3,R2](f : Term[(A1,A2,A3),R1], g : Term[(R1,B2,B3),R2]) : Term5[A1,A2,A3,B2,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 3, 3) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_3_3[A1,A2,A3,R1,B1,B3,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,R1,B3),R2]) : Term5[B1,A1,A2,A3,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 3, 3) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_3_3[A1,A2,A3,R1,B1,B2,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,R1),R2]) : Term5[B1,B2,A1,A2,A3,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 3, 3) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_4_3[A1,A2,A3,A4,R1,B2,B3,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(R1,B2,B3),R2]) : Term6[A1,A2,A3,A4,B2,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 4, 3) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_4_3[A1,A2,A3,A4,R1,B1,B3,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,R1,B3),R2]) : Term6[B1,A1,A2,A3,A4,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 4, 3) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_4_3[A1,A2,A3,A4,R1,B1,B2,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,B2,R1),R2]) : Term6[B1,B2,A1,A2,A3,A4,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 4, 3) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_5_3[A1,A2,A3,A4,A5,R1,B2,B3,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(R1,B2,B3),R2]) : Term7[A1,A2,A3,A4,A5,B2,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 5, 3) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_5_3[A1,A2,A3,A4,A5,R1,B1,B3,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(B1,R1,B3),R2]) : Term7[B1,A1,A2,A3,A4,A5,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 5, 3) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_5_3[A1,A2,A3,A4,A5,R1,B1,B2,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(B1,B2,R1),R2]) : Term7[B1,B2,A1,A2,A3,A4,A5,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 5, 3) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_6_3[A1,A2,A3,A4,A5,A6,R1,B2,B3,R2](f : Term[(A1,A2,A3,A4,A5,A6),R1], g : Term[(R1,B2,B3),R2]) : Term8[A1,A2,A3,A4,A5,A6,B2,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 6, 3) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_6_3[A1,A2,A3,A4,A5,A6,R1,B1,B3,R2](f : Term[(A1,A2,A3,A4,A5,A6),R1], g : Term[(B1,R1,B3),R2]) : Term8[B1,A1,A2,A3,A4,A5,A6,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 6, 3) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_6_3[A1,A2,A3,A4,A5,A6,R1,B1,B2,R2](f : Term[(A1,A2,A3,A4,A5,A6),R1], g : Term[(B1,B2,R1),R2]) : Term8[B1,B2,A1,A2,A3,A4,A5,A6,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 6, 3) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_7_3[A1,A2,A3,A4,A5,A6,A7,R1,B2,B3,R2](f : Term[(A1,A2,A3,A4,A5,A6,A7),R1], g : Term[(R1,B2,B3),R2]) : Term9[A1,A2,A3,A4,A5,A6,A7,B2,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 7, 3) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_7_3[A1,A2,A3,A4,A5,A6,A7,R1,B1,B3,R2](f : Term[(A1,A2,A3,A4,A5,A6,A7),R1], g : Term[(B1,R1,B3),R2]) : Term9[B1,A1,A2,A3,A4,A5,A6,A7,B3,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 7, 3) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_7_3[A1,A2,A3,A4,A5,A6,A7,R1,B1,B2,R2](f : Term[(A1,A2,A3,A4,A5,A6,A7),R1], g : Term[(B1,B2,R1),R2]) : Term9[B1,B2,A1,A2,A3,A4,A5,A6,A7,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 7, 3) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_1_4[A1,R1,B2,B3,B4,R2](f : Term[(A1),R1], g : Term[(R1,B2,B3,B4),R2]) : Term4[A1,B2,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 1, 4) + Term4(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_1_4[A1,R1,B1,B3,B4,R2](f : Term[(A1),R1], g : Term[(B1,R1,B3,B4),R2]) : Term4[B1,A1,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 1, 4) + Term4(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_1_4[A1,R1,B1,B2,B4,R2](f : Term[(A1),R1], g : Term[(B1,B2,R1,B4),R2]) : Term4[B1,B2,A1,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 1, 4) + Term4(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_1_4[A1,R1,B1,B2,B3,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,R1),R2]) : Term4[B1,B2,B3,A1,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 1, 4) + Term4(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_2_4[A1,A2,R1,B2,B3,B4,R2](f : Term[(A1,A2),R1], g : Term[(R1,B2,B3,B4),R2]) : Term5[A1,A2,B2,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 2, 4) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_2_4[A1,A2,R1,B1,B3,B4,R2](f : Term[(A1,A2),R1], g : Term[(B1,R1,B3,B4),R2]) : Term5[B1,A1,A2,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 2, 4) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_2_4[A1,A2,R1,B1,B2,B4,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,R1,B4),R2]) : Term5[B1,B2,A1,A2,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 2, 4) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_2_4[A1,A2,R1,B1,B2,B3,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,R1),R2]) : Term5[B1,B2,B3,A1,A2,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 2, 4) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_3_4[A1,A2,A3,R1,B2,B3,B4,R2](f : Term[(A1,A2,A3),R1], g : Term[(R1,B2,B3,B4),R2]) : Term6[A1,A2,A3,B2,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 3, 4) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_3_4[A1,A2,A3,R1,B1,B3,B4,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,R1,B3,B4),R2]) : Term6[B1,A1,A2,A3,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 3, 4) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_3_4[A1,A2,A3,R1,B1,B2,B4,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,R1,B4),R2]) : Term6[B1,B2,A1,A2,A3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 3, 4) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_3_4[A1,A2,A3,R1,B1,B2,B3,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,B3,R1),R2]) : Term6[B1,B2,B3,A1,A2,A3,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 3, 4) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_4_4[A1,A2,A3,A4,R1,B2,B3,B4,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(R1,B2,B3,B4),R2]) : Term7[A1,A2,A3,A4,B2,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 4, 4) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_4_4[A1,A2,A3,A4,R1,B1,B3,B4,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,R1,B3,B4),R2]) : Term7[B1,A1,A2,A3,A4,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 4, 4) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_4_4[A1,A2,A3,A4,R1,B1,B2,B4,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,B2,R1,B4),R2]) : Term7[B1,B2,A1,A2,A3,A4,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 4, 4) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_4_4[A1,A2,A3,A4,R1,B1,B2,B3,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,B2,B3,R1),R2]) : Term7[B1,B2,B3,A1,A2,A3,A4,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 4, 4) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_5_4[A1,A2,A3,A4,A5,R1,B2,B3,B4,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(R1,B2,B3,B4),R2]) : Term8[A1,A2,A3,A4,A5,B2,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 5, 4) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_5_4[A1,A2,A3,A4,A5,R1,B1,B3,B4,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(B1,R1,B3,B4),R2]) : Term8[B1,A1,A2,A3,A4,A5,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 5, 4) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_5_4[A1,A2,A3,A4,A5,R1,B1,B2,B4,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(B1,B2,R1,B4),R2]) : Term8[B1,B2,A1,A2,A3,A4,A5,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 5, 4) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_5_4[A1,A2,A3,A4,A5,R1,B1,B2,B3,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(B1,B2,B3,R1),R2]) : Term8[B1,B2,B3,A1,A2,A3,A4,A5,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 5, 4) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_6_4[A1,A2,A3,A4,A5,A6,R1,B2,B3,B4,R2](f : Term[(A1,A2,A3,A4,A5,A6),R1], g : Term[(R1,B2,B3,B4),R2]) : Term9[A1,A2,A3,A4,A5,A6,B2,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 6, 4) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_6_4[A1,A2,A3,A4,A5,A6,R1,B1,B3,B4,R2](f : Term[(A1,A2,A3,A4,A5,A6),R1], g : Term[(B1,R1,B3,B4),R2]) : Term9[B1,A1,A2,A3,A4,A5,A6,B3,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 6, 4) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_6_4[A1,A2,A3,A4,A5,A6,R1,B1,B2,B4,R2](f : Term[(A1,A2,A3,A4,A5,A6),R1], g : Term[(B1,B2,R1,B4),R2]) : Term9[B1,B2,A1,A2,A3,A4,A5,A6,B4,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 6, 4) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_6_4[A1,A2,A3,A4,A5,A6,R1,B1,B2,B3,R2](f : Term[(A1,A2,A3,A4,A5,A6),R1], g : Term[(B1,B2,B3,R1),R2]) : Term9[B1,B2,B3,A1,A2,A3,A4,A5,A6,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 6, 4) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_1_5[A1,R1,B2,B3,B4,B5,R2](f : Term[(A1),R1], g : Term[(R1,B2,B3,B4,B5),R2]) : Term5[A1,B2,B3,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 1, 5) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_1_5[A1,R1,B1,B3,B4,B5,R2](f : Term[(A1),R1], g : Term[(B1,R1,B3,B4,B5),R2]) : Term5[B1,A1,B3,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 1, 5) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_1_5[A1,R1,B1,B2,B4,B5,R2](f : Term[(A1),R1], g : Term[(B1,B2,R1,B4,B5),R2]) : Term5[B1,B2,A1,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 1, 5) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_1_5[A1,R1,B1,B2,B3,B5,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,R1,B5),R2]) : Term5[B1,B2,B3,A1,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 1, 5) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_1_5[A1,R1,B1,B2,B3,B4,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,R1),R2]) : Term5[B1,B2,B3,B4,A1,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 1, 5) + Term5(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_2_5[A1,A2,R1,B2,B3,B4,B5,R2](f : Term[(A1,A2),R1], g : Term[(R1,B2,B3,B4,B5),R2]) : Term6[A1,A2,B2,B3,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 2, 5) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_2_5[A1,A2,R1,B1,B3,B4,B5,R2](f : Term[(A1,A2),R1], g : Term[(B1,R1,B3,B4,B5),R2]) : Term6[B1,A1,A2,B3,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 2, 5) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_2_5[A1,A2,R1,B1,B2,B4,B5,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,R1,B4,B5),R2]) : Term6[B1,B2,A1,A2,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 2, 5) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_2_5[A1,A2,R1,B1,B2,B3,B5,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,R1,B5),R2]) : Term6[B1,B2,B3,A1,A2,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 2, 5) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_2_5[A1,A2,R1,B1,B2,B3,B4,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,B4,R1),R2]) : Term6[B1,B2,B3,B4,A1,A2,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 2, 5) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_3_5[A1,A2,A3,R1,B2,B3,B4,B5,R2](f : Term[(A1,A2,A3),R1], g : Term[(R1,B2,B3,B4,B5),R2]) : Term7[A1,A2,A3,B2,B3,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 3, 5) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_3_5[A1,A2,A3,R1,B1,B3,B4,B5,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,R1,B3,B4,B5),R2]) : Term7[B1,A1,A2,A3,B3,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 3, 5) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_3_5[A1,A2,A3,R1,B1,B2,B4,B5,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,R1,B4,B5),R2]) : Term7[B1,B2,A1,A2,A3,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 3, 5) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_3_5[A1,A2,A3,R1,B1,B2,B3,B5,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,B3,R1,B5),R2]) : Term7[B1,B2,B3,A1,A2,A3,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 3, 5) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_3_5[A1,A2,A3,R1,B1,B2,B3,B4,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,B3,B4,R1),R2]) : Term7[B1,B2,B3,B4,A1,A2,A3,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 3, 5) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_4_5[A1,A2,A3,A4,R1,B2,B3,B4,B5,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(R1,B2,B3,B4,B5),R2]) : Term8[A1,A2,A3,A4,B2,B3,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 4, 5) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_4_5[A1,A2,A3,A4,R1,B1,B3,B4,B5,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,R1,B3,B4,B5),R2]) : Term8[B1,A1,A2,A3,A4,B3,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 4, 5) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_4_5[A1,A2,A3,A4,R1,B1,B2,B4,B5,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,B2,R1,B4,B5),R2]) : Term8[B1,B2,A1,A2,A3,A4,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 4, 5) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_4_5[A1,A2,A3,A4,R1,B1,B2,B3,B5,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,B2,B3,R1,B5),R2]) : Term8[B1,B2,B3,A1,A2,A3,A4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 4, 5) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_4_5[A1,A2,A3,A4,R1,B1,B2,B3,B4,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,B2,B3,B4,R1),R2]) : Term8[B1,B2,B3,B4,A1,A2,A3,A4,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 4, 5) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_5_5[A1,A2,A3,A4,A5,R1,B2,B3,B4,B5,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(R1,B2,B3,B4,B5),R2]) : Term9[A1,A2,A3,A4,A5,B2,B3,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 5, 5) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_5_5[A1,A2,A3,A4,A5,R1,B1,B3,B4,B5,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(B1,R1,B3,B4,B5),R2]) : Term9[B1,A1,A2,A3,A4,A5,B3,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 5, 5) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_5_5[A1,A2,A3,A4,A5,R1,B1,B2,B4,B5,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(B1,B2,R1,B4,B5),R2]) : Term9[B1,B2,A1,A2,A3,A4,A5,B4,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 5, 5) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_5_5[A1,A2,A3,A4,A5,R1,B1,B2,B3,B5,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(B1,B2,B3,R1,B5),R2]) : Term9[B1,B2,B3,A1,A2,A3,A4,A5,B5,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 5, 5) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_5_5[A1,A2,A3,A4,A5,R1,B1,B2,B3,B4,R2](f : Term[(A1,A2,A3,A4,A5),R1], g : Term[(B1,B2,B3,B4,R1),R2]) : Term9[B1,B2,B3,B4,A1,A2,A3,A4,A5,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 5, 5) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_1_6[A1,R1,B2,B3,B4,B5,B6,R2](f : Term[(A1),R1], g : Term[(R1,B2,B3,B4,B5,B6),R2]) : Term6[A1,B2,B3,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 1, 6) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_1_6[A1,R1,B1,B3,B4,B5,B6,R2](f : Term[(A1),R1], g : Term[(B1,R1,B3,B4,B5,B6),R2]) : Term6[B1,A1,B3,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 1, 6) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_1_6[A1,R1,B1,B2,B4,B5,B6,R2](f : Term[(A1),R1], g : Term[(B1,B2,R1,B4,B5,B6),R2]) : Term6[B1,B2,A1,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 1, 6) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_1_6[A1,R1,B1,B2,B3,B5,B6,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,R1,B5,B6),R2]) : Term6[B1,B2,B3,A1,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 1, 6) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_1_6[A1,R1,B1,B2,B3,B4,B6,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,R1,B6),R2]) : Term6[B1,B2,B3,B4,A1,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 1, 6) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_5_1_6[A1,R1,B1,B2,B3,B4,B5,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,B5,R1),R2]) : Term6[B1,B2,B3,B4,B5,A1,R2] = { + val (newExpr, newTypes) = compose(f, g, 5, 1, 6) + Term6(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_2_6[A1,A2,R1,B2,B3,B4,B5,B6,R2](f : Term[(A1,A2),R1], g : Term[(R1,B2,B3,B4,B5,B6),R2]) : Term7[A1,A2,B2,B3,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 2, 6) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_2_6[A1,A2,R1,B1,B3,B4,B5,B6,R2](f : Term[(A1,A2),R1], g : Term[(B1,R1,B3,B4,B5,B6),R2]) : Term7[B1,A1,A2,B3,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 2, 6) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_2_6[A1,A2,R1,B1,B2,B4,B5,B6,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,R1,B4,B5,B6),R2]) : Term7[B1,B2,A1,A2,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 2, 6) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_2_6[A1,A2,R1,B1,B2,B3,B5,B6,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,R1,B5,B6),R2]) : Term7[B1,B2,B3,A1,A2,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 2, 6) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_2_6[A1,A2,R1,B1,B2,B3,B4,B6,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,B4,R1,B6),R2]) : Term7[B1,B2,B3,B4,A1,A2,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 2, 6) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_5_2_6[A1,A2,R1,B1,B2,B3,B4,B5,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,B4,B5,R1),R2]) : Term7[B1,B2,B3,B4,B5,A1,A2,R2] = { + val (newExpr, newTypes) = compose(f, g, 5, 2, 6) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_3_6[A1,A2,A3,R1,B2,B3,B4,B5,B6,R2](f : Term[(A1,A2,A3),R1], g : Term[(R1,B2,B3,B4,B5,B6),R2]) : Term8[A1,A2,A3,B2,B3,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 3, 6) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_3_6[A1,A2,A3,R1,B1,B3,B4,B5,B6,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,R1,B3,B4,B5,B6),R2]) : Term8[B1,A1,A2,A3,B3,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 3, 6) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_3_6[A1,A2,A3,R1,B1,B2,B4,B5,B6,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,R1,B4,B5,B6),R2]) : Term8[B1,B2,A1,A2,A3,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 3, 6) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_3_6[A1,A2,A3,R1,B1,B2,B3,B5,B6,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,B3,R1,B5,B6),R2]) : Term8[B1,B2,B3,A1,A2,A3,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 3, 6) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_3_6[A1,A2,A3,R1,B1,B2,B3,B4,B6,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,B3,B4,R1,B6),R2]) : Term8[B1,B2,B3,B4,A1,A2,A3,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 3, 6) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_5_3_6[A1,A2,A3,R1,B1,B2,B3,B4,B5,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,B3,B4,B5,R1),R2]) : Term8[B1,B2,B3,B4,B5,A1,A2,A3,R2] = { + val (newExpr, newTypes) = compose(f, g, 5, 3, 6) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_4_6[A1,A2,A3,A4,R1,B2,B3,B4,B5,B6,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(R1,B2,B3,B4,B5,B6),R2]) : Term9[A1,A2,A3,A4,B2,B3,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 4, 6) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_4_6[A1,A2,A3,A4,R1,B1,B3,B4,B5,B6,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,R1,B3,B4,B5,B6),R2]) : Term9[B1,A1,A2,A3,A4,B3,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 4, 6) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_4_6[A1,A2,A3,A4,R1,B1,B2,B4,B5,B6,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,B2,R1,B4,B5,B6),R2]) : Term9[B1,B2,A1,A2,A3,A4,B4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 4, 6) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_4_6[A1,A2,A3,A4,R1,B1,B2,B3,B5,B6,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,B2,B3,R1,B5,B6),R2]) : Term9[B1,B2,B3,A1,A2,A3,A4,B5,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 4, 6) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_4_6[A1,A2,A3,A4,R1,B1,B2,B3,B4,B6,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,B2,B3,B4,R1,B6),R2]) : Term9[B1,B2,B3,B4,A1,A2,A3,A4,B6,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 4, 6) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_5_4_6[A1,A2,A3,A4,R1,B1,B2,B3,B4,B5,R2](f : Term[(A1,A2,A3,A4),R1], g : Term[(B1,B2,B3,B4,B5,R1),R2]) : Term9[B1,B2,B3,B4,B5,A1,A2,A3,A4,R2] = { + val (newExpr, newTypes) = compose(f, g, 5, 4, 6) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_1_7[A1,R1,B2,B3,B4,B5,B6,B7,R2](f : Term[(A1),R1], g : Term[(R1,B2,B3,B4,B5,B6,B7),R2]) : Term7[A1,B2,B3,B4,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 1, 7) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_1_7[A1,R1,B1,B3,B4,B5,B6,B7,R2](f : Term[(A1),R1], g : Term[(B1,R1,B3,B4,B5,B6,B7),R2]) : Term7[B1,A1,B3,B4,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 1, 7) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_1_7[A1,R1,B1,B2,B4,B5,B6,B7,R2](f : Term[(A1),R1], g : Term[(B1,B2,R1,B4,B5,B6,B7),R2]) : Term7[B1,B2,A1,B4,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 1, 7) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_1_7[A1,R1,B1,B2,B3,B5,B6,B7,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,R1,B5,B6,B7),R2]) : Term7[B1,B2,B3,A1,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 1, 7) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_1_7[A1,R1,B1,B2,B3,B4,B6,B7,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,R1,B6,B7),R2]) : Term7[B1,B2,B3,B4,A1,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 1, 7) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_5_1_7[A1,R1,B1,B2,B3,B4,B5,B7,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,B5,R1,B7),R2]) : Term7[B1,B2,B3,B4,B5,A1,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 5, 1, 7) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_6_1_7[A1,R1,B1,B2,B3,B4,B5,B6,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,B5,B6,R1),R2]) : Term7[B1,B2,B3,B4,B5,B6,A1,R2] = { + val (newExpr, newTypes) = compose(f, g, 6, 1, 7) + Term7(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_2_7[A1,A2,R1,B2,B3,B4,B5,B6,B7,R2](f : Term[(A1,A2),R1], g : Term[(R1,B2,B3,B4,B5,B6,B7),R2]) : Term8[A1,A2,B2,B3,B4,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 2, 7) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_2_7[A1,A2,R1,B1,B3,B4,B5,B6,B7,R2](f : Term[(A1,A2),R1], g : Term[(B1,R1,B3,B4,B5,B6,B7),R2]) : Term8[B1,A1,A2,B3,B4,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 2, 7) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_2_7[A1,A2,R1,B1,B2,B4,B5,B6,B7,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,R1,B4,B5,B6,B7),R2]) : Term8[B1,B2,A1,A2,B4,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 2, 7) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_2_7[A1,A2,R1,B1,B2,B3,B5,B6,B7,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,R1,B5,B6,B7),R2]) : Term8[B1,B2,B3,A1,A2,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 2, 7) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_2_7[A1,A2,R1,B1,B2,B3,B4,B6,B7,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,B4,R1,B6,B7),R2]) : Term8[B1,B2,B3,B4,A1,A2,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 2, 7) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_5_2_7[A1,A2,R1,B1,B2,B3,B4,B5,B7,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,B4,B5,R1,B7),R2]) : Term8[B1,B2,B3,B4,B5,A1,A2,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 5, 2, 7) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_6_2_7[A1,A2,R1,B1,B2,B3,B4,B5,B6,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,B4,B5,B6,R1),R2]) : Term8[B1,B2,B3,B4,B5,B6,A1,A2,R2] = { + val (newExpr, newTypes) = compose(f, g, 6, 2, 7) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_3_7[A1,A2,A3,R1,B2,B3,B4,B5,B6,B7,R2](f : Term[(A1,A2,A3),R1], g : Term[(R1,B2,B3,B4,B5,B6,B7),R2]) : Term9[A1,A2,A3,B2,B3,B4,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 3, 7) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_3_7[A1,A2,A3,R1,B1,B3,B4,B5,B6,B7,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,R1,B3,B4,B5,B6,B7),R2]) : Term9[B1,A1,A2,A3,B3,B4,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 3, 7) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_3_7[A1,A2,A3,R1,B1,B2,B4,B5,B6,B7,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,R1,B4,B5,B6,B7),R2]) : Term9[B1,B2,A1,A2,A3,B4,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 3, 7) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_3_7[A1,A2,A3,R1,B1,B2,B3,B5,B6,B7,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,B3,R1,B5,B6,B7),R2]) : Term9[B1,B2,B3,A1,A2,A3,B5,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 3, 7) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_3_7[A1,A2,A3,R1,B1,B2,B3,B4,B6,B7,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,B3,B4,R1,B6,B7),R2]) : Term9[B1,B2,B3,B4,A1,A2,A3,B6,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 3, 7) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_5_3_7[A1,A2,A3,R1,B1,B2,B3,B4,B5,B7,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,B3,B4,B5,R1,B7),R2]) : Term9[B1,B2,B3,B4,B5,A1,A2,A3,B7,R2] = { + val (newExpr, newTypes) = compose(f, g, 5, 3, 7) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_6_3_7[A1,A2,A3,R1,B1,B2,B3,B4,B5,B6,R2](f : Term[(A1,A2,A3),R1], g : Term[(B1,B2,B3,B4,B5,B6,R1),R2]) : Term9[B1,B2,B3,B4,B5,B6,A1,A2,A3,R2] = { + val (newExpr, newTypes) = compose(f, g, 6, 3, 7) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_1_8[A1,R1,B2,B3,B4,B5,B6,B7,B8,R2](f : Term[(A1),R1], g : Term[(R1,B2,B3,B4,B5,B6,B7,B8),R2]) : Term8[A1,B2,B3,B4,B5,B6,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 1, 8) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_1_8[A1,R1,B1,B3,B4,B5,B6,B7,B8,R2](f : Term[(A1),R1], g : Term[(B1,R1,B3,B4,B5,B6,B7,B8),R2]) : Term8[B1,A1,B3,B4,B5,B6,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 1, 8) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_1_8[A1,R1,B1,B2,B4,B5,B6,B7,B8,R2](f : Term[(A1),R1], g : Term[(B1,B2,R1,B4,B5,B6,B7,B8),R2]) : Term8[B1,B2,A1,B4,B5,B6,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 1, 8) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_1_8[A1,R1,B1,B2,B3,B5,B6,B7,B8,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,R1,B5,B6,B7,B8),R2]) : Term8[B1,B2,B3,A1,B5,B6,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 1, 8) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_1_8[A1,R1,B1,B2,B3,B4,B6,B7,B8,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,R1,B6,B7,B8),R2]) : Term8[B1,B2,B3,B4,A1,B6,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 1, 8) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_5_1_8[A1,R1,B1,B2,B3,B4,B5,B7,B8,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,B5,R1,B7,B8),R2]) : Term8[B1,B2,B3,B4,B5,A1,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 5, 1, 8) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_6_1_8[A1,R1,B1,B2,B3,B4,B5,B6,B8,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,B5,B6,R1,B8),R2]) : Term8[B1,B2,B3,B4,B5,B6,A1,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 6, 1, 8) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_7_1_8[A1,R1,B1,B2,B3,B4,B5,B6,B7,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,B5,B6,B7,R1),R2]) : Term8[B1,B2,B3,B4,B5,B6,B7,A1,R2] = { + val (newExpr, newTypes) = compose(f, g, 7, 1, 8) + Term8(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_2_8[A1,A2,R1,B2,B3,B4,B5,B6,B7,B8,R2](f : Term[(A1,A2),R1], g : Term[(R1,B2,B3,B4,B5,B6,B7,B8),R2]) : Term9[A1,A2,B2,B3,B4,B5,B6,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 2, 8) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_2_8[A1,A2,R1,B1,B3,B4,B5,B6,B7,B8,R2](f : Term[(A1,A2),R1], g : Term[(B1,R1,B3,B4,B5,B6,B7,B8),R2]) : Term9[B1,A1,A2,B3,B4,B5,B6,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 2, 8) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_2_8[A1,A2,R1,B1,B2,B4,B5,B6,B7,B8,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,R1,B4,B5,B6,B7,B8),R2]) : Term9[B1,B2,A1,A2,B4,B5,B6,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 2, 8) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_2_8[A1,A2,R1,B1,B2,B3,B5,B6,B7,B8,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,R1,B5,B6,B7,B8),R2]) : Term9[B1,B2,B3,A1,A2,B5,B6,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 2, 8) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_2_8[A1,A2,R1,B1,B2,B3,B4,B6,B7,B8,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,B4,R1,B6,B7,B8),R2]) : Term9[B1,B2,B3,B4,A1,A2,B6,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 2, 8) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_5_2_8[A1,A2,R1,B1,B2,B3,B4,B5,B7,B8,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,B4,B5,R1,B7,B8),R2]) : Term9[B1,B2,B3,B4,B5,A1,A2,B7,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 5, 2, 8) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_6_2_8[A1,A2,R1,B1,B2,B3,B4,B5,B6,B8,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,B4,B5,B6,R1,B8),R2]) : Term9[B1,B2,B3,B4,B5,B6,A1,A2,B8,R2] = { + val (newExpr, newTypes) = compose(f, g, 6, 2, 8) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_7_2_8[A1,A2,R1,B1,B2,B3,B4,B5,B6,B7,R2](f : Term[(A1,A2),R1], g : Term[(B1,B2,B3,B4,B5,B6,B7,R1),R2]) : Term9[B1,B2,B3,B4,B5,B6,B7,A1,A2,R2] = { + val (newExpr, newTypes) = compose(f, g, 7, 2, 8) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_0_1_9[A1,R1,B2,B3,B4,B5,B6,B7,B8,B9,R2](f : Term[(A1),R1], g : Term[(R1,B2,B3,B4,B5,B6,B7,B8,B9),R2]) : Term9[A1,B2,B3,B4,B5,B6,B7,B8,B9,R2] = { + val (newExpr, newTypes) = compose(f, g, 0, 1, 9) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_1_1_9[A1,R1,B1,B3,B4,B5,B6,B7,B8,B9,R2](f : Term[(A1),R1], g : Term[(B1,R1,B3,B4,B5,B6,B7,B8,B9),R2]) : Term9[B1,A1,B3,B4,B5,B6,B7,B8,B9,R2] = { + val (newExpr, newTypes) = compose(f, g, 1, 1, 9) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_2_1_9[A1,R1,B1,B2,B4,B5,B6,B7,B8,B9,R2](f : Term[(A1),R1], g : Term[(B1,B2,R1,B4,B5,B6,B7,B8,B9),R2]) : Term9[B1,B2,A1,B4,B5,B6,B7,B8,B9,R2] = { + val (newExpr, newTypes) = compose(f, g, 2, 1, 9) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_3_1_9[A1,R1,B1,B2,B3,B5,B6,B7,B8,B9,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,R1,B5,B6,B7,B8,B9),R2]) : Term9[B1,B2,B3,A1,B5,B6,B7,B8,B9,R2] = { + val (newExpr, newTypes) = compose(f, g, 3, 1, 9) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_4_1_9[A1,R1,B1,B2,B3,B4,B6,B7,B8,B9,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,R1,B6,B7,B8,B9),R2]) : Term9[B1,B2,B3,B4,A1,B6,B7,B8,B9,R2] = { + val (newExpr, newTypes) = compose(f, g, 4, 1, 9) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_5_1_9[A1,R1,B1,B2,B3,B4,B5,B7,B8,B9,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,B5,R1,B7,B8,B9),R2]) : Term9[B1,B2,B3,B4,B5,A1,B7,B8,B9,R2] = { + val (newExpr, newTypes) = compose(f, g, 5, 1, 9) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_6_1_9[A1,R1,B1,B2,B3,B4,B5,B6,B8,B9,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,B5,B6,R1,B8,B9),R2]) : Term9[B1,B2,B3,B4,B5,B6,A1,B8,B9,R2] = { + val (newExpr, newTypes) = compose(f, g, 6, 1, 9) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_7_1_9[A1,R1,B1,B2,B3,B4,B5,B6,B7,B9,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,B5,B6,B7,R1,B9),R2]) : Term9[B1,B2,B3,B4,B5,B6,B7,A1,B9,R2] = { + val (newExpr, newTypes) = compose(f, g, 7, 1, 9) + Term9(f.program, newExpr, newTypes, f.converter) + } + + private def compose_8_1_9[A1,R1,B1,B2,B3,B4,B5,B6,B7,B8,R2](f : Term[(A1),R1], g : Term[(B1,B2,B3,B4,B5,B6,B7,B8,R1),R2]) : Term9[B1,B2,B3,B4,B5,B6,B7,B8,A1,R2] = { + val (newExpr, newTypes) = compose(f, g, 8, 1, 9) + Term9(f.program, newExpr, newTypes, f.converter) } /** Compute composed expression for g∘f */ diff --git a/src/cp/Utils.scala b/src/cp/Utils.scala index 39eb23dd7..335cc062e 100644 --- a/src/cp/Utils.scala +++ b/src/cp/Utils.scala @@ -2,45 +2,211 @@ package cp object Utils { + val composeMethods = scala.collection.mutable.Map[Int,Seq[String]]() + private def indent(s : String) : String = s.split("\n").mkString(" ", "\n ", "") + /** Generate `compose' methods for terms */ object GenerateCompose { - private def indent(s : String) : String = s.split("\n").mkString(" ", "\n ", "") - def apply(maxArity : Int) : String = { val methods : Seq[String] = (for (arityG <- 1 to maxArity) yield { for (arityF <- 1 to (maxArity - arityG + 1)) yield { for (index <- 0 until arityG) yield { - val sb = new scala.collection.mutable.StringBuilder - sb.append("private def compose_") - sb.append(index + "_" + arityF + "_" + arityG) + val methodName = "compose_%d_%d_%d" format (index, arityF, arityG) val fParams = (1 to arityF).map("A" + _) val gParams = (1 to arityG).map("B" + _) val replacedGParams = gParams.take(index) ++ Seq("R1") ++ gParams.drop(index + 1) val allParams = fParams ++ Seq("R1") ++ (gParams.take(index) ++ gParams.drop(index + 1)) ++ Seq("R2") - sb.append(allParams.mkString("[", ",", "]")) + val methodParams = allParams.mkString("[", ",", "]") - sb.append("(f : Term[") - sb.append(fParams.mkString("(", ",", ")")) - sb.append(",R1], g : Term[") - sb.append(replacedGParams.mkString("(", ",", ")")) - sb.append(",R2]) : Term") + val fParamsTuple = fParams.mkString("(", ",", ")") + val replacedGParamsTuple = replacedGParams.mkString("(", ",", ")") val newTermSize = arityG + arityF - 1 - val resultParams = gParams.take(index) ++ fParams ++ gParams.drop(index + 1) ++ Seq("R2") - - sb.append(resultParams.mkString(newTermSize + "[", ",", "]")) - sb.append(" = {\n") - sb.append(indent("val (newExpr, newTypes) = compose(f, g, " + index + ", " + arityF + ", " + arityG + ")")) - sb.append("\n") - sb.append(indent("Term" + newTermSize + "(f.program, newExpr, newTypes, f.converter)")) - sb.append("\n") - sb.append("}") - sb.toString + val resultParams = (gParams.take(index) ++ fParams ++ gParams.drop(index + 1) ++ Seq("R2")).mkString("[", ",", "]") + + val fParamsBrackets = fParams.mkString("[", ",", "]") + val rangeType = "T" + (index + 1) + val otherTypeParams = (fParams ++ Seq(rangeType)).mkString("[", ",", "]") + val resultTermArity = arityG + arityF - 1 + val classParams = (1 to arityG) map ("T" + _) + val resultTermParams = (classParams.take(index) ++ fParams ++ classParams.drop(index + 1) ++ Seq("R")).mkString("[", ",", "]") + + val s1 = +"""private def %s%s(f : Term[%s,%s], g : Term[%s,%s]) : Term%d%s = { + val (newExpr, newTypes) = compose(f, g, %d, %d, %d) + Term%d(f.program, newExpr, newTypes, f.converter) +}""" format (methodName, methodParams, fParamsTuple, "R1", replacedGParamsTuple, "R2", newTermSize, resultParams, index, arityF, arityG, newTermSize) + + val s2 = +"""def compose%d%s(other : Term%d%s) : Term%d%s = %s(other, this)""" format (index, fParamsBrackets, arityF, otherTypeParams, resultTermArity, resultTermParams, methodName) + composeMethods(arityG) = s2 +: composeMethods.getOrElse(arityG,Nil) + + s1 } } }).flatten.flatten + + methods.mkString("\n\n") + } + } + + object GenerateTerms { + def apply(maxArity : Int) : String = { + val termTraits = for (arity <- 1 to maxArity) yield { + val traitArgParams = (1 to arity) map ("T" + _) + val traitArgParamsString = traitArgParams.mkString("[", ",", "]") + val traitParams = traitArgParams ++ Seq("R") + val traitParamsString = traitParams.mkString("[", ",", "]") + val termClassParamTuple = traitArgParams.mkString("(", ",", ")") + val traitName = "Term%d%s" format (arity, traitParamsString) + val booleanTraitName = "Term%d%s" format (arity, (traitArgParams ++ Seq("Boolean")).mkString("[", ",", "]")) + val orConstraintName = "OrConstraint%d%s" format (arity, traitArgParamsString) + val andConstraintName = "AndConstraint%d%s" format (arity, traitArgParamsString) + val notConstraintName = "NotConstraint%d%s" format (arity, traitArgParamsString) + val curriedImplicit2Boolean = "(implicit asConstraint : t2c)" + val orMethod = "def ||(other : %s)%s : %s = %s(this, other)" format (booleanTraitName, curriedImplicit2Boolean, booleanTraitName, orConstraintName) + val andMethod = "def &&(other : %s)%s : %s = %s(this, other)" format (booleanTraitName, curriedImplicit2Boolean, booleanTraitName, andConstraintName) + val notMethod = "def unary_!%s : %s = %s(this)" format (curriedImplicit2Boolean, booleanTraitName, notConstraintName) + + val intTraitName = "Term%d%s" format (arity, (traitArgParams ++ Seq("Int")).mkString("[", ",", "]")) + val minimizingMethod = +"""def minimizing(minFunc : %s)%s : MinConstraint%d%s = { + MinConstraint%d%s(asConstraint(this), minFunc) +}""" format (intTraitName, curriedImplicit2Boolean, arity, traitArgParamsString, arity, traitArgParamsString) + + val composeMethodsString = composeMethods.getOrElse(arity, Nil).reverse.mkString("\n") + + val termTraitString = +"""sealed trait %s extends Term[%s,%s] { + val convertingFunction = converterOf(this).exprSeq2scala%d%s _ + type t2c = (%s) => %s + +%s + +%s + +%s + +%s + +%s +}""" format (traitName, termClassParamTuple, "R", arity, traitArgParamsString, traitName, booleanTraitName, indent(orMethod), indent(andMethod), indent(notMethod), indent(minimizingMethod), indent(composeMethodsString)) + + termTraitString + } + + termTraits.mkString("\n\n") + } + } + + object GenerateTermObjects { + def apply(maxArity : Int) : String = { + val objectStrings = for (arity <- 1 to maxArity) yield { + val argParams = (1 to arity) map ("T" + _) + val argParamsString = argParams.mkString("[", ",", "]") + val applyParamString = (argParams ++ Seq("R")).mkString("[", ",", "]") + val argParamTuple = argParams.mkString("(", ",", ")") + val termClassName = "Term[%s,%s]" format (argParamTuple, "R") + val booleanTermClassName = "Term[%s,%s]" format (argParamTuple, "Boolean") + val termTraitName = "Term%d%s" format (arity, applyParamString) + val booleanTermTraitName = "Term%d%s" format (arity, (argParams ++ Seq("Boolean")).mkString("[", ",", "]")) + val objectString = +"""object Term%d { + def apply%s(conv : Converter, serializedProg : Serialized, serializedInputVars: Serialized, serializedOutputVars : Serialized, serializedExpr : Serialized, inputVarValues : Seq[Expr]) = { + val (converter, program, expr, types) = Term.processArgs(conv, serializedProg, serializedInputVars, serializedOutputVars, serializedExpr, inputVarValues) + new %s(program, expr, types, converter) with %s + } + + def apply%s(program : Program, expr : Expr, types : Seq[TypeTree], converter : Converter) = + new %s(program, expr, types, converter) with %s +}""" format (arity, applyParamString, termClassName, termTraitName, applyParamString, termClassName, termTraitName) + + val binaryOpObjectString = +"""object %sConstraint%d { + def apply%s(l : %s, r : %s) : %s = (l, r) match { + case (Term(p1,ex1,ts1,conv1), Term(p2,ex2,ts2,conv2)) => Term%d(p1,%s(ex1,ex2),ts1,conv1) + } +}""" + val orObjectString = binaryOpObjectString format ("Or", arity, argParamsString, booleanTermClassName, booleanTermClassName, booleanTermTraitName, arity, "Or") + val andObjectString = binaryOpObjectString format ("And", arity, argParamsString, booleanTermClassName, booleanTermClassName, booleanTermTraitName, arity, "And") + + val unaryOpObjectString = +"""object %sConstraint%d { + def apply%s(c : %s) : %s = c match { + case Term(p,ex,ts,conv) => Term%d(p,%s(ex),ts,conv) + } +}""" + + val notObjectString = unaryOpObjectString format ("Not", arity, argParamsString, booleanTermClassName, booleanTermTraitName, arity, "Not") + + List(objectString, orObjectString, andObjectString, notObjectString).mkString("\n\n") + } + + objectStrings.mkString("\n\n") + } + } + + object GenerateMinConstraintClasses { + def apply(maxArity : Int) : String = { + val classes = for (arity <- 1 to maxArity) yield { + val params = (1 to arity) map ("T" + _) + val paramString = params.mkString("[", ",", "]") + val paramTupleString = params.mkString("(", ",", ")") + val booleanTermParams = (params ++ Seq("Boolean")).mkString("[", ",", "]") + val intTermParams = (params ++ Seq("Int")).mkString("[", ",", "]") + val booleanTermName = "Term%d%s" format (arity, booleanTermParams) + val intTermName = "Term%d%s" format (arity, intTermParams) + val classString = +"""case class MinConstraint%d%s(cons : %s, minFunc : %s) extends MinConstraint[%s](cons, minFunc) { + val convertingFunction = converterOf(cons).exprSeq2scala%d%s _ +}""" format (arity, paramString, booleanTermName, intTermName, paramTupleString, arity, paramString) + + classString + } + + classes.mkString("\n\n") + } + } + + object GenerateTypeAliases { + def apply(maxArity : Int) : String = { + var booleanTerms = List[String]() + var intTerms = List[String]() + + booleanTerms = "type Constraint[T] = Term[T,Boolean]" :: booleanTerms + intTerms = "type IntTerm[T] = Term[T,Int]" :: intTerms + + for (arity <- 1 to maxArity) { + val params = (1 to arity) map ("T" + _) + val paramWithBooleanString = (params ++ Seq("Boolean")).mkString("[", ",", "]") + val paramWithIntString = (params ++ Seq("Int")).mkString("[", ",", "]") + val paramString = params.mkString("[", ",", "]") + val boolType = "type Constraint%d%s = Term%d%s" format (arity, paramString, arity, paramWithBooleanString) + val intType = "type IntTerm%d%s = Term%d%s" format (arity, paramString, arity, paramWithIntString) + + booleanTerms = boolType :: booleanTerms + intTerms = intType :: intTerms + } + + (booleanTerms.reverse ++ intTerms.reverse).mkString("\n") + } + } + + object GenerateConverterMethods { + def apply(maxArity : Int) : String = { + val methods = for (arity <- 1 to maxArity) yield { + val params = (1 to arity) map ("T" + _) + val paramsBrackets = params.mkString("[", ",", "]") + val paramsParen = params.mkString("(", ",", ")") + val tuple = params.zipWithIndex.map{ case (p, i) => "expr2scala(exprs(%d)).asInstanceOf[%s]" format (i, p) }.mkString("(", ",", ")") + val methodString = +"""def exprSeq2scala%d%s(exprs : Seq[Expr]) : %s = + %s""" format (arity, paramsBrackets, paramsParen, tuple) + + methodString + } methods.mkString("\n\n") } @@ -48,5 +214,10 @@ object Utils { def main(args: Array[String]) : Unit = { println(GenerateCompose(args(0).toInt)) + println(GenerateTerms(args(0).toInt)) + println(GenerateTermObjects(args(0).toInt)) + println(GenerateMinConstraintClasses(args(0).toInt)) + println(GenerateTypeAliases(args(0).toInt)) + println(GenerateConverterMethods(args(0).toInt)) } } -- GitLab