All Downloads are FREE. Search and download functionalities are using the official Maven repository.

expr.Expr.scala Maven / Gradle / Ivy

The newest version!
package galileo.expr

import galileo.complex._
import galileo.constants.ConstantE
import galileo.environment._
import galileo.linalg._
import galileo.logic._
//import galileo.proof.Conversion
import galileo.trigonometry._

trait Expr{
	def derive(v:Variable):Expr = this match {
		case Number(_) => Number( 0 )
		case Variable( name ) => if( name == v.name ) Number( 1 ) else Number( 0 )
		case Sum( e1, e2 ) => Sum( e1 derive v, e2 derive v )
		case Product( e1, e2 ) => Sum( Product( e1, e2 derive v), Product( e1 derive v, e2 ) )
		case Power( e1, e2 ) => Product( e2, Power( e1, Sum( e2, Number( -1 ) ) ) )
		case ExpF1( e ) => Product( ExpF1( e ), e derive v )
		case LogF1( e ) => Product( Power( e, Number( -1 ) ), e derive v )
		case CosF1( e ) => Product( Product( Number( -1 ), SinF1( e  ) ), e derive v )
		case SinF1( e ) => Product( CosF1( e  ), e derive v )

	} // def derive

	def visit(env:Option[Environment]=None):Expr = this
	def eval():Expr = this
	
	// Manipulation
	def simplify:Expr = this
	def expand:Expr = this
	def factor:Expr = this

	//def factors
	def toString():String
	def factorToString():String = toString() // if printed as a factor, e.g as a in 5 * a or as (-1+b) in a * ( -1 + b )
	def denominatorToString():String = factorToString() // if printed as a denominator, e.g. a*b in 1/(a*b)
	def toStringWithSign():String = toString()

	def >(d:Double):Boolean = false
	def <(d:Double):Boolean = false
	val doubleValue:Double = Double.MinValue

	def unary_-():Expr = Product( Number( -1 ), this ).visit()
	def +(that:Expr) = Sum( this, that ).visit()
	def -(that:Expr) = Sum( this, Product( Number( -1 ), that ) )
	//def *(that:Expr) = Product( this, that ).visit()
	//def /(that:Expr) = Fraction( this, that ).visit()
	def info(env:Option[Environment]=None):String // abstract, needs to be defined = "Expr(" + toString() + ")"
	//def conversions(depth:Int):List[Conversion]

	// Possibly extract factor e from an expression
	// (a).extractFactor(a) -> Number( 1 )
	def extractFactor(e:Expr):Option[Expr] = e match {
		case Number( 1 ) => Some( this )
		case s if ( s == this ) => Some( Number( 1 ) )
		case _ => None
	}

	def flatFactors:List[Expr] = List( this )
	def flatTerms:List[Expr] = List( this )
	def possibleFactors:List[Expr] = List( this )
	def leadingVariable:Option[String] = None
	def variables:List[Variable]
	def <(that:Expr):Boolean = (this.leadingVariable,that.leadingVariable) match { 
		case (Some(a),Some(b)) => a < b
		case (_,Some(b)) => false // Plain numbers go after expressions with variables
		case (Some(a),_) => true
		case (_,_) => false // whatever...
	}
}

// Needed for things like comments, etc, which don't express anything
class NilExpr extends Expr with Statement {
	def info(env:Option[Environment]=None) = "NilExpr"
	//def variables:List[Variable] = List()
}

case class ErrorExpr( message:String = "Unknown error" ) extends Expr with Statement {
	override def toString  = message
	def info(env:Option[Environment]=None) = "ErrorExpr(" + message + ")"
}

case class StringExpr( message:String ) extends Expr with Statement {
	override def toString  = message
	def info(env:Option[Environment]=None) = "StringExpr(" + message + ")"
}

case class ExprArray(exprs:Expr*) extends Expr with Statement {
	override def toString() = exprs.mkString( "\n" ) //( e:Expr => e.toString() )
	def info(env:Option[Environment]=None) = "ExprArray(" + exprs + ")"
	override def visit(env:Option[Environment]=None):Expr = {
		ExprArray( exprs.map( expression => expression.visit( env ) ):_* )
	}
	//def variables:List[Variable] = exprs.flatMap( expr => expr.variables )
}


