public PType intersect(PType a, PType b)
	{
		Set<PType> tsa = new HashSet<PType>();
		Set<PType> tsb = new HashSet<PType>();

		// Obtain the fundamental type of BracketTypes, NamedTypes and OptionalTypes.
		boolean resolved = false;

		while (!resolved)
		{
			if (a instanceof ABracketType)
			{
				a = ((ABracketType) a).getType();
				continue;
			}

			if (b instanceof ABracketType)
			{
				b = ((ABracketType) b).getType();
				continue;
			}

			if (a instanceof ANamedInvariantType)
			{
				ANamedInvariantType nt = (ANamedInvariantType) a;

				if (nt.getInvDef() == null)
				{
					a = nt.getType();
					continue;
				}
			}

			if (b instanceof ANamedInvariantType)
			{
				ANamedInvariantType nt = (ANamedInvariantType) b;

				if (nt.getInvDef() == null)
				{
					b = nt.getType();
					continue;
				}
			}

			if (a instanceof AOptionalType && b instanceof AOptionalType)
			{
				a = ((AOptionalType) a).getType();
				b = ((AOptionalType) b).getType();
				continue;
			}

			resolved = true;
		}

		if (a instanceof AUnionType)
		{
			AUnionType uta = (AUnionType) a;
			tsa.addAll(uta.getTypes());
		} else
		{
			tsa.add(a);
		}

		if (b instanceof AUnionType)
		{
			AUnionType utb = (AUnionType) b;
			tsb.addAll(utb.getTypes());
		} else
		{
			tsb.add(b);
		}

		// Keep largest types which are compatible (eg. nat and int choses int)
		Set<PType> result = new HashSet<PType>();

		for (PType atype : tsa)
		{
			for (PType btype : tsb)
			{
				if (isSubType(atype, btype))
				{
					result.add(btype);
				} else if (isSubType(btype, atype))
				{
					result.add(atype);
				}
			}
		}

		if (result.isEmpty())
		{
			return null;
		} else
		{
			List<PType> list = new Vector<PType>();
			list.addAll(result);
			return AstFactory.newAUnionType(a.getLocation(), list);
		}
	}
public PType intersect ( PType a , PType b ) { Set < PType > tsa = new HashSet < PType > ( ) ; Set < PType > tsb = new HashSet < PType > ( ) ; boolean resolved = false ; while ( ! resolved ) { if ( a instanceof ABracketType ) { a = ( ( ABracketType ) a ) . getType ( ) ; continue ; } if ( b instanceof ABracketType ) { b = ( ( ABracketType ) b ) . getType ( ) ; continue ; } if ( a instanceof ANamedInvariantType ) { ANamedInvariantType nt = ( ANamedInvariantType ) a ; if ( nt . getInvDef ( ) == null ) { a = nt . getType ( ) ; continue ; } } if ( b instanceof ANamedInvariantType ) { ANamedInvariantType nt = ( ANamedInvariantType ) b ; if ( nt . getInvDef ( ) == null ) { b = nt . getType ( ) ; continue ; } } if ( a instanceof AOptionalType && b instanceof AOptionalType ) { a = ( ( AOptionalType ) a ) . getType ( ) ; b = ( ( AOptionalType ) b ) . getType ( ) ; continue ; } resolved = true ; } if ( a instanceof AUnionType ) { AUnionType uta = ( AUnionType ) a ; tsa . addAll ( uta . getTypes ( ) ) ; } else { tsa . add ( a ) ; } if ( b instanceof AUnionType ) { AUnionType utb = ( AUnionType ) b ; tsb . addAll ( utb . getTypes ( ) ) ; } else { tsb . add ( b ) ; } Set < PType > result = new HashSet < PType > ( ) ; for ( PType atype : tsa ) { for ( PType btype : tsb ) { if ( isSubType ( atype , btype ) ) { result . add ( btype ) ; } else if ( isSubType ( btype , atype ) ) { result . add ( atype ) ; } } } if ( result . isEmpty ( ) ) { return null ; } else { List < PType > list = new Vector < PType > ( ) ; list . addAll ( result ) ; return AstFactory . newAUnionType ( a . getLocation ( ) , list ) ; } }
Calculate the intersection of two types.

@param a
@param b
@return