What's assignable to what? related



What's assignable to what?

In this challenge you will be given two types, A and B and determine if A is assignable to B, B is assignable to A, or neither.

The Type System

(I will use t to represent any type)

Basic Types

Basic types are represented by a single capital letter, such as X. They are basically classes.


X is assignable to Y if Y is either the same as, or a parent class of X.


Intersection Types

Intersection types are represented by intersect&lt;X, Y&gt;, and can have any number of types between the &lt;'s (e.g. intersect&lt;X, Y, Z, D, E&gt;). 


t is assignable to intersect&lt;X1, X2... Xn&gt; if t is assignable to all X. 
intersect&lt;X1, X2... Xn&gt; is assignable to t if any X is assignable to t.


Union Types

Union types are represented by union&lt;X, Y&gt; and can have any number of types between the &lt;'s (e.g. union&lt;X, Y, Z, D, E&gt;).


t is assignable to union&lt;X1, X2... Xn&gt; if t is assignable to any X.
union&lt;X1, X2... Xn&gt; is assignable to t if all X are assignable to t.




Input

You will receive as input:


The class hierarchy. You may choose the method of input for the class hierarchy. You can input a representation of a tree, or each type with a list of its parents, or anything else that accurately represents the class hierarchy.
Two types (input is flexible, as long as the notation is consistent you may receive these types however you like).




Output

You will output one of three consistent and distinct values, call them X, Y, and Z. Given two types A and B, output X if A is assignable to B, output Y if B is assignable to A and output Z otherwise (If A is assignable to B and B is assignable to A, you may output X, Y, both, or a fourth value).



Test Cases

Format:

# of types
[type, parents...]
[type, parents...]
Type a
Type b




2
[A,B]
[B]
A
B
--
A is assignable to B


3
[A,B,C]
[B,C]
[C]
intersect&lt;A,C&gt;
A
--
A is assignable to intersect&lt;A,C&gt;


3
[A,B,C]
[B,C]
[C]
union&lt;A,C&gt;
A
--
A is assignable to union&lt;A,C&gt;


3
[A,B,C]
[B,C]
[C]
intersect&lt;B,C&gt;
A
--
A is assignable to intersect&lt;B,C&gt;


3
[A,B,C]
[X,Y,Z]
[T,U,V]
intersect&lt;union&lt;A,T,X&gt;,intersect&lt;A,B&gt;,Y&gt;
intersect&lt;T,C,X&gt;
--
intersect&lt;T,C,X&gt; and intersect&lt;union&lt;A,T,X&gt;,intersect&lt;A,B&gt;,Y&gt; are not assignable to each other    

1
[A]
A
A
--
A is assignable to A


3
[A,B,C]
[X,Y,Z]
[T,U,V]
intersect&lt;A,intersect&lt;A,B&gt;,Y&gt;
intersect&lt;T,C,X&gt;
--
intersect&lt;T,C,X&gt; and intersect&lt;A,intersect&lt;A,B&gt;,Y&gt; are not assignable to each other


2
[A]
[B]
A
B
--
B and A are not assignable to each other

3
[A,B,C]
[X,Y,Z]
[T,U,V]
intersect&lt;union&lt;A,X&gt;,intersect&lt;A,B&gt;,Y&gt;
intersect&lt;T,C,X&gt;
--
intersect&lt;T,C,X&gt; and intersect&lt;union&lt;A,X&gt;,intersect&lt;A,B&gt;,Y&gt; are not assignable to each other


Here is a link to a working ungolfed Java solution you can use for testing (it takes input in the same way as the test cases)



This is code-golf, so least bytes in each language wins for that language!
Python 3, 177 bytes

c is a dictionary of the parents of each type, a and b are the two expression to check. Types are represented by strings, while intersects and unions are represented by lists with of expressions, with the first element set to 0for intersect and 1 for union

Returns 0 if they are not assignable to each other, 1 if a is assignable to b, 2 if b is assignable to a and 3 if both are assignable to each other



lambda c,a,b:y(a,b,c)+2*y(b,a,c)
y=lambda a,b,c:(b in c[a]or a==b if b[0]in c else[all,any][b[0]](y(a,x,c)for x in b[1:]))if a[0]in c else[any,all][a[0]](y(x,b,c)for x in a[1:])


Try it online!