diff --git a/src/main/scala/inox/ast/DSL.scala b/src/main/scala/inox/ast/DSL.scala
index 0f4f0404f73980b24b32106779bfaf8ae0bf1948..9fed5297a0f71c92df1210d63b398c207d9230aa 100644
--- a/src/main/scala/inox/ast/DSL.scala
+++ b/src/main/scala/inox/ast/DSL.scala
@@ -5,6 +5,18 @@ package ast
 
 import scala.language.implicitConversions
 
+/** This trait provides a DSL to create Inox trees.
+  *
+  * The two following principles are followed (hopefully with some consistency):
+  * 1) When a fresh identifier needs to be introduced, the API provides constructors
+  *    which are passed the fresh identifiers in the form of [[inox.ast.Definitions.ValDef]]s
+  *    (construct them with [[inox.ast.DSL.TypeToValDef]]), and then a context
+  *    (in the form of a function) to which the newly created identifiers will be passed.
+  * 2) No implicit conversions are provided where there would be ambiguity.
+  *    This refers mainly to Identifiers, which can be transformed to
+  *    [[inox.ast.Types.ClassType]] or [[inox.ast.Expressions.FunctionInvocation]] or ... .
+  *    Instead one-letter constructors are provided.
+  */
 trait DSL {
   val program: Program
   import program._
@@ -38,20 +50,23 @@ trait DSL {
     }
 
     // Arithmetic
-    def +   = binOp(Plus, plus)
-    def -   = binOp(Minus, minus)
+    def + = binOp(Plus, plus)
+    def - = binOp(Minus, minus)
+    def % = binOp(Modulo, Modulo)
+    def / = binOp(Division, Division)
+
+    // Comparisons
+    def <   = binOp(LessThan, LessThan)
+    def <=  = binOp(LessEquals, LessEquals)
+    def >   = binOp(GreaterThan, GreaterThan)
+    def >=  = binOp(GreaterEquals, GreaterEquals)
     def === = binOp(Equals, equality)
+
+    // Boolean
     def &&  = binOp(And(_, _), and(_, _))
     def ||  = binOp(Or(_, _), or(_, _))
     def ==> = binOp(Implies, implies)
-    def %   = binOp(Modulo, Modulo)
-    def /   = binOp(Division, Division)
-
-    // Comparisons
-    def <  = binOp(LessThan, LessThan)
-    def <= = binOp(LessEquals, LessEquals)
-    def >  = binOp(GreaterThan, GreaterThan)
-    def >= = binOp(GreaterEquals, GreaterEquals)
+    def unary_! = unOp(Not, not)
 
     // Tuple selections
     def _1 = unOp(TupleSelect(_, 1), tupleSelect(_, 1, true))
@@ -60,8 +75,9 @@ trait DSL {
     def _4 = unOp(TupleSelect(_, 4), tupleSelect(_, 4, true))
 
     // Sets
-    def size      = SetCardinality(e)
-    def subsetOf  = binOp(SubsetOf, SubsetOf)
+    def size     = SetCardinality(e)
+    def subsetOf = binOp(SubsetOf, SubsetOf)
+    def insert   = binOp(SetAdd, SetAdd)
     def ++ = binOp(SetUnion, SetUnion)
     def -- = binOp(SetDifference, SetDifference)
     def &  = binOp(SetIntersection, SetIntersection)
@@ -100,7 +116,12 @@ trait DSL {
     require(s.nonEmpty)
     FiniteSet(s.toSeq, leastUpperBound(s.toSeq map (_.getType)).get)
   }
-  def E(vd: ValDef) = vd.toVariable
+  def E(vd: ValDef) = vd.toVariable // TODO: We should be able to remove this
+  def E(id: Identifier) = new IdToFunInv(id)
+  class IdToFunInv(id: Identifier) {
+    def apply(tps: TypeParameter*)(args: Expr*) =
+      FunctionInvocation(id, tps.toSeq, args.toSeq)
+  }
 
   // if-then-else
   class DanglingElse(cond: Expr, thenn: Expr) {
@@ -123,11 +144,18 @@ trait DSL {
     def ## (id: Int) = GenericValue(tp, id)
   }
 
-  // This introduces valdefs
+  // Syntax to make ValDefs, e.g. ("i" :: Integer)
   implicit class TypeToValDef(tp: Type) {
     def :: (nm: String): ValDef = ValDef(FreshIdentifier(nm, true), tp)
   }
 
+  /** Creates a [[Let]]. A [[ValDef]] and a context is given; the identifier of the ValDef
+    * is passed to the context.
+    *
+    * @param vd The ValDef which will be bound in the body (see [[TypeToValDef.::]])
+    * @param v The value bound to the let-variable
+    * @param body The context which will be filled with the let-variable
+    */
   def let(vd: ValDef, v: Expr)(body: Expr => Expr)(implicit simpLvl: SimplificationLevel) = {
     simp(
       Let(vd, v, body(vd.toVariable)),
@@ -258,7 +286,7 @@ trait DSL {
             P("k" :: Untyped),
             P(__, ( "j" :: Untyped) @@ P(42))
           ) ==> {
-            (i, j, k) => e1
+            (i, j, k) => !e1
           },
           __ ~|~ e1 ==> e2
         )
@@ -268,7 +296,8 @@ trait DSL {
 
   /* Types */
   def T(tp1: Type, tp2: Type, tps: Type*) = TupleType(tp1 :: tp2 :: tps.toList)
-  implicit class IdToClassType(id: Identifier) {
+  def T(id: Identifier) = new IdToClassType(id)
+  class IdToClassType(id: Identifier) {
     def apply(tps: Type*) = ClassType(id, tps.toSeq)
   }
   implicit class FunctionTypeBuilder(to: Type) {
@@ -280,7 +309,6 @@ trait DSL {
       FunctionType(Seq(from._1, from._2, from._3), to)
     def =>: (from: (Type, Type, Type, Type)) =
       FunctionType(Seq(from._1, from._2, from._3, from._4), to)
-
   }
 
   // TODO remove this at some point
@@ -288,9 +316,9 @@ trait DSL {
     val ct1 = FreshIdentifier("ct1")
     val ct2 = FreshIdentifier("ct2")
     T(
-      ct1(),
-      ct1(ct2(), IntegerType),
-      (ct1(), ct2()) =>: ct1()
+      T(ct1)(),
+      T(ct1)(T(ct2)(), IntegerType),
+      (T(ct1)(), T(ct2)()) =>: T(ct1)()
     )
   }
 
@@ -311,9 +339,7 @@ trait DSL {
     */
   def mkFunDef(id: Identifier)
               (tParamNames: String*)
-              (builder: Seq[TypeParameter] =>
-                (Seq[ValDef], Type, Seq[Expr] => Expr)
-              ) = {
+              (builder: Seq[TypeParameter] => (Seq[ValDef], Type, Seq[Expr] => Expr)) = {
     val tParams = tParamNames map TypeParameter.fresh
     val tParamDefs = tParams map TypeParameterDef
     val (params, retType, bodyBuilder) = builder(tParams)
@@ -347,7 +373,7 @@ trait DSL {
     }
   */
   private def testDefs = {
-    val c = FreshIdentifier("c")
+    val c = T(FreshIdentifier("c"))
     val f = FreshIdentifier("f")
     mkFunDef(f)("A", "B"){ case Seq(aT, bT) => (
       Seq("i" :: IntegerType, "j" :: c(aT), "a" :: aT),