#NEWLINE# def most_general_unification( a , b , bindings = None ) : #NEWLINE# #INDENT# '\n    Find the most general unification of the two given expressions\n\n    :param a: ``Expression``\n    :param b: ``Expression``\n    :param bindings: ``BindingDict`` a starting set of bindings with which the\n                     unification must be consistent\n    :return: a list of bindings\n    :raise BindingException: if the Expressions cannot be unified\n    ' #NEWLINE# if ( bindings is None ) : #NEWLINE# #INDENT# bindings = BindingDict ( ) #NEWLINE# #UNINDENT# if ( a == b ) : #NEWLINE# #INDENT# return bindings #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if isinstance ( a , IndividualVariableExpression ) : #NEWLINE# #INDENT# return _mgu_var ( a , b , bindings ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if isinstance ( b , IndividualVariableExpression ) : #NEWLINE# #INDENT# return _mgu_var ( b , a , bindings ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( isinstance ( a , ApplicationExpression ) and isinstance ( b , ApplicationExpression ) ) : #NEWLINE# #INDENT# return ( most_general_unification ( a . function , b . function , bindings ) + most_general_unification ( a . argument , b . argument , bindings ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# raise BindingException ( ( a , b ) )