trait Assignment {
	val expr:Expr
	def variables:List[Variable] = expr.variables
}

// a = ...
case class Assignment1(name:String, expr:Expr) extends Expr with Assignment {
	override def toString() = name + "\t=\n" + expr.toString()
	def info(env:Option[Environment]=None) = "Assignment(" + name + "," + expr + ")"
	override def visit(env:Option[Environment]) = {
		val vv = expr.visit( env )
		env match {
			case Some( e ) => { e.set( name, vv ); this }
			case None => ErrorExpr( "Internal error" )
		}
	}
}

// [ A,B] = ...
case class Assignment2(name0:String, name1:String, expr:Expr ) extends Expr with Assignment {
	override def toString() = "[" + name0 + "," + name1 + "]\t=\n" + expr.toString() 
	def info(env:Option[Environment]=None) = "Assignment2(" + name0 + "," + name1 + "," + expr + ")"
	override def visit(env:Option[Environment]) = ErrorExpr( "Todo Assignment2.visit" ) //{ val vv = expr.visit( env ); env.set( name, vv ); vv }
}

// [A,B, C] = ...
case class Assignment3(name0:String, name1:String, name2: String, expr:Expr ) extends Expr with Assignment { 
	override def toString() = "[" + name0 + "," + name1 + "," + name2 + "]\t=\n" + expr.toString() 
	def info(env:Option[Environment]=None) = "Assignment3(" + name0 + "," + name1 + "," + name2 + "," + expr + ")"
	override def visit(env:Option[Environment]) = ErrorExpr( "Todo Assignment3.visit" ) //{ val vv = expr.visit( env ); env.set( name, vv ); vv }
}

// E.g. a=1
case class Variable(name : String = "x") extends Expr {
	override def toString() = name
	def info(env:Option[Environment]=None):String = "Variable(" + name + ",value:" + this.visit(env) + ")"
	override def toStringWithSign() = "+" + name

	
	override def visit(env:Option[Environment]=None):Expr = env match {
		case Some( e ) => e.get( this.name ) match {
			//case Some( c:Constant ) => c // this doesn't work well... What is var is a = 2 * pi was set?
			case Some( v ) => v.visit( env )
//				v.visit( Some( e.getWithout( this.name ) ) ) // avoid infinite loops
//				v.visit( env )
//			}
			case None => this
		}
		case None => this
	}
	override def possibleFactors:List[Expr] = List( this )
	override def leadingVariable:Option[String] = Some( name )
	def variables:List[Variable] = List( this )
}

case class FuncCall(func:Expr, params:List[Expr]) extends Expr {
	def info(env:Option[Environment]=None):String = "FuncCall(" + func + "," + params + ")"
	def variables:List[Variable] = params.flatMap( param => param.variables )
}

case class Eval( e:Expr ) extends Expr {
	override def visit( env:Option[Environment]=None):Expr = e.eval()
	def info(env:Option[Environment]=None):String = "Eval(" + e + ")"
	def variables:List[Variable] = e.variables
}

// a Variable free expression
trait Statement {
	def variables:List[Variable] = {
		throw new IllegalArgumentException( "variables should not be called on an unassigned Tensor" )
		List()
	}
}

// ls, pwd
case class SystemCommand( command:String ) extends Expr with Statement {
	def info(env:Option[Environment]=None) ="SystemCommand(" + command + ")"
	import sys.process._
	override def toString() = {
		import scala.language.postfixOps
		command !! // does not work for cd
	}
}

// who
case class Who() extends Expr with Statement {
	def info(env:Option[Environment]=None) = "Who()"
}

// whos
case class Whos() extends Expr with Statement {
	def info(env:Option[Environment]=None) = "Whos()"
}

// clear
case class Clear() extends Expr with Statement {
	def info(env:Option[Environment]=None) = "Clear()"
}

// exit
case class Exit() extends Expr with Statement {
	def info(env:Option[Environment]=None) = "Exit()"
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy