package Ġru . spb stu . lamb das Ċ Ċ import Ġru . spb stu . wheel s .* Ċ import Ġru . spb stu . wheel s . Option . Companion . empty Ċ import Ġru . spb stu . wheel s . Option . Companion . just Ċ Ċ sealed Ġclass ĠStmt Ċ data Ġclass ĠBinding ( val Ġsymbol : ĠSymbol , Ġval Ġexpr : ĠExpr ): ĠStmt () Ċ enum Ġclass ĠEval Format Ġ{ ĠOBJECT , ĠINTEGER , ĠBOOLEAN , ĠLIST Ġ} Ċ data Ġclass ĠEval ( val Ġexpr : ĠExpr , Ġval Ġformat : ĠEval Format Ġ= ĠEval Format . OBJECT ): ĠStmt () Ċ object ĠDebug Ġ: ĠStmt () Ċ Ċ class ĠEval State ( val Ġoutput : ĠAppend able , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbindings : ĠMutable Map < Symbol , ĠExpr > Ġ= Ġmutable Map Of ()) Ġ{ ĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġbindings . join ToString ("\ n ") Ċ } Ċ Ċ fun ĠExpr . run ( state : ĠEval State , Ġeval Steps : ĠInt ) Ġ= Ġreplace ( state . bindings ). eval ( eval Steps ) Ċ Ċ fun ĠExpr . re ify Boolean ( step Limit : ĠInt Ġ= Ġ 1 0 0 0 ): ĠOption < Boolean > Ġ= Ġrun Ġ{ ĊĠĠĠ Ġval Ġt Ġ= ĠFree Var ("# T ") ĊĠĠĠ Ġval Ġf Ġ= ĠFree Var ("# F ") ĊĠĠĠ Ġwhen ( this ( t , Ġf ). eval ( step Limit )) Ġ{ ĊĠĠĠĠĠĠĠ Ġt Ġ-> Ġjust ( true ) ĊĠĠĠĠĠĠĠ Ġf Ġ-> Ġjust ( false ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġempty () ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠExpr . re ify Int ( step Limit : ĠInt Ġ= Ġ 1 0 0 0 ): ĠOption < Int > Ġ{ ĊĠĠĠ Ġval Ġf Ġ= ĠFree Var ("# F ") ĊĠĠĠ Ġval Ġz Ġ= ĠFree Var ("# Z ") ĊĠĠĠ Ġvar Ġres Ġ= Ġthis ( f , Ġz ). eval ( step Limit ) ĊĠĠĠ Ġvar Ġtotal Ġ= Ġ 0 ĊĠĠĠ Ġloop @ Ġwhile ( true ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen ( res ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠFree Var Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( res Ġ!= Ġz ) Ġbreak @ loop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġjust ( total ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠApp Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfunc Ġ= Ġres . function ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( func Ġ!= Ġf ) Ġbreak @ loop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġres Ġ= Ġres . argument ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ++ total ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbreak @ loop ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġempty () Ċ } Ċ Ċ fun ĠExpr . re ify List ( step Limit : ĠInt Ġ= Ġ 1 0 0 0 ): ĠOption < List < Expr >> Ġ{ ĊĠĠĠ Ġval Ġf Ġ= ĠFree Var ("# F ") ĊĠĠĠ Ġval Ġgrav est one Ġ= ĠFree Var ("# G ") ĊĠĠĠ Ġvar Ġcurrent Ġ= Ġthis ĊĠĠĠ Ġval Ġresult Ġ= Ġmutable ListOf < Expr >() ĊĠĠĠ Ġloop @ Ġwhile ( true ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen ( val Ġde cons Ġ= Ġcurrent ( f , Ġgrav est one ). eval ( step Limit )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgrav est one Ġ-> Ġreturn Ġjust ( result ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠApp Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( f 1 , Ġa 2 ) Ġ= Ġde cons ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( a 2 Ġ!= Ġgrav est one Ġ|| Ġf 1 Ġ! is ĠApp ) Ġbreak @ loop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( f 2 , Ġa 1 ) Ġ= Ġf 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( f 2 Ġ! is ĠApp ) Ġbreak @ loop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( f 3 , Ġa 0 ) Ġ= Ġf 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( f 3 Ġ!= Ġf ) Ġbreak @ loop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ+= Ġa 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Ġ= Ġa 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbreak @ loop ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġempty () Ċ } Ċ Ċ fun ĠExpr . re ify As Anything ( step Limit : ĠInt ): ĠAny Ġ= ĊĠĠĠ Ġre ify Int ( step Limit ) ĊĠĠĠĠĠĠĠ Ġ. orElse Ġ{ Ġre ify Boolean ( step Limit ) Ġ} ĊĠĠĠĠĠĠĠ Ġ. orElse Ġ{ Ġre ify List ( step Limit ). map Ġ{ Ġlist Ġ-> Ġlist . map Ġ{ Ġit . re ify As Anything ( step Limit ) Ġ} Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġ. getOrElse Ġ{ Ġthis Ġ} Ċ Ċ fun ĠStmt . eval ( state : ĠEval State , Ġeval Steps : ĠInt ) Ġ{ ĊĠĠĠ Ġwhen Ġ( this ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠBinding Ġ-> Ġstate . bindings . put ( symbol , Ġexpr . run ( state , Ġeval Steps )) ĊĠĠĠĠĠĠĠ Ġis ĠEval Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġe Ġ= Ġexpr . run ( state , Ġeval Steps ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen ( format ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEval Format . OBJECT Ġ-> Ġe Ġas ĠAny ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEval Format . INTEGER Ġ-> Ġe . re ify Int ( eval Steps ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. getOrElse Ġ{ Ġthrow ĠException (" Expression Ġ$ e Ġis Ġnot Ġan Ġinteger ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEval Format . BOOLEAN Ġ-> Ġe . re ify Boolean ( eval Steps ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. getOrElse Ġ{ Ġthrow ĠException (" Expression Ġ$ e Ġis Ġnot Ġa Ġboolean ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEval Format . LIST Ġ-> Ġe . re ify List ( eval Steps ). map Ġ{ Ġlist Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist . map Ġ{ Ġit . re ify As Anything ( eval Steps ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. getOrElse Ġ{ Ġthrow ĠException (" Expression Ġ$ e Ġis Ġnot Ġa Ġlist ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. let Ġ{ Ġstate . output . append ln ("$ it ") Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġis ĠDebug Ġ-> Ġstate . bindings . join To ( state . output , Ġ"\ n ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠEval State . add Binding ( binding : ĠBinding , Ġeval Steps : ĠInt ) Ġ= Ġbinding . eval ( this , Ġeval Steps ) Ċ Ċ fun ĠIterable < Stmt >. eval ( state : ĠEval State , Ġeval Steps : ĠInt ) Ġ= ĠforEach Ġ{ Ġit . eval ( state , Ġeval Steps ) Ġ} Ċ