#NEWLINE# def unify( x , y , s = None , **fns ) : #NEWLINE# #INDENT# ' Unify two expressions\n\n    inputs:\n        x, y - expression trees containing leaves, Compounds and Variables\n        s    - a mapping of variables to subtrees\n    outputs:\n        lazy sequence of mappings {Variable: subtree}\n\n    Examples\n    ========\n\n    >>> from sympy.unify.core import unify, Compound, Variable\n    >>> expr    = Compound("Add", ("x", "y"))\n    >>> pattern = Compound("Add", ("x", Variable("a")))\n    >>> next(unify(expr, pattern, {}))\n    {Variable(a): \'y\'}\n    ' #NEWLINE# s = ( s or { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } ) #NEWLINE# if ( x == y ) : #NEWLINE# #INDENT# ( yield s ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if isinstance ( x , ( Variable , CondVariable ) ) : #NEWLINE# #INDENT# for match in unify_var ( x , y , s , ** fns ) : #NEWLINE# #INDENT# ( yield match ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if isinstance ( y , ( Variable , CondVariable ) ) : #NEWLINE# #INDENT# for match in unify_var ( y , x , s , ** fns ) : #NEWLINE# #INDENT# ( yield match ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( isinstance ( x , Compound ) and isinstance ( y , Compound ) ) : #NEWLINE# #INDENT# is_commutative = fns . get ( 'is_commutative' , ( lambda x : False ) ) #NEWLINE# is_associative = fns . get ( 'is_associative' , ( lambda x : False ) ) #NEWLINE# for sop in unify ( x . op , y . op , s , ** fns ) : #NEWLINE# #INDENT# if ( is_associative ( x ) and is_associative ( y ) ) : #NEWLINE# #INDENT# ( a , b ) = ( ( x , y ) if ( len ( x . args ) < len ( y . args ) ) else ( y , x ) ) #NEWLINE# if ( is_commutative ( x ) and is_commutative ( y ) ) : #NEWLINE# #INDENT# combs = allcombinations ( a . args , b . args , 'commutative' ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# combs = allcombinations ( a . args , b . args , 'associative' ) #NEWLINE# #UNINDENT# for ( aaargs , bbargs ) in combs : #NEWLINE# #INDENT# aa = [ unpack ( Compound ( a . op , arg ) ) for arg in aaargs ] #NEWLINE# bb = [ unpack ( Compound ( b . op , arg ) ) for arg in bbargs ] #NEWLINE# for match in unify ( aa , bb , sop , ** fns ) : #NEWLINE# #INDENT# ( yield match ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( len ( x . args ) == len ( y . args ) ) : #NEWLINE# #INDENT# for match in unify ( x . args , y . args , sop , ** fns ) : #NEWLINE# #INDENT# ( yield match ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( is_args ( x ) and is_args ( y ) and ( len ( x ) == len ( y ) ) ) : #NEWLINE# #INDENT# if ( len ( x ) == 0 ) : #NEWLINE# #INDENT# ( yield s ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# for shead in unify ( x [ 0 ] , y [ 0 ] , s , ** fns ) : #NEWLINE# #INDENT# for match in unify ( x [ 1 : ] , y [ 1 : ] , shead , ** fns ) : #NEWLINE# #INDENT# ( yield match )