/** Returns true if expr is a value. Stronger than isGround */
/** Returns true if expr is a value. Stronger than isGround */
valisValue=(e:Expr)=>isValueOfType(e,e.getType)
valisValue=(e:Expr)=>isValueOfType(e,e.getType)
/** Returns a nested string explaining why this expression is typed the way it is.*/
defexplainTyping(e:Expr):String={
leon.purescala.ExprOps.fold[String]{(e,se)=>
ematch{
caseFunctionInvocation(tfd,args)=>
s"$e is of type ${e.getType}"+se.map(child=>"\n "+"\n".r.replaceAllIn(child,"\n ")).mkString+s" because ${tfd.fd.id.name} was instantiated with ${tfd.fd.tparams.zip(args).map(k => k._1 +":="+k._2).mkString(",")} with type ${tfd.fd.params.map(_.getType).mkString(",")} => ${tfd.fd.returnType}"
casee=>
s"$e is of type ${e.getType}"+se.map(child=>"\n "+"\n".r.replaceAllIn(child,"\n ")).mkString