def revise(csp, Xi, Xj, removals): "Return true if we remove a value." revised = False for x in csp.curr_domains[Xi][:]: # If Xi=x conflicts with Xj=y for every possible y, eliminate Xi=x if every(lambda y: not csp.constraints(Xi, x, Xj, y), csp.curr_domains[Xj]): csp.prune(Xi, x, removals) revised = True return revised
def add(self, node_spec): """Add a node to the net. Its parents must already be in the net, and its variable must not.""" node = BayesNode(*node_spec) assert node.variable not in self.variables assert every(lambda parent: parent in self.variables, node.parents) self.nodes.append(node) self.variables.append(node.variable) for parent in node.parents: self.variable_node(parent).children.append(node)
def is_definite_clause(s): """returns True for exprs s of the form A & B & ... & C ==> D, where all literals are positive. In clause form, this is ~A | ~B | ... | ~C | D, where exactly one clause is positive. >>> is_definite_clause(expr('Farmer(Mac)')) True """ if is_symbol(s.op): return True elif s.op == '==>': antecedent, consequent = s.args return (is_symbol(consequent.op) and every( lambda arg: is_symbol(arg.op), conjuncts(antecedent))) else: return False
def is_definite_clause(s): """returns True for exprs s of the form A & B & ... & C ==> D, where all literals are positive. In clause form, this is ~A | ~B | ... | ~C | D, where exactly one clause is positive. >>> is_definite_clause(expr('Farmer(Mac)')) True """ if is_symbol(s.op): return True elif s.op == '==>': antecedent, consequent = s.args return (is_symbol(consequent.op) and every(lambda arg: is_symbol(arg.op), conjuncts(antecedent))) else: return False
def __init__(self, X, parents, cpt): """X is a variable name, and parents a sequence of variable names or a space-separated string. cpt, the conditional probability table, takes one of these forms: * A number, the unconditional probability P(X=true). You can use this form when there are no parents. * A dict {v: p, ...}, the conditional probability distribution P(X=true | parent=v) = p. When there's just one parent. * A dict {(v1, v2, ...): p, ...}, the distribution P(X=true | parent1=v1, parent2=v2, ...) = p. Each key must have as many values as there are parents. You can use this form always; the first two are just conveniences. In all cases the probability of X being false is left implicit, since it follows from P(X=true). >>> X = BayesNode('X', '', 0.2) >>> Y = BayesNode('Y', 'P', {T: 0.2, F: 0.7}) >>> Z = BayesNode('Z', 'P Q', ... {(T, T): 0.2, (T, F): 0.3, (F, T): 0.5, (F, F): 0.7}) """ if isinstance(parents, str): parents = parents.split() # We store the table always in the third form above. if isinstance(cpt, (float, int)): # no parents, 0-tuple cpt = {(): cpt} elif isinstance(cpt, dict): # one parent, 1-tuple if cpt and isinstance(list(cpt.keys())[0], bool): cpt = dict(((v, ), p) for v, p in list(cpt.items())) assert isinstance(cpt, dict) for vs, p in list(cpt.items()): assert isinstance(vs, tuple) and len(vs) == len(parents) assert every(lambda v: isinstance(v, bool), vs) assert 0 <= p <= 1 self.variable = X self.parents = parents self.cpt = cpt self.children = []
def __init__(self, X, parents, cpt): """X is a variable name, and parents a sequence of variable names or a space-separated string. cpt, the conditional probability table, takes one of these forms: * A number, the unconditional probability P(X=true). You can use this form when there are no parents. * A dict {v: p, ...}, the conditional probability distribution P(X=true | parent=v) = p. When there's just one parent. * A dict {(v1, v2, ...): p, ...}, the distribution P(X=true | parent1=v1, parent2=v2, ...) = p. Each key must have as many values as there are parents. You can use this form always; the first two are just conveniences. In all cases the probability of X being false is left implicit, since it follows from P(X=true). >>> X = BayesNode('X', '', 0.2) >>> Y = BayesNode('Y', 'P', {T: 0.2, F: 0.7}) >>> Z = BayesNode('Z', 'P Q', ... {(T, T): 0.2, (T, F): 0.3, (F, T): 0.5, (F, F): 0.7}) """ if isinstance(parents, str): parents = parents.split() # We store the table always in the third form above. if isinstance(cpt, (float, int)): # no parents, 0-tuple cpt = {(): cpt} elif isinstance(cpt, dict): # one parent, 1-tuple if cpt and isinstance(list(cpt.keys())[0], bool): cpt = dict(((v,), p) for v, p in list(cpt.items())) assert isinstance(cpt, dict) for vs, p in list(cpt.items()): assert isinstance(vs, tuple) and len(vs) == len(parents) assert every(lambda v: isinstance(v, bool), vs) assert 0 <= p <= 1 self.variable = X self.parents = parents self.cpt = cpt self.children = []
def goal_test(self, state): "The goal is to assign all vars, with all constraints satisfied." assignment = dict(state) return (len(assignment) == len(self.vars) and every( lambda var: self.nconflicts(var, assignment[var], assignment) == 0, self.vars))
def goal_test(self, state): "The goal is to assign all variables, with all constraints satisfied." assignment = dict(state) return (len(assignment) == len(self.variables) and every(lambda variables: self.nconflicts(variables, assignment[variables], assignment) == 0, self.variables))