def bindings(ifs, facts, dict, why): if ifs == []: return [(copy_dict(dict), [])] # all conjuncts matched res = [] head, tail = ifs[0], ifs[1:] if head[0] == 'ask': ground = substitute(head[1:], dict) if ask_user(ground, facts, why): for (dict2, proof2) in bindings(tail, facts, dict, why): res.append((dict2, [(ground, 'told')] + proof2)) elif head[0] == 'not': ground = substitute(head[1:], dict) if not asserted(ground, facts) or asserted(['not']+ground, facts): for (dict2, proof2) in bindings(tail, facts, dict, why): res.append((dict2, [(ground, 'not')] + proof2)) else: for (fact, proof) in facts: matched, changes = match(head, fact, dict, {}) if matched: for (dict2, proof2) in bindings(tail, facts, dict, why): res.append((dict2, [(fact, proof)] + proof2)) for (var, env) in changes: env[var] = '?' return res
def conjunct(ifs, known, dict, why): if ifs == []: return [(copy_dict(dict), [])] # all conjuncts matched res = [] head, tail = ifs[0], ifs[1:] if head[0] == 'ask': term = substitute(head[1:], dict) if ask_user(term, known, why): for (dict2, proof2) in conjunct(tail, known, dict, why): res.append((dict2, [(term, 'told')] + proof2)) elif head[0] == 'not': term = substitute(head[1:], dict) if not known.search_unique(term) or \ known.search_unique(['not'] + term): for (dict2, proof2) in conjunct(tail, known, dict, why): res.append((dict2, [(term, 'not')] + proof2)) else: for (fact, proof) in known.search(head, dict): matched, changes = match(head, fact, dict, {}) if matched: for (dict2, proof2) in conjunct(tail, known, dict, why): res.append((dict2, [(fact, proof)] + proof2)) for (var, env) in changes: env[var] = '?' return res
def copy_proof_tree(proof): copy = [] for node in proof: if node == () or node[1] in ['told', 'not']: copy.append(node) else: copy.append((node[0], (node[1][0], copy_dict(node[1][1])))) for node in copy: if node != () and node[1] not in ['told', 'not']: adjust_pointers(node[1][1], proof, copy) return copy
def copy_proof_tree(proof): copy = [] for node in proof: if node == () or node[1] in ['told', 'not']: copy.append(node) else: copy.append((node[0], (node[1][0], copy_dict(node[1][1])) )) for node in copy: if node != () and node[1] not in ['told', 'not']: adjust_pointers(node[1][1], proof, copy) return copy
def copy_dict_stack(stack): copy = [] for dict in stack: copy.append(copy_dict(dict)) for new in copy: for var in new.keys(): value = new[var] if type(value) == type(()): # a sharing var? for i in range(len(stack)): # refs dict in old? if value[1] is stack[i]: # not '==' new[var] = (value[0], copy[i]) # to newstk dict break return copy