import math


def conditional(model, player, state_set, x):
    """
    >>> from simple_model import *
    >>> m = SimpleModel(0.1, 0.95)
    >>> conditional(m, 0, set([(1, 1, 1)]), (1,1,0))
    0.95
    >>> conditional(m, 0, set([(1, 1, 1)]), (1,0,0))
    0.0
    >>> conditional(m, 0, get_satisfying_states(m), (1,0,0))
    0.10000000000000002
    >>> from thomas_model import *
    >>> m = ThomasModel(0.1, 0.25)
    >>> conditional(m, 0, get_satisfying_states(m), (1,1,1,0,0))
    1.0
    >>> conditional(m, 0, set([(1, 1, 1, 0, 0), (1, 1, 1, 0, 1), (1, 1, 1, 1, 1), (1, 1, 1, 1, 0)]), (1,1,1,0,0))
    0.25000000000000017
    >>> conditional(m, 0, set([(1, 1, 1, 0, 0), (1, 1, 1, 0, 1), (1, 1, 1, 1, 1), (1, 1, 1, 1, 0)]), (1,1,1,1,1))
    1.0
    >>> from extended_thomas_model import *
    >>> m = ExtendedThomasModel(0.1, 0.25, 2)
    >>> conditional(m, 0, get_satisfying_states(m), (1,1,0,0,0,0,0,0,0,0,0))
    1.0
    """
    
    possible_states = set(model.graphs[player][x])
    state_set = state_set.intersection(possible_states)
    norm = sum([model.probs[x] for x in possible_states])
    if len(state_set) > 0:
        p = sum([model.probs[x] for x in state_set])
        p = math.exp( math.log(p) - math.log(norm) )
    else:
        p = 0.0
        assert norm > 0
    
    return p