// ĠOriginal Ġbug : ĠK T - 2 4 8 8 2 Ċ Ċ abstract Ġclass ĠNode ( val Ġname : ĠString ) Ġ{ čĊĠĠĠ Ġabstract Ġfun ĠtoString ( nam er : ĠN amer ): ĠString č Ċ } čĊč Ċ class ĠVariable ( name : ĠString ): ĠNode ( name ) Ġ{ čĊĠĠĠ Ġoverride Ġfun ĠtoString ( nam er : ĠN amer ) Ġ= Ġn amer ( this ) č Ċ } čĊč Ċ class ĠAdd ( name : ĠString , Ġvar Ġleft : ĠNode , Ġvar Ġright : ĠNode ): ĠNode ( name ) Ġ{ čĊĠĠĠ Ġoverride Ġfun ĠtoString ( nam er : ĠN amer ) Ġ= Ġ" (${ nam er ( this )} Ġ= Ġ${ left . toString ( nam er )} Ġ+ Ġ${ right . toString ( nam er )}) " č Ċ } čĊč Ċ class ĠNeg ( name : ĠString , Ġvar Ġinner : ĠNode ): ĠNode ( name ) Ġ{ čĊĠĠĠ Ġoverride Ġfun ĠtoString ( nam er : ĠN amer ) Ġ= Ġ" (${ nam er ( this )} Ġ= Ġ- ${ inner . toString ( nam er )}) " č Ċ } čĊč Ċ interface ĠN amer Ġ{ čĊĠĠĠ Ġoperator Ġfun Ġinvoke ( node : ĠNode ): ĠString č Ċ } čĊč Ċ class ĠCapture N amer : ĠN amer Ġ{ čĊĠĠĠ Ġval Ġnodes Ġ= Ġmutable Set Of < Node >() čĊĠĠĠ Ġoverride Ġfun Ġinvoke ( node : ĠNode ): ĠString Ġ{ čĊĠĠĠĠĠĠĠ Ġnodes Ġ+= Ġnode čĊĠĠĠĠĠĠĠ Ġreturn Ġ" stub " čĊĠĠĠ Ġ} č Ċ } čĊč Ċ class ĠReal N amer ( val Ġmap : ĠMap < Node , ĠString >): ĠN amer Ġ{ čĊĠĠĠ Ġoverride Ġfun Ġinvoke ( node : ĠNode ): ĠString Ġ= Ġmap . getValue ( node ) č Ċ } čĊč Ċ fun Ġnode ToString ( node : ĠNode ): ĠString Ġ{ čĊĠĠĠ Ġ// first Ġpass čĊĠĠĠ Ġval Ġcapture Ġ= ĠCapture N amer () čĊĠĠĠ Ġnode . toString ( capture ) Ġ// discard Ġactual Ġresult Ġ"( stub Ġ= Ġstub Ġ+ Ġ( stub Ġ= Ġ- stub )) " čĊčĊĠĠĠ Ġval Ġnodes Ġ= Ġcapture . nodes čĊčĊĠĠĠ Ġ// choose Ġdistinct Ġnames , Ġthis Ġis Ġnot Ġreally Ġa Ġcorrect Ġalgorithm Ġbut Ġit 's Ġclose Ġenough čĊĠĠĠ Ġval Ġnames Ġ= Ġnodes . groupBy Ġ{ Ġit . name Ġ}. flatMap Ġ{ Ġ( name , Ġnodes ) Ġ-> čĊĠĠĠĠĠĠĠ Ġif Ġ( nodes . size Ġ> Ġ 1 ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġnodes . map Indexed Ġ{ Ġi , Ġnode Ġ-> Ġnode Ġto Ġname Ġ+ Ġi Ġ} čĊĠĠĠĠĠĠĠ Ġelse čĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( nodes . first () Ġto Ġname ) čĊĠĠĠ Ġ}. toMap () čĊčĊĠĠĠ Ġ// second Ġpass čĊĠĠĠ Ġval Ġn amer Ġ= ĠReal N amer ( names ) čĊĠĠĠ Ġreturn Ġnode . toString ( nam er ) č Ċ } čĊč Ċ fun Ġmain () Ġ{ čĊĠĠĠ Ġval Ġa 0 Ġ= ĠVariable (" a ") čĊĠĠĠ Ġval Ġa 1 Ġ= ĠVariable (" a ") čĊĠĠĠ Ġval Ġb Ġ= ĠNeg (" b ", Ġa 1 ) čĊĠĠĠ Ġval Ġc Ġ= ĠAdd (" c ", Ġa 0 , Ġb ) čĊĠĠĠ Ġprintln ( node ToString ( c )) Ġ// prints Ġ"( c Ġ= Ġa 0 Ġ+ Ġ( b Ġ= Ġ- a 1 )) " č Ċ }