In the documentation for ec.gp.koza.CrossoverPipeline it says "Then a random node is chosen in each tree such that the two nodes have the same return type". Does "same return type" in that quote mean that the types "fit" by GType's compatibleWith method?

First off as I understand it GType.compatibleWith is assumed to be commutative (that is t1.compatibleWith(init, t2) is true if and only if t2.compatibleWith(init, t1) is true). Is this correct or is it just one way? That is Int fits {Double, Int} but {Double, Int} doesn't fit Int? This would certainly clear up my confusions.

Say you have a node X of type {string, int} (a set type) and another node Y of type int (an atomic type). X and Y are being passed in as parameters of type {string, int} and int respeticvlly. These return types are "compatible" ("fit") by the definition of compatibleWith for GPAtomicType and GPSetType yet you shouldn't be allowed to swap them sense the parameter type of X's parent can't handle a string, only an int. 

Obliviously i'm missing something or have maid a bad assumption somewhere. Could someone clear this up for me?