From ffaae455670db62698adc234c28fabc8490803e7 Mon Sep 17 00:00:00 2001
From: Manos Koukoutos <emmanouil.koukoutos@epfl.ch>
Date: Wed, 10 Aug 2016 10:23:01 +0200
Subject: [PATCH] Documentation

---
 src/main/scala/inox/ast/Definitions.scala | 79 ++++++++++++++---------
 src/main/scala/inox/ast/Expressions.scala | 36 ++++-------
 2 files changed, 63 insertions(+), 52 deletions(-)

diff --git a/src/main/scala/inox/ast/Definitions.scala b/src/main/scala/inox/ast/Definitions.scala
index 4559bc702..69f9b2269 100644
--- a/src/main/scala/inox/ast/Definitions.scala
+++ b/src/main/scala/inox/ast/Definitions.scala
@@ -5,8 +5,10 @@ package ast
 
 import scala.collection.mutable.{Map => MutableMap}
 
+/** Provides types that describe Inox definitions. */
 trait Definitions { self: Trees =>
 
+  /** The base trait for Inox definitions */
   sealed trait Definition extends Tree {
     val id: Identifier
 
@@ -82,7 +84,7 @@ trait Definitions { self: Trees =>
 
   type Symbols >: Null <: AbstractSymbols
 
-  /** A wrapper for a program. For now a program is simply a single object. */
+  /** Provides the class and function definitions of a program and lookups on them */
   trait AbstractSymbols
      extends Printable
         with TypeOps
@@ -158,12 +160,14 @@ trait Definitions { self: Trees =>
 
   // Compiler annotations given in the source code as @annot
   case class Annotation(annot: String, args: Seq[Option[Any]]) extends FunctionFlag with ClassFlag
-  // Class has ADT invariant method
+  /** Denotes that this class is refined by invariant ''id'' */
   case class HasADTInvariant(id: Identifier) extends ClassFlag
   // Is inlined
   case object IsInlined extends FunctionFlag
 
-  /** Represents a class definition (either an abstract- or a case-class) */
+  /** Represents a class definition (either an abstract- or a case-class).
+    * In functional terms, abstract classes are ADTs and case classes are ADT constructors.
+    */
   sealed trait ClassDef extends Definition {
     val id: Identifier
     val tparams: Seq[TypeParameterDef]
@@ -172,7 +176,10 @@ trait Definitions { self: Trees =>
     def annotations: Set[String] = extAnnotations.keySet
     def extAnnotations: Map[String, Seq[Option[Any]]] = flags.collect { case Annotation(s, args) => s -> args }.toMap
 
+    /** The root of the class hierarchy */
     def root(implicit s: Symbols): ClassDef
+
+    /** An invariant that refines this [[ClassDef]] */
     def invariant(implicit s: Symbols): Option[FunDef] = {
       val rt = root
       if (rt ne this) rt.invariant
@@ -189,7 +196,7 @@ trait Definitions { self: Trees =>
     def typed(implicit s: Symbols): TypedClassDef
   }
 
-  /** Abstract classes. */
+  /** Abstract classes / ADTs */
   class AbstractClassDef(val id: Identifier,
                          val tparams: Seq[TypeParameterDef],
                          val children: Seq[Identifier],
@@ -232,7 +239,14 @@ trait Definitions { self: Trees =>
     }
   }
 
-  /** Case classes/ case objects. */
+  /** Case classes/ ADT constructors. For single-case classes these may coincide
+    *
+    * @param id
+    * @param tparams
+    * @param parent
+    * @param fields
+    * @param flags
+    */
   class CaseClassDef(val id: Identifier,
                      val tparams: Seq[TypeParameterDef],
                      val parent: Option[Identifier],
@@ -240,7 +254,7 @@ trait Definitions { self: Trees =>
                      val flags: Set[ClassFlag]) extends ClassDef {
 
     val isAbstract = false
-
+    /** Returns the index of the field with the specified id */
     def selectorID2Index(id: Identifier) : Int = {
       val index = fields.indexWhere(_.id == id)
 
@@ -261,13 +275,14 @@ trait Definitions { self: Trees =>
     }
   }
 
+  /** Represents a [[ClassDef]] whose type parameters have been instantiated to ''tps'' */
   sealed abstract class TypedClassDef extends Tree {
     val cd: ClassDef
     val tps: Seq[Type]
     implicit val symbols: Symbols
 
     val id: Identifier = cd.id
-
+    /** The root of the class hierarchy */
     lazy val root: TypedClassDef = cd.root.typed(tps)
     lazy val invariant: Option[TypedFunDef] = cd.invariant.map(_.typed(tps))
     lazy val hasInvariant: Boolean = invariant.isDefined
@@ -285,10 +300,12 @@ trait Definitions { self: Trees =>
     }
   }
 
+  /** Represents an [[AbstractClassDef]] whose type parameters have been instantiated to ''tps'' */
   case class TypedAbstractClassDef(cd: AbstractClassDef, tps: Seq[Type])(implicit val symbols: Symbols) extends TypedClassDef {
     def descendants: Seq[TypedCaseClassDef] = cd.descendants.map(_.typed(tps))
   }
 
+  /** Represents a [[CaseClassDef]] whose type parameters have been instantiated to ''tps'' */
   case class TypedCaseClassDef(cd: CaseClassDef, tps: Seq[Type])(implicit val symbols: Symbols) extends TypedClassDef {
     lazy val fields: Seq[ValDef] = {
       val tmap = (cd.typeArgs zip tps).toMap
@@ -305,18 +322,11 @@ trait Definitions { self: Trees =>
   }
 
 
-  /** Function/method definition.
-    *
-    *  This class represents methods or fields of objects or classes. By "fields" we mean
-    *  fields defined in the body of a class/object, not the constructor arguments of a case class
-    *  (those are accessible through [[leon.purescala.Definitions.ClassDef.fields]]).
+  /** Function definition
     *
-    *  When it comes to verification, all are treated the same (as functions).
-    *  They are only differentiated when it comes to code generation/ pretty printing.
-    *  By default, the FunDef represents a function/method as opposed to a field,
-    *  unless otherwise specified by its flags.
-    *
-    *  Bear in mind that [[id]] will not be consistently typed.
+    * @param id The identifier which will refer to this function.
+    * @param body The optional body of this function. Empty body functions are treated as uninterpreted
+    * @param flags Flags that annotate this function with attributes.
     */
   class FunDef(
     val id: Identifier,
@@ -327,20 +337,20 @@ trait Definitions { self: Trees =>
     val flags: Set[FunctionFlag]
   ) extends Definition {
 
-    def hasBody          = body.isDefined
+    def hasBody = body.isDefined
 
     def annotations: Set[String] = extAnnotations.keySet
     def extAnnotations: Map[String, Seq[Option[Any]]] = flags.collect {
       case Annotation(s, args) => s -> args
     }.toMap
 
-    /* Wrapping in TypedFunDef */
-
+    /** Wraps this [[FunDef]] in a in [[TypedFunDef]] with the specified type parameters */
     def typed(tps: Seq[Type])(implicit s: Symbols): TypedFunDef = {
       assert(tps.size == tparams.size)
       TypedFunDef(this, tps)
     }
 
+    /** Wraps this [[FunDef]] in a in [[TypedFunDef]] with its own type parameters */
     def typed(implicit s: Symbols): TypedFunDef = typed(tparams.map(_.tp))
 
     /* Auxiliary methods */
@@ -349,12 +359,14 @@ trait Definitions { self: Trees =>
 
     def typeArgs = tparams map (_.tp)
 
+    /** Applies this function on some arguments; type parameters are inferred. */
     def applied(args: Seq[Expr])(implicit s: Symbols): FunctionInvocation = s.functionInvocation(this, args)
+    /** Applies this function on its formal parameters */
     def applied = FunctionInvocation(id, typeArgs, params map (_.toVariable))
   }
 
 
-  // Wrapper for typing function according to valuations for type parameters
+  /** Represents a [[FunDef]] whose type parameters have been instantiated with the specified types */
   case class TypedFunDef(fd: FunDef, tps: Seq[Type])(implicit symbols: Symbols) extends Tree {
     val id = fd.id
 
@@ -370,13 +382,15 @@ trait Definitions { self: Trees =>
       (fd.typeArgs zip tps).toMap.filter(tt => tt._1 != tt._2)
     }
 
-    def translated(t: Type): Type = symbols.instantiateType(t, typesMap)
+    /** A [[Type]] instantiated with this [[TypedFunDef]]'s type instantiation */
+    def instantiate(t: Type): Type = symbols.instantiateType(t, typesMap)
 
-    def translated(e: Expr): Expr = symbols.instantiateType(e, typesMap)
+    /** A [[Expr]] instantiated with this [[TypedFunDef]]'s type instantiation */
+    def instantiate(e: Expr): Expr = symbols.instantiateType(e, typesMap)
 
     /** A mapping from this [[TypedFunDef]]'s formal parameters to real arguments
       *
-      * @param realArgs The arguments to which the formal argumentas are mapped
+      * @param realArgs The arguments to which the formal arguments are mapped
       */
     def paramSubst(realArgs: Seq[Expr]) = {
       require(realArgs.size == params.size)
@@ -392,26 +406,31 @@ trait Definitions { self: Trees =>
       exprOps.replaceFromSymbols(paramSubst(realArgs), e)
     }
 
+    /** Apply this [[inox.ast.Definitions.TypedFunDef]] on specified arguments */
     def applied(realArgs: Seq[Expr]): FunctionInvocation = {
       FunctionInvocation(id, tps, realArgs)
     }
 
+    /** Apply this [[inox.ast.Definitions.TypedFunDef]] on its formal parameters */
     def applied: FunctionInvocation = applied(params map { _.toVariable })
 
-    /** Params will contain ValDefs instantiated with the correct types */
+    /** The paremeters of the respective [[FunDef]] instantiated with the real type parameters */
     lazy val params: Seq[ValDef] = {
       if (typesMap.isEmpty) {
         fd.params
       } else {
-        fd.params.map(vd => vd.copy(tpe = translated(vd.getType)))
+        fd.params.map(vd => vd.copy(tpe = instantiate(vd.getType)))
       }
     }
 
+    /** The function type corresponding to this [[TypedFunDef]]'s arguments and return type */
     lazy val functionType = FunctionType(params.map(_.getType).toList, returnType)
 
-    lazy val returnType: Type = translated(fd.returnType)
+    /** The return type of the respective [[FunDef]] instantiated with the real type parameters */
+    lazy val returnType: Type = instantiate(fd.returnType)
 
-    lazy val body          = fd.body map translated
-    def hasBody           = body.isDefined
+    /** The body of the respective [[FunDef]] instantiated with the real type parameters */
+    lazy val body = fd.body map instantiate
+    def hasBody   = body.isDefined
   }
 }
diff --git a/src/main/scala/inox/ast/Expressions.scala b/src/main/scala/inox/ast/Expressions.scala
index 2828e2cfe..24da96276 100644
--- a/src/main/scala/inox/ast/Expressions.scala
+++ b/src/main/scala/inox/ast/Expressions.scala
@@ -7,19 +7,11 @@ import scala.collection.BitSet
 
 /** Expression definitions for Pure Scala.
   *
-  * If you are looking for things such as function or class definitions,
-  * please have a look in [[purescala.Definitions]].
+  * Every expression in Inox inherits from [[Expressions.Expr]].
+  * Expressions can be manipulated with functions in [[Constructors]] and [[ExprOps]].
   *
-  * Every expression in Leon inherits from [[Expr]]. The AST definitions are simple
-  * case classes, with no behaviour. In particular, they do not perform smart
-  * rewriting. What you build is what you get. For example,
-  * {{{
-  * And(BooleanLiteral(true), Variable(id, BooleanType)) != Variable(id, BooleanType)
-  * }}}
-  * because the ``And`` constructor will simply build a tree without checking for
-  * optimization opportunities. Unless you need exact control on the structure
-  * of the trees, you should use constructors in [[purescala.Constructors]], that
-  * simplify the trees they produce.
+  * If you are looking for things such as function or class definitions,
+  * please have a look in [[inox.ast.Definitions]].
   *
   * @define encodingof Encoding of
   * @define noteBitvector (32-bit vector)
@@ -76,7 +68,7 @@ trait Expressions { self: Trees =>
     * @param vd The ValDef used in body, defined just after '''val'''
     * @param value The value assigned to the identifier, after the '''=''' sign
     * @param body The expression following the ``val ... = ... ;`` construct
-    * @see [[purescala.Constructors#let purescala's constructor let]]
+    * @see [[Constructors#let purescala's constructor let]]
     */
   case class Let(vd: ValDef, value: Expr, body: Expr) extends Expr with CachingTyped {
     protected def computeType(implicit s: Symbols): Type = {
@@ -247,7 +239,7 @@ trait Expressions { self: Trees =>
   /** $encodingof `value.selector` where value is of a case class type
     *
     * If you are not sure about the requirement you should use
-    * [[purescala.Constructors#caseClassSelector purescala's constructor caseClassSelector]]
+    * [[Constructors#caseClassSelector purescala's constructor caseClassSelector]]
     */
   case class CaseClassSelector(caseClass: Expr, selector: Identifier) extends Expr with CachingTyped {
 
@@ -287,8 +279,8 @@ trait Expressions { self: Trees =>
   /** $encodingof `... && ...`
     *
     * [[exprs]] must contain at least two elements; if you are not sure about this,
-    * you should use [[purescala.Constructors#and purescala's constructor and]]
-    * or [[purescala.Constructors#andJoin purescala's constructor andJoin]]
+    * you should use [[Constructors#and purescala's constructor and]]
+    * or [[Constructors#andJoin purescala's constructor andJoin]]
     */
   case class And(exprs: Seq[Expr]) extends Expr with CachingTyped {
     require(exprs.size >= 2)
@@ -305,8 +297,8 @@ trait Expressions { self: Trees =>
   /** $encodingof `... || ...`
     *
     * [[exprs]] must contain at least two elements; if you are not sure about this,
-    * you should use [[purescala.Constructors#or purescala's constructor or]] or
-    * [[purescala.Constructors#orJoin purescala's constructor orJoin]]
+    * you should use [[Constructors#or purescala's constructor or]] or
+    * [[Constructors#orJoin purescala's constructor orJoin]]
     */
   case class Or(exprs: Seq[Expr]) extends Expr with CachingTyped {
     require(exprs.size >= 2)
@@ -325,7 +317,7 @@ trait Expressions { self: Trees =>
     * This is not a standard Scala operator, but it results from an implicit
     * conversion in the Leon library.
     *
-    * @see [[leon.purescala.Constructors.implies]]
+    * @see [[Constructors.implies]]
     */
   case class Implies(lhs: Expr, rhs: Expr) extends Expr with CachingTyped {
     protected def computeType(implicit s: Symbols): Type = {
@@ -336,7 +328,7 @@ trait Expressions { self: Trees =>
 
   /** $encodingof `!...`
     *
-    * @see [[leon.purescala.Constructors.not]]
+    * @see [[Constructors.not]]
     */
   case class Not(expr: Expr) extends Expr with CachingTyped {
     protected def computeType(implicit s: Symbols): Type = {
@@ -525,7 +517,7 @@ trait Expressions { self: Trees =>
     *
     * [[exprs]] should always contain at least 2 elements.
     * If you are not sure about this requirement, you should use
-    * [[leon.purescala.Constructors.tupleWrap purescala's constructor tupleWrap]]
+    * [[Constructors.tupleWrap purescala's constructor tupleWrap]]
     *
     * @param exprs The expressions in the tuple
     */
@@ -538,7 +530,7 @@ trait Expressions { self: Trees =>
     *
     * Index is 1-based, first element of tuple is 1.
     * If you are not sure that [[tuple]] is indeed of a TupleType,
-    * you should use [[leon.purescala.Constructors.tupleSelect(t:leon\.purescala\.Expressions\.Expr,index:Int,isTuple:Boolean):leon\.purescala\.Expressions\.Expr* purescala's constructor tupleSelect]]
+    * you should use [[Constructors.tupleSelect purescala's constructor tupleSelect]]
     */
   case class TupleSelect(tuple: Expr, index: Int) extends Expr with CachingTyped {
     require(index >= 1)
-- 
GitLab