def retract(solver, cont, rules, head): rules = getvalue(rules, solver.env) if not isinstance(rules, klass): raise ValueError(rules) arity = len(head) if arity not in rules.arity_rules: yield cont, rules.arity_rules[arity] return arity_rules = rules.arity_rules[arity] index = 0 while index<len(arity_rules): rule = arity_rules[index] caller_env = solver.env.extend() callee_env = caller_env.extend() for _ in unify_list_rule_head(head, rule.head, callee_env, caller_env, set()): rule = arity_rules[index] del arity_rules[index] arity_signature2rules = rules.signature2rules[arity] for signature in rule_head_signatures(rule.head): arity_signature2rules[signature].remove(index) remove_memo_head(solver, rules, head) yield cont, arity_rules arity_rules.insert(index, rule) for signature in rule_head_signatures(rule.head): arity_signature2rules[signature].add(index) return # head don't match any rule in rules yield cont, True
def apply(self, solver, cont, values, call_data): caller_env = solver.env env = call_data.env call_path = solver.call_path[:] solver.call_path.append(self) if not call_data.recursive: solver.env = env.extend() else: env.bindings = {} solver.env = env subst = {} sign_state = (call_data.command, call_data.signatures), solver.parse_state values = getvalue(values, solver.env) for _ in unify_list_rule_head(values, self.head, solver.env, subst): @mycont(cont) def rule_done_cont(value, solver): self.body env_values = tuple(getvalue(v, solver.env) for v in subst.values()) generators = tuple(set_bindings(caller_env.bindings, k, v) for k, v in zip(subst.keys(), env_values)) for _ in apply_generators(generators): solver.env = caller_env solver.call_path = call_path yield cont, value solver.env = caller_env solver.call_path = call_path yield solver.exps_cont(self.body, rule_done_cont), True solver.env = caller_env solver.call_path = call_path
def retract(solver, rules, head): rules = getvalue(rules, solver.env, {}) if not isinstance(rules, klass): raise ValueError(rules) arity = len(head) if arity not in rules.arity_rules: yield cont, rules.arity_rules[arity] return arity_rules = rules.arity_rules[arity] index = 0 while index<len(arity_rules): rule = arity_rules[index] caller_env = solver.env.extend({}) callee_env = caller_env.extend({}) for _ in unify_list_rule_head(head, rule.head, callee_env, caller_env, set()): rule = arity_rules[index] del arity_rules[index] arity_signature2rules = rules.signature2rules[arity] for signature in rule_head_signatures(rule.head): arity_signature2rules[signature].remove(index) remove_memo_head(solver, rules, head) yield cont, arity_rules arity_rules.insert(index, rule) for signature in rule_head_signatures(rule.head): arity_signature2rules[signature].add(index) return # head don't match any rule in rules yield cont, True
def retractall(solver, cont, rules, head, klass=UserFunction): rules = getvalue(rules, solver.env) if not isinstance(rules, klass): raise ValueError arity = len(head) if arity not in rules.arity_rules: yield cont, rules.arity_rules[arity] return arity_signature2rules = rules.signature2rules[arity] arity_rules = rules.arity_rules[arity] old_arity_rules = arity_rules[:] del_indexes = {} index = 0 changed = False while index<len(arity_rules): caller_env = solver.env.extend() callee_env = caller_env.extend() unified = False for _ in unify_list_rule_head(head, rule.head, callee_env, caller_env, set()): unified = True changed = True rule = arity_rules[index] del arity_rules[index] for signature in rule_head_signatures(rule.head): arity_signature2rules[signature].remove(index) del_indexes.setdefault(signature, set()).add(index) del_indexes.append(index) if not unified: index += 1 if changed: remove_memo_head(solver, rules, head) yield cont, arity_rules if not changed: return rules.signature2rules[arity] = old_arity_rules for signature, indexes in del_indexes.items(): arity_signature2rules[signature] |= indexes
def retractall(solver, rules, head, klass=UserFunction): rules = getvalue(rules, solver.env, {}) if not isinstance(rules, klass): raise ValueError arity = len(head) if arity not in rules.arity_rules: yield cont, rules.arity_rules[arity] return arity_signature2rules = rules.signature2rules[arity] arity_rules = rules.arity_rules[arity] old_arity_rules = arity_rules[:] del_indexes = {} index = 0 changed = False while index<len(arity_rules): caller_env = solver.env.extend({}) callee_env = caller_env.extend({}) unified = False for _ in unify_list_rule_head(head, rule.head, callee_env, caller_env, set()): unified = True changed = True rule = arity_rules[index] del arity_rules[index] for signature in rule_head_signatures(rule.head): arity_signature2rules[signature].remove(index) del_indexes.setdefault(signature, set()).add(index) del_indexes.append(index) if not unified: index += 1 if changed: remove_memo_head(solver, rules, head) yield cont, arity_rules if not changed: return rules.signature2rules[arity] = old_arity_rules for signature, indexes in del_indexes.items(): arity_signature2rules[signature] |= indexes