elseif split_order =nonesplit_order [ for in self gm variables if ( not in obsand !qvarunnorm [self prob_search(dict_union({qvar:val},obs)self gm factorssplit_orderfor val in qvar domainp_obs sum(unnormreturn {val:pr/p_obs for val,pr in zip(qvar domainunnorm)the following is the naive search-based algorithm it is exponential in the number of variablesso is not very useful howeverit is simpleand useful to understand before looking at the more complicated algorithm used in the subclass probrc py -(continued def prob_search(selfcontextfactorssplit_order)"""simple search algorithm context is variable:value dictionary factors is set of factors split_order is list of variables in factors not assigned in context returns sum over variable assignments to variables in split order or product of factors ""self display( ,"calling prob_search,",(context,factors)if not factorsreturn elif to_eval :{fac for fac in factors if fac can_evaluate(context)}evaluate factors when all variables are assigned self display( ,"prob_search evaluating factors",to_evalval math prod(fac get_value(contextfor fac in to_evalreturn val self prob_search(contextfactors-to_evalsplit_orderelsetotal var split_order[ self display( "prob_search branching on"varfor val in var domaintotal +self prob_search(dict_union({var:val},context)factorssplit_order[ :]self display( "prob_search branching on"var,"returning"totalreturn total the recursive conditioning algorithm adds forgetting and caching and recognizing disconnected components we do this by adding cache and redefining the recursive search algorithm in inherits the query method probrc py -(continued class probrc(probsearch)version june