package Ġit . uni bo . sk pf . re . classification . t rep an Ċ Ċ import Ġit . uni bo . sk pf . re . Extractor Ċ import Ġit . uni bo . sk pf . re . schema . Dis cret ization Ċ import Ġit . uni bo . sk pf . re . utils . create Head Ċ import Ġit . uni bo . sk pf . re . utils . create Term Ċ import Ġit . uni bo . sk pf . re . utils . create Variable List Ċ import Ġit . uni bo . tup ro log . core . Clause Ċ import Ġit . uni bo . tup ro log . core . Var Ċ import Ġit . uni bo . tup ro log . theory . Mutable Theory Ċ import Ġit . uni bo . tup ro log . theory . Theory Ċ import Ġsm ile . classification . Classifier Ċ import Ġsm ile . data . DataFrame Ċ import Ġsm ile . data . Tuple Ċ import Ġsm ile . data . categories Ċ import Ġsm ile . data . inputs Ċ import Ġsm ile . data . name Ċ import Ġjava . util . Sorted Set Ċ import Ġkotlin . math . sign Ċ import Ġkotlin . streams . toList Ċ Ċ internal Ġclass ĠT rep an ( ĊĠĠĠ Ġoverride Ġval Ġpredictor : ĠClass ifier < Double Array >, ĊĠĠĠ Ġoverride Ġval Ġdis cret ization : ĠDis cret ization , ĊĠĠĠ Ġval Ġmin Examples : ĠInt Ġ= Ġ 0 , ĊĠĠĠ Ġval Ġmax Depth : ĠInt Ġ= Ġ 0 , ĊĠĠĠ Ġval Ġsplit Logic : ĠSplit Logic Ġ= ĠSplit Logic . DEFAULT Ċ ) Ġ: ĠExtract or < Double Array , ĠClass ifier < Double Array >> Ġ{ ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġroot : ĠNode ĊĊĠĠĠ Ġprivate Ġfun Ġinit ( dataset : ĠDataFrame ): ĠSorted Set < Node > Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . root Ġ= ĠNode ( dataset , Ġdataset . nrows ()) ĊĠĠĠĠĠĠĠ Ġval Ġqueue : ĠSorted Set < Node > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsorted Set Of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkotlin . Comparator Ġ{ Ġn 1 , Ġn 2 Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( n 1 . priority Ġ- Ġn 2 . priority ). sign . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġqueue . add ( this . root ) ĊĠĠĠĠĠĠĠ Ġreturn Ġqueue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġextract ( dataset : ĠDataFrame ): ĠTheory Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġqueue Ġ= Ġthis . init ( dataset ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( queue . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnode Ġ= Ġqueue . first () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . remove ( node ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbest Ġ= Ġwhen Ġ( split Logic ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSplit Logic . DEFAULT Ġ-> Ġthis . best Split ( node , Ġdataset . inputs (). names ()) Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġelse Ġ-> Ġthrow ĠIllegalStateException (" Illegal ĠSplit Logic ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . addAll ( best . toList ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnode . children . addAll ( best . toList ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthis . optimize () ĊĠĠĠĠĠĠĠ Ġif Ġ( max Depth Ġ> Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠNotImplementedError () ĊĠĠĠĠĠĠĠ Ġreturn Ġthis . create Theory ( dataset . name ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinit Spl its ( node : ĠNode ) Ġ= ĠPair ( ĊĠĠĠĠĠĠĠ Ġsorted Set Of < Split >({ Ġs 1 , Ġs 2 Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( s 1 . priority Ġ- Ġs 2 . priority ). sign . toInt () ĊĠĠĠĠĠĠĠ Ġ}), ĊĠĠĠĠĠĠĠ Ġnode . constraints . map Ġ{ Ġit . first Ġ}. toSet () ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Spl its ( node : ĠNode , Ġnames : ĠArray < String >): ĠSorted Set < Split > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( splits , Ġconstraints ) Ġ= Ġinit Spl its ( node ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( column Ġin Ġ( names . filter Not Ġ{ Ġconstraints . contains ( it ) Ġ})) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . create Split ( node , Ġcolumn )?. let Ġ{ Ġsplits . add ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġsplits ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbest Split ( node : ĠNode , Ġnames : ĠArray < String >): ĠPair < Node , ĠNode >? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( node . samples . nrows () Ġ< Ġthis . min Examples ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠNotImplementedError () ĊĠĠĠĠĠĠĠ Ġif Ġ( node . n Classes Ġ== Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġsplits Ġ= Ġcreate Spl its ( node , Ġnames ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( splits . isEmpty ()) Ġnull Ġelse Ġsplits . first (). children ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Samples ( node : ĠNode , Ġcolumn : ĠString , Ġvalue : ĠDouble ): ĠDataFrame ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfiltered Ġ= Ġnode . samples . stream (). filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit [ column ] Ġ== Ġvalue ĊĠĠĠĠĠĠĠ Ġ}. toList () ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( filtered . isNotEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDataFrame . of ( filtered ) ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Split ( node : ĠNode , Ġcolumn : ĠString ): ĠSplit ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtrue Examples Ġ= Ġcreate Samples ( node , Ġcolumn , Ġ 1 . 0 ) ĊĠĠĠĠĠĠĠ Ġval Ġfalse Examples Ġ= Ġcreate Samples ( node , Ġcolumn , Ġ 0 . 0 ) ĊĠĠĠĠĠĠĠ Ġval Ġtrue Constraints Ġ= Ġnode . constraints . plus ( Pair ( column , Ġ 1 . 0 )) ĊĠĠĠĠĠĠĠ Ġval Ġfalse Constraints Ġ= Ġnode . constraints . plus ( Pair ( column , Ġ 0 . 0 )) ĊĠĠĠĠĠĠĠ Ġval Ġtrue Node Ġ= Ġtrue Examples ?. let Ġ{ ĠNode ( it , Ġnode . n Examples , Ġtrue Constraints ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġfalse Node Ġ= Ġfalse Examples ?. let Ġ{ ĠNode ( it , Ġnode . n Examples , Ġfalse Constraints ) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( true Node Ġ== Ġnull Ġ|| Ġfalse Node Ġ== Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSplit ( node , Ġtrue Node Ġto Ġfalse Node ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġtail rec Ġfun Ġpredict ( x : ĠTuple , Ġnode : ĠNode , Ġcategories : ĠSet < Any >): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġnext Child @ for Ġ( child Ġin Ġnode . children ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( constraint , Ġvalue ) Ġin Ġchild . constraints ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( x [ constraint ] Ġ!= Ġvalue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue @ next Child ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis . predict ( x , Ġchild , Ġcategories ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcategories . indexOf ( node . dom inant ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġpredict ( dataset : ĠDataFrame ): ĠArray < *> Ġ= ĊĠĠĠĠĠĠĠ Ġdataset . stream (). map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . predict ( it , Ġthis . root , Ġdataset . categories ()) ĊĠĠĠĠĠĠĠ Ġ}. toArray () ĊĊĠĠĠ Ġprivate Ġfun Ġremove Nodes ( nodes : ĠMutable List < Node >): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnode Ġ= Ġnodes . remove At ( 0 ) ĊĠĠĠĠĠĠĠ Ġval Ġto Remove Ġ= Ġmutable ListOf < Node >() ĊĠĠĠĠĠĠĠ Ġnode . children . filter Ġ{ Ġit . children . isEmpty () Ġ&& Ġnode . dom inant Ġ== Ġit . dom inant Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġto Remove . add ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġnode . children . removeAll ( to Remove ) ĊĠĠĠĠĠĠĠ Ġnode . children . filter Ġ{ Ġit . children . isNotEmpty () Ġ}. forEach Ġ{ Ġnodes . add ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġto Remove . size ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġtail rec Ġfun Ġoptimize () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnodes Ġ= Ġmutable ListOf ( this . root ) ĊĠĠĠĠĠĠĠ Ġvar Ġn Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġwhile Ġ( nodes . isNotEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġn Ġ+= Ġremove Nodes ( nodes ) ĊĠĠĠĠĠĠĠ Ġif Ġ( n Ġ== Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . compact () ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . optimize () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnodes ToRemove ( node : ĠNode , Ġnodes : ĠMutable List < Node >): ĠMutable List < Node > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġto Remove Ġ= Ġmutable ListOf < Node >() ĊĠĠĠĠĠĠĠ Ġfor Ġ( child Ġin Ġnode . children ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(( node . dom inant Ġ== Ġchild . dom inant ) Ġ&& Ġ( child . children . size Ġ== Ġ 1 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Remove . add ( child ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnodes . add ( node ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnodes . add ( child ) ĊĠĠĠĠĠĠĠ Ġreturn Ġto Remove ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcompact () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnodes Ġ= Ġmutable ListOf ( this . root ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( nodes . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnode Ġ= Ġnodes . remove At ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnodes ToRemove ( node , Ġnodes ). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode . children . remove ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode . children . addAll ( it . children ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Body ( variables : ĠMap < String , ĠVar >, Ġnode : ĠNode ) Ġ= Ġsequence Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ(( constraint , Ġvalue ) Ġin Ġnode . constraints ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdis cret ization . first Ġ{ Ġit . ad miss ible Values . containsKey ( constraint ) Ġ}. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġyield ( create Term ( variables [ this . name ], Ġthis . ad miss ible Values [ constraint ] !! , Ġvalue Ġ== Ġ 1 . 0 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}. toList (). to Typed Array () ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Theory ( name : ĠString ): ĠMutable Theory Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtheory Ġ= ĠMutable Theory . empty () ĊĠĠĠĠĠĠĠ Ġfor Ġ( node Ġin Ġthis . root . as Sequence ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvariables Ġ= Ġcreate Variable List ( this . dis cret ization ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtheory . assert Z ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠClause . of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Head ( name , Ġvariables . values , Ġnode . dom inant . toString ()), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* create Body ( variables , Ġnode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtheory ĊĠĠĠ Ġ} Ċ } Ċ