package Ġthe sis . preprocess . expressions . algebra ic . type Ċ Ċ import Ġthe sis . preprocess . expressions . Expression Ċ import Ġthe sis . preprocess . expressions . TypeName Ċ import Ġthe sis . preprocess . expressions . Type Variable Name Ċ Ċ /** Ċ Ġ* ĠRaw Ġalgebra ic Ġtype Ġwhich Ġwe Ġget Ġfrom Ġparser . ĠWe Ġsupport Ġonly Ġtypes Ġwhose Ġarguments Ġare Ġof Ġfirst Ġkind Ċ Ġ* Ċ Ġ* Ġ@ author ĠDan il ĠK ol ik ov Ċ Ġ*/ Ċ data Ġclass ĠRaw Algebra ic Type ( ĊĠĠĠĠĠĠĠ Ġval Ġname : ĠType Name , ĊĠĠĠĠĠĠĠ Ġval Ġparameters : ĠList < Type Variable Name >, ĊĠĠĠĠĠĠĠ Ġval Ġstructure : ĠStructure Ċ ) Ġ{ ĊĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġ"$ name Ġ${ parameters . join ToString (" Ġ" )} Ġ= Ġ$ structure " ĊĊĠĠĠ Ġdata Ġclass ĠStructure ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoperands : ĠList < Sum Operand > ĊĠĠĠ Ġ) Ġ: ĠExpression Ġ{ ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġoperands . join ToString (" Ġ| Ġ") ĊĊĠĠĠĠĠĠĠ Ġsealed Ġclass ĠSum Operand Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġabstract Ġval Ġname : ĠType Name ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġabstract Ġfun Ġcontains Type ( typeName : ĠType Name ): ĠBoolean ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠLiteral ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġname : ĠType Name ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ: ĠSum Operand () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġname ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcontains Type ( typeName : ĠType Name ) Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠProduct ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġname : ĠType Name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoperands : ĠList < Product Operand > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ: ĠSum Operand () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġ"$ name Ġ${ operands . join ToString (" Ġ") }" ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcontains Type ( typeName : ĠType Name ) Ġ= Ġoperands . any Ġ{ Ġit . contains Type ( typeName ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġsealed Ġclass ĠProduct Operand Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġabstract Ġval Ġname : ĠString ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġabstract Ġfun Ġcontains Type ( typeName : ĠType Name ): ĠBoolean ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠVariable ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġname : ĠString ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ: ĠProduct Operand () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġname ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcontains Type ( typeName : ĠType Name ) Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠApplication ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġname : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarguments : ĠList < Product Operand > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ: ĠProduct Operand () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġ" ($ name Ġ${ arguments . join ToString (" Ġ") }" ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcontains Type ( typeName : ĠType Name ) Ġ= Ġname Ġ== ĠtypeName Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġarguments . any Ġ{ Ġit . contains Type ( typeName Ġ)} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }