package Ġj at yc . core Ċ Ċ object ĠSub typing Ġ{ ĊĊĠ Ġfun Ġsubtype ( a : ĠJ TC Type , Ġb : ĠJ TC Type ): ĠBoolean Ġ{ ĊĠĠĠ Ġval Ġresult Ġ= Ġwhen Ġ( a ) Ġ{ ĊĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb Ġis ĠJ TC Unknown Type ĊĠĠĠĠĠ Ġis ĠJ TC Shared Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġtrue ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Shared Type Ġ-> Ġa . java Type . is Subtype ( b . java Type ) ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġb . types . any Ġ{ Ġsubtype ( a , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> Ġb . types . all Ġ{ Ġsubtype ( a , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TC Unknown State Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġtrue ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown State Type Ġ-> Ġa . java Type . is Subtype ( b . java Type ) ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġb . types . any Ġ{ Ġsubtype ( a , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> Ġb . types . all Ġ{ Ġsubtype ( a , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ Ġ// Ġis ĠJ TC No Protocol Type Ġ-> Ġjava Type . is Subtype ( other . java Type ) Ġ&& Ġ! other . exact ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TC State Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġtrue ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown State Type Ġ-> Ġa . java Type . is Subtype ( b . java Type ) Ġ&& Ġ( ĊĠĠĠĠĠĠĠĠĠ Ġa . graph Ġ== Ġb . graph Ġ|| Ġa . graph . get InitialState () Ġ== Ġa . state Ġ|| Ġa . state . is End () ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġis ĠJ TC State Type Ġ-> Ġa . java Type . is Subtype ( b . java Type ) Ġ&& Ġ( ĊĠĠĠĠĠĠĠĠĠ Ġa . state Ġ== Ġb . state Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( a . graph . get InitialState () Ġ== Ġa . state Ġ&& Ġb . graph . get InitialState () Ġ== Ġb . state ) Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( a . state . is End () Ġ&& Ġb . state . is End ()) ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġb . types . any Ġ{ Ġsubtype ( a , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> Ġb . types . all Ġ{ Ġsubtype ( a , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ Ġ// Ġis ĠJ TC No Protocol Type Ġ-> Ġjava Type . is Subtype ( other . java Type ) Ġ&& Ġ! other . exact ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TCP ri mitive Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġtrue ĊĠĠĠĠĠĠĠ Ġis ĠJ TCP ri mitive Type Ġ-> Ġa . java Type . is Subtype ( b . java Type ) ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġb . types . any Ġ{ Ġsubtype ( a , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> Ġb . types . all Ġ{ Ġsubtype ( a , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TC Null Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġtrue ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Null Type Ġ-> Ġtrue ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġb . types . any Ġ{ Ġsubtype ( a , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> Ġb . types . all Ġ{ Ġsubtype ( a , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ T CB ottom Type Ġ-> Ġtrue ĊĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġtrue ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġa . types . all Ġ{ Ġit A Ġ-> Ġb . types . any Ġ{ Ġit B Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> Ġb . types . all Ġ{ Ġit B Ġ-> Ġa . types . all Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġa . types . all Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġb ) Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ/* is ĠJ TC Intersection Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġtrue ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġa . types . any Ġ{ Ġit A Ġ-> Ġb . types . any Ġ{ Ġit B Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> Ġb . types . all Ġ{ Ġit B Ġ-> Ġa . types . any Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġa . types . any Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġb ) Ġ} ĊĠĠĠĠĠ Ġ}*/ ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġresult ĊĠ Ġ} ĊĊĠ Ġfun Ġup cast ( a : ĠJ TC Type , Ġb : ĠJ TC Type ): ĠJ TC Type Ġ{ ĊĠĠĠ Ġval Ġbot Ġ= ĠJ T CB ottom Type . SINGLE TON ĊĠĠĠ Ġval Ġresult Ġ= Ġwhen Ġ( a ) Ġ{ ĊĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġif Ġ( b Ġis ĠJ TC Unknown Type ) Ġb Ġelse Ġbot ĊĠĠĠĠĠ Ġis ĠJ TC Shared Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Shared Type Ġ-> Ġif Ġ( a . java Type . is Subtype ( b . java Type )) Ġb Ġelse Ġbot ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġup cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġup cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TC Unknown State Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown State Type Ġ-> Ġif Ġ( a . java Type . is Subtype ( b . java Type )) Ġb Ġelse Ġbot ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġup cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġup cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TC State Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown State Type Ġ-> Ġif Ġ( a . java Type . is Subtype ( b . java Type )) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa . graph Ġ== Ġb . graph Ġ-> ĠJ TC State Type ( b . java Type , Ġb . graph , Ġa . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa . graph . get InitialState () Ġ== Ġa . state Ġ-> ĠJ TC State Type ( b . java Type , Ġb . graph , Ġb . graph . get InitialState ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa . state . is End () Ġ-> ĠJ TC State Type ( b . java Type , Ġb . graph , Ġb . graph . getEnd State ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġbot ĊĠĠĠĠĠĠĠ Ġis ĠJ TC State Type Ġ-> Ġif Ġ( a . java Type . is Subtype ( b . java Type )) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa . graph Ġ== Ġb . graph Ġ&& Ġa . state Ġ== Ġb . state Ġ-> Ġb ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa . graph . get InitialState () Ġ== Ġa . state Ġ&& Ġb . graph . get InitialState () Ġ== Ġb . state Ġ-> ĠJ TC State Type ( b . java Type , Ġb . graph , Ġb . graph . get InitialState ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa . state . is End () Ġ&& Ġb . state . is End () Ġ-> ĠJ TC State Type ( b . java Type , Ġb . graph , Ġb . graph . getEnd State ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġbot ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġup cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġup cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TCP ri mitive Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TCP ri mitive Type Ġ-> Ġif Ġ( a . java Type . is Subtype ( b . java Type )) Ġb Ġelse Ġbot ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġup cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġ// s ĠJ TC Intersection Type Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġup cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TC Null Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Null Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġup cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġup cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ T CB ottom Type Ġ-> Ġbot ĊĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġa . types . all Ġ{ Ġit A Ġ-> Ġb . types . any Ġ{ Ġit B Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġa . types . map Ġ{ Ġit A Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġit B Ġ-> Ġup cast ( it A , Ġit B ) Ġ}) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . contains ( bot )) Ġbot Ġelse ĠJ TC Type . create Union ( new Types ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ/* is ĠJ TC Intersection Type Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġb . types . all Ġ{ Ġit B Ġ-> Ġa . types . all Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġb . types . map Ġ{ Ġit B Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġit A Ġ-> Ġup cast ( it A , Ġit B ) Ġ}) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . contains ( bot )) Ġbot Ġelse ĠJ TC Type . create Union ( new Types ) ĊĠĠĠĠĠĠĠ Ġ}*/ ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġa . types . all Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġb ) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġa . types . map Ġ{ Ġit A Ġ-> Ġup cast ( it A , Ġb ) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . contains ( bot )) Ġbot Ġelse ĠJ TC Type . create Union ( new Types ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ/* is ĠJ TC Intersection Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġa . types . any Ġ{ Ġit A Ġ-> Ġb . types . any Ġ{ Ġit B Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġa . types . map Ġ{ Ġit A Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġit B Ġ-> Ġup cast ( it A , Ġit B ) Ġ}) Ġ}. filter Ġ{ Ġit Ġ!= Ġbot Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . isEmpty ()) Ġbot Ġelse ĠJ TC Type . create Intersection ( new Types ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Intersection Type Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġb . types . all Ġ{ Ġit B Ġ-> Ġa . types . any Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġb . types . map Ġ{ Ġit B Ġ-> ĠJ TC Type . create Union ( a . types . map Ġ{ Ġit A Ġ-> Ġup cast ( it A , Ġit B ) Ġ}) Ġ}. filter Ġ{ Ġit Ġ!= Ġbot Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . contains ( bot )) Ġbot Ġelse ĠJ TC Type . create Intersection ( new Types ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġa . types . any Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġb ) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġa . types . map Ġ{ Ġit A Ġ-> Ġup cast ( it A , Ġb ) Ġ}. filter Ġ{ Ġit Ġ!= Ġbot Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . isEmpty ()) Ġbot Ġelse ĠJ TC Type . create Intersection ( new Types ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ}*/ ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġresult ĊĠ Ġ} ĊĊĠ Ġfun Ġforce Cast ( a : ĠJ TC Type , Ġb : ĠJ TC Type ): ĠJ TC Type Ġ{ ĊĠĠĠ Ġval Ġbot Ġ= ĠJ T CB ottom Type . SINGLE TON ĊĠĠĠ Ġval Ġresult Ġ= Ġwhen Ġ( a ) Ġ{ ĊĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠ Ġis ĠJ TC Shared Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Shared Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġforce Cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġforce Cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TC Unknown State Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown State Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġforce Cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġforce Cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TC State Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown State Type Ġ-> Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġa . graph Ġ== Ġb . graph Ġ-> ĠJ TC State Type ( b . java Type , Ġb . graph , Ġa . state ) ĊĠĠĠĠĠĠĠĠĠ Ġa . graph . get InitialState () Ġ== Ġa . state Ġ-> ĠJ TC State Type ( b . java Type , Ġb . graph , Ġb . graph . get InitialState ()) ĊĠĠĠĠĠĠĠĠĠ Ġa . state . is End () Ġ-> ĠJ TC State Type ( b . java Type , Ġb . graph , Ġb . graph . getEnd State ()) ĊĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġis ĠJ TC State Type Ġ-> Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġa . graph Ġ== Ġb . graph Ġ&& Ġa . state Ġ== Ġb . state Ġ-> Ġb ĊĠĠĠĠĠĠĠĠĠ Ġa . graph . get InitialState () Ġ== Ġa . state Ġ&& Ġb . graph . get InitialState () Ġ== Ġb . state Ġ-> ĠJ TC State Type ( b . java Type , Ġb . graph , Ġb . graph . get InitialState ()) ĊĠĠĠĠĠĠĠĠĠ Ġa . state . is End () Ġ&& Ġb . state . is End () Ġ-> ĠJ TC State Type ( b . java Type , Ġb . graph , Ġb . graph . getEnd State ()) ĊĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġforce Cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġforce Cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TCP ri mitive Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TCP ri mitive Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġforce Cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġforce Cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ TC Null Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Null Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġforce Cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġ// is ĠJ TC Intersection Type Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġforce Cast ( a , Ġit ) Ġ}) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbot ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis ĠJ T CB ottom Type Ġ-> Ġbot ĊĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġa . types . all Ġ{ Ġit A Ġ-> Ġb . types . any Ġ{ Ġit B Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġa . types . map Ġ{ Ġit A Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġit B Ġ-> Ġforce Cast ( it A , Ġit B ) Ġ}) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . contains ( bot )) Ġbot Ġelse ĠJ TC Type . create Union ( new Types ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ/* is ĠJ TC Intersection Type Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġb . types . all Ġ{ Ġit B Ġ-> Ġa . types . all Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġb . types . map Ġ{ Ġit B Ġ-> ĠJ TC Type . create Intersection ( b . types . map Ġ{ Ġit A Ġ-> Ġforce Cast ( it A , Ġit B ) Ġ}) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . contains ( bot )) Ġbot Ġelse ĠJ TC Type . create Union ( new Types ) ĊĠĠĠĠĠĠĠ Ġ}*/ ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġa . types . all Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġb ) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġa . types . map Ġ{ Ġit A Ġ-> Ġforce Cast ( it A , Ġb ) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . contains ( bot )) Ġbot Ġelse ĠJ TC Type . create Union ( new Types ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ/* is ĠJ TC Intersection Type Ġ-> Ġwhen Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Unknown Type Ġ-> Ġb ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Union Type Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġa . types . any Ġ{ Ġit A Ġ-> Ġb . types . any Ġ{ Ġit B Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġa . types . map Ġ{ Ġit A Ġ-> ĠJ TC Type . create Union ( b . types . map Ġ{ Ġit B Ġ-> Ġforce Cast ( it A , Ġit B ) Ġ}) Ġ}. filter Ġ{ Ġit Ġ!= Ġbot Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . isEmpty ()) Ġbot Ġelse ĠJ TC Type . create Intersection ( new Types ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġis ĠJ TC Intersection Type Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġb . types . all Ġ{ Ġit B Ġ-> Ġa . types . any Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġit B ) Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġb . types . map Ġ{ Ġit B Ġ-> ĠJ TC Type . create Union ( a . types . map Ġ{ Ġit A Ġ-> Ġforce Cast ( it A , Ġit B ) Ġ}) Ġ}. filter Ġ{ Ġit Ġ!= Ġbot Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . contains ( bot )) Ġbot Ġelse ĠJ TC Type . create Intersection ( new Types ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġa . types . any Ġ{ Ġit A Ġ-> Ġsubtype ( it A , Ġb ) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Types Ġ= Ġa . types . map Ġ{ Ġit A Ġ-> Ġforce Cast ( it A , Ġb ) Ġ}. filter Ġ{ Ġit Ġ!= Ġbot Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Types . isEmpty ()) Ġbot Ġelse ĠJ TC Type . create Intersection ( new Types ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ}*/ ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġresult ĊĠ Ġ} Ċ Ċ } Ċ