def contain(solver, cont, container, member): container = getvalue(container, solver.env) member = getvalue(member, solver.env) if isinstance(member, Var): for x in container: for _ in unify(member, x, solver.env): yield cont, True elif member in container: yield cont, True
def asserta(solver, cont, rules, head, body, klass=UserFunction): rules = getvalue(rules, solver.env) if not isinstance(rules, klass): raise ValueError(rules) arity = len(head) arity_rules = rules.arity2rules.setdefault(arity, []) arity_signature = rules.signature2rules.setdefault(arity, {}) arity_rules.insert(0, Rule(head, body)) for sign in arity_signature: arity_signature[sign] = set([i+1 for i in arity_signature[sign]]) for signature in rule_head_signatures(head): arity_signature.setdefault(signature, set()).add(0) remove_memo_arity(solver, rules, arity) yield cont, rules del arity_rules[0] if len(arity_rules)==1: del rules.arity2rules[arity] del rules.signature2rules[arity] else: del arity_rules[0] for sign in arity_signature: arity_signature[sign] = set([i-1 for i in arity_signature[sign] if i!=0]) if arity_signature[sign]==set(): del arity_signature[sign]
def asserta(solver, rules, head, body, klass=UserFunction): rules = getvalue(rules, solver.env, {}) if not isinstance(rules, klass): raise ValueError(rules) arity = len(head) arity_rules = rules.arity2rules.setdefault(arity, []) arity_signature = rules.signature2rules.setdefault(arity, {}) arity_rules.insert(0, Rule(head, body)) for sign in arity_signature: arity_signature[sign] = set([i+1 for i in arity_signature[sign]]) for signature in rule_head_signatures(head): arity_signature.setdefault(signature, set()).add(0) remove_memo_arity(solver, rules, arity) yield cont, rules del arity_rules[0] if len(arity_rules)==1: del rules.arity2rules[arity] del rules.signature2rules[arity] else: del arity_rules[0] for sign in arity_signature: arity_signature[sign] = set([i-1 for i in arity_signature[sign] if i!=0]) if arity_signature[sign]==set(): del arity_signature[sign]
def insert_def(solver, rules, head, bodies, klass=UserFunction): rules = getvalue(rules, solver.env, {}) if not isinstance(rules, klass): raise ValueError(rules) arity = len(head) arity_rules = rules.arity2rules.setdefault(arity, []) arity2signature = rules.signature2rules.setdefault(arity, {}) length = len(rules.arity2rules[arity]) arity_rules = [Rule(head, body) for body in bodies]+rules.arity2rules[arity] bodies_length = len(bodies) new_indexes = set(range(bodies_length)) for signature in rule_head_signatures(head): indexes = arity2signature.setdefault(signature, set()) indexes |= new_indexes remove_memo_head(solver, rules, head) yield cont, arity_rules if length==0: del rules.arity2rules[arity] del rules.signature2rules[arity] else: del arity_rules[:bodies_length] for signature in rule_head_signatures(head): arity2signature[signature] -= new_indexes if arity2signature[signature]==set(): del arity2signature[signature]
def remove(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.arity2rules: yield cont, rules.arity2rules[arity] return arity_signature2rules = rules.signature2rules[arity] arity_rules = rules.arity2rules[arity] old_arity_rules = arity_rules[:] del_arity_signature2rules = {} index = 0 old_index = 0 changed = False while index<len(arity_rules): if match(head, arity_rules[index].head): changed = True rule = arity_rules[index] del arity_rules[index] for signature in rule_head_signatures(rule.head): arity_signature2rules[signature].remove(old_index) del_arity_signature2rules.setdefault(signature, set()).add(old_index) else: index += 1 old_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_arity_signature2rules.items(): arity_signature2rules[signature] |= indexes
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 insert_def(solver, cont, rules, head, bodies, klass=UserFunction): rules = getvalue(rules, solver.env) if not isinstance(rules, klass): raise ValueError(rules) arity = len(head) arity_rules = rules.arity2rules.setdefault(arity, []) arity2signature = rules.signature2rules.setdefault(arity, {}) length = len(rules.arity2rules[arity]) arity_rules = [Rule(head, body) for body in bodies]+rules.arity2rules[arity] bodies_length = len(bodies) new_indexes = set(range(bodies_length)) for signature in rule_head_signatures(head): indexes = arity2signature.setdefault(signature, set()) indexes |= new_indexes remove_memo_head(solver, rules, head) yield cont, arity_rules if length==0: del rules.arity2rules[arity] del rules.signature2rules[arity] else: del arity_rules[:bodies_length] for signature in rule_head_signatures(head): arity2signature[signature] -= new_indexes if arity2signature[signature]==set(): del arity2signature[signature]
def remove(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.arity2rules: yield cont, rules.arity2rules[arity] return arity_signature2rules = rules.signature2rules[arity] arity_rules = rules.arity2rules[arity] old_arity_rules = arity_rules[:] del_arity_signature2rules = {} index = 0 old_index = 0 changed = False while index<len(arity_rules): if match(head, arity_rules[index].head): changed = True rule = arity_rules[index] del arity_rules[index] for signature in rule_head_signatures(rule.head): arity_signature2rules[signature].remove(old_index) del_arity_signature2rules.setdefault(signature, set()).add(old_index) else: index += 1 old_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_arity_signature2rules.items(): arity_signature2rules[signature] |= indexes
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 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 times_cont(value, solver): if matched_times>0: matched_list.append(getvalue(template, solver.env)) for _ in unify(expect_times, matched_times, solver.env): for _ in unify(result, matched_list, solver.env): yield cont, True next_cont = lazy_times_result_cont(item, cont, matched_times+1, matched_list, template, result) yield solver.cont(item, next_cont), True
def times_less(solver, cont, item, expect_times, template=None, result=None, mode=nongreedy): item = deref(item, solver.env) expect_times = getvalue(expect_times, solver.env) template = deref(template, solver.env) result = deref(result, solver.env) if not isinstance(expect_times, int): raise ValueError(expect_times) if expect_times<0: raise ValueError(self) elif expect_times==0: for c, _ in solver.exp_run_cont(nullword, cont): if result is not None: for _ in unify(result, [], solver.env): yield c, True else: yield cont, True else: if result is None: if mode==greedy: yield greedy_times_less_cont(item, expect_times, cont, 0), True elif mode==nongreedy: yield nongreedy_times_less_cont(item, expect_times, cont, 0), True else:# mode==lazy: yield lazy_times_less_cont(item, expect_times, cont, 0), True else: if mode==greedy: yield greedy_times_less_result_cont( item, expect_times, cont, 0, [], template, result), [] elif mode==nongreedy: yield nongreedy_times_less_result_cont( item, expect_times, cont, 0, [], template, result), [] else: # mode==lazy yield lazy_times_less_result_cont( item, expect_times, cont, 0, [], template, result), []
def times_bultin(solver, cont, item): expectTimes1 = getvalue(expect_times, solver.env) if isinstance(expectTimes1, int): if expectTimes1<0: raise Error elif expectTimes1==0: yield cont, True return yield lazy_times_cont(item, expectTimes1, cont, 0), True
def times_cont(value, solver): if matched_times>0: matched_list.append(getvalue(template, solver.env)) if expect_times==matched_times: for _ in unify(result, matched_list, solver.env): yield cont, True return else: yield solver.cont(item, greedy_times_result_cont(item, expect_times, cont, matched_times+1, matched_list, template, result)), True
def repeat_cont(value, solver): if matched_times>0: matched_list1 = matched_list+[getvalue(template, solver.env)] else: matched_list1 = matched_list next_cont = nongreedy_repeat_result_cont(item, cont, matched_times+1, matched_list1, template, result) yield solver.cont(item, next_cont), True for _ in unify(result, matched_list1, solver.env): yield cont, True
def times_bultin(solver, cont, item, template, result): expectTimes1 = getvalue(expect_times, solver.env) if isinstance(expectTimes1, int): if expectTimes1<0: raise Error elif expectTimes1==0: for _ in unify(result, [], solver.env): yield cont, True return yield lazy_times_result_cont( deref(item, solver.env), expectTimes1, cont, 0, [], deref(template, solver.env), deref(result, solver.env)), []
def seplist_bultin(solver, cont, item, separator): separator1 = deref(separator, solver.env) item1 = deref(item, solver.env) expectTimes1 = getvalue(expect_times, solver.env) if isinstance(expectTimes1, int): if expectTimes1<0: raise Error elif expectTimes1==0: yield cont, True return yield solver.cont(item1, lazy_times_cont((and_p, separator1, item1), expectTimes1, cont, 1, [])), True
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
def times_between_builtin(solver, cont, item, template, result): min1 = deref(min, solver.env) max1 = deref(max, solver.env) if not isinstance(min1, int): raise ValueError(min1) if not isinstance(max1, int): raise ValueError(max1) if min1==0: yield solver.cont((time_less, item, max1, template, result, mode), cont), True if result is not None: temp1 = Var('temp1') temp2 = Var('temp2') else: temp1 = None temp2 = None for c, _ in solver.exp_run_cont(make_times(item, min, template, temp1, mode), cont): for c, _ in solver.exp_run_cont((times_less, item, max-min, template, temp2, mode), cont): if result is not None: matched_list = getvalue(temp1, solver.env)+getvalue(temp2, solver.env) for _ in unify(result, matched_list, solver.env): yield c, True else: yield cont, True
def times_cont(value, solver): if matched_times>0: matched_list.append(getvalue(template, solver.env)) if expect_times==matched_times: for _ in unify(result, matched_list, solver.env): yield cont, True else: for _ in unify(result, matched_list, solver.env): yield cont, True next_cont = lazy_times_less_result_cont(item, expect_times, cont, matched_times+1, matched_list, template, result) for c, x in solver.exp_run_cont(item, next_cont): yield next_cont, x
def findall(solver, cont, goal, template=None, bag=None): goal = deref(goal, solver.env) if bag is not None: result = [] for c, x in solver.exp_run_cont(goal, cont): result.append(getvalue(template, solver.env)) for x in bag.unify(result, solver.env): yield cont, True else: for c, x in solver.exp_run_cont(goal, cont): pass yield cont, True
def seplist_bultin(solver, cont, item, separator, template, result): separator1 = deref(separator, solver.env) item1 = deref(item, solver.env) expectTimes1 = getvalue(expect_times, solver.env) if isinstance(expectTimes1, int): if expectTimes1<0: raise Error elif expectTimes1==0: for _ in unify(result, [], solver.env): yield cont, True return yield solver.cont(item1, lazy_times_result_cont( (and_p, separator1, item1), expectTimes1, cont, 1, [], deref(template, solver.env), deref(result, solver.env))), []
def repeat_cont(value, solver): matched = [False] if matched_times>0: matched_list.append(getvalue(template, solver.env)) next_cont = greedy_repeat_result_cont(item, cont, matched_times+1, matched_list, template, result) @mycont(next_cont) def try_repeat_cont(value, solver): matched[0] = True yield next_cont, True yield solver.cont(item, try_repeat_cont), value if matched[0]: return for _ in unify(result, matched_list, solver.env): yield cont, True
def times_cont(value, solver): if matched_times>0: matched_list1 = matched_list+[getvalue(template, solver.env)] else: matched_list1 = matched_list if expect_times==matched_times: for _ in unify(result, matched_list1, solver.env): yield cont, True else: next_cont = nongreedy_times_less_result_cont(item, expect_times, cont, matched_times+1, matched_list1, template, result) for c, x in solver.exp_run_cont(item, next_cont): yield c, x for _ in unify(result, matched_list1, solver.env): yield cont, True
def times_cont(value, solver): if matched_times>0: matched_list.append(getvalue(template, solver.env)) if expect_times==matched_times: for _ in unify(result, matched_list, solver.env): yield cont, True else: matched = [False] next_cont = greedy_times_less_result_cont(item, expect_times, cont, matched_times+1, matched_list, template, result) @mycont(next_cont) def try_times_cont(value, solver): matched[0] = True yield next_cont, value yield solver.cont(item, try_times_cont), value if not matched: for _ in unify(result, matched_list, solver.env): yield cont, True
def replace(solver, rules, head, body, klass=UserFunction): rules = getvalue(rules, solver.env, {}) if not isinstance(rules, klass): raise ValueError(rules) arity = len(head) arity_rules = rules.arity2rules.setdefault(arity, []) old_arity_rules = None arity_signatures = rules.signature2rules.setdefault(arity, {}) del_indexes = [] index = 0 while index<len(arity_rules): rule = arity_rules[index] if match(head, rule.head): if old_arity_rules is None: old_arity_rules = arity_rules[:] old_arity_signatures = deepcopy(arity_signatures) arity_rules[index] = Rule(head, body) for signature in rule_head_signatures(rule.head): arity_signatures[signature].remove(index) for signature in rule_head_signatures(head): arity_signatures.setdefault(signature, set()).add(index) index += 1 else: del arity_rules[index] del_indexes.append(index) else: index += 1 remove_memo_head(solver, rules, head) if old_arity_rules is not None: delta = 0 modify_dict = {} for i in range(index): if i in del_indexes: delta += 1 else: modify_dict[i] = i-delta for sign in arity_signatures: arity_signatures[sign] = set([modify_dict[i] for i in arity_signatures[sign] if i not in del_indexes]) yield cont, arity_rules # backtracking rules.arity2rules[arity] = old_arity_rules rules.arity2signatures[arity] = old_arity_signatures else: yield cont, arity_rules
def replace(solver, cont, rules, head, body, klass=UserFunction): rules = getvalue(rules, solver.env) if not isinstance(rules, klass): raise ValueError(rules) arity = len(head) arity_rules = rules.arity2rules.setdefault(arity, []) old_arity_rules = None arity_signatures = rules.signature2rules.setdefault(arity, {}) del_indexes = [] index = 0 while index<len(arity_rules): rule = arity_rules[index] if match(head, rule.head): if old_arity_rules is None: old_arity_rules = arity_rules[:] old_arity_signatures = deepcopy(arity_signatures) arity_rules[index] = Rule(head, body) for signature in rule_head_signatures(rule.head): arity_signatures[signature].remove(index) for signature in rule_head_signatures(head): arity_signatures.setdefault(signature, set()).add(index) index += 1 else: del arity_rules[index] del_indexes.append(index) else: index += 1 remove_memo_head(solver, rules, head) if old_arity_rules is not None: delta = 0 modify_dict = {} for i in range(index): if i in del_indexes: delta += 1 else: modify_dict[i] = i-delta for sign in arity_signatures: arity_signatures[sign] = set([modify_dict[i] for i in arity_signatures[sign] if i not in del_indexes]) yield cont, arity_rules # backtracking rules.arity2rules[arity] = old_arity_rules rules.arity2signatures[arity] = old_arity_signatures else: yield cont, arity_rules
def abolish(solver, cont, rules, arity): rules = getvalue(rules, solver.cont) if not isinstance(rules, UserFunction) and not isinstance(rules, UserMacro): raise ValueError(rules) arity = deref(arity, solver.cont) if arity not in rules.arity2rules: yield cont, rules.arity2rules return old_arity2rules = rules.arity2rules[arity] old_signature2rules = rules.signature2rules[arity] del rules.arity2rules[arity] del rules.signature2rules[arity] remove_memo_arity(solver, rules, arity) yield cont, rules.arity2rules rules.arity2rules[arity] = old_arity2rules rules.signature2rules[arity] = old_signature2rules
def seplist_bultin(solver, cont, item, separator, template, result): expect_times = deref(expect_times, solver.env) if not isinstance(expect_times, int): raise ValueError(expect_times) result1 = deref(result, solver.env) if result1 is not None: template1 = deref(template, solver.env) temp_result = Var('temp_result') else: template1 = None temp_result = None prefix_list = make_seplist(item, separator, template1, temp_result1, expect_times, mode) for c, v in solver.exp_run_cont(prefix_list, cont): if result1 is not None: matched_list = getvalue(temp_result1, solver.env) else: matched_list = None next_cont = make_repeat_cont(solver, cont, (and_p, separator1, item1), 0, matched_list, template1, result1, mode) yield next_cont, v
def abolish(solver, rules, arity): rules = getvalue(rules, solver.env, {}) if not isinstance(rules, UserFunction) and not isinstance(rules, UserMacro): raise ValueError(rules) arity = deref(arity, solver.cont) if arity not in rules.arity2rules: yield cont, rules.arity2rules return old_arity2rules = rules.arity2rules[arity] old_signature2rules = rules.signature2rules[arity] del rules.arity2rules[arity] del rules.signature2rules[arity] remove_memo_arity(solver, rules, arity) yield cont, rules.arity2rules rules.arity2rules[arity] = old_arity2rules rules.signature2rules[arity] = old_signature2rules
def times_more(solver, cont, item, expect_times, template=None, result=None, mode=nongreedy): item = deref(item, solver.env) expect_times = getvalue(expect_times, solver.env) template = deref(template, solver.env) result = deref(result, solver.env) if not isinstance(expect_times, int): raise ValueError(expect_times) if expect_times<0: raise ValueError(self) elif expect_times==0: yield solver.cont(any(item, template, result, mode), cont), True elif expect_times==1: yield solver.cont(some(item, template, result, mode)), True else: if result is not None: temp_result = Var('temp_result') else: temp_result = None @mycont(cont) def times_more_cont(value, solver): matched_list = getvalue(temp_result, solver.env) if result is not None else None yield make_repeat_cont(solver, cont, item, 0, matched_list, template, result, mode), value yield solver.cont(make_times(item, expect_times, template, temp_result), times_more_cont), True
def assert_(solver, cont, rules, head, body, klass=UserFunction): rules = getvalue(rules, solver.env) if not isinstance(rules, klass): raise ValueError(rules) arity = len(head) arity_rules = rules.arity2rules.setdefault(arity, []) index = len(arity_rules) arity_rules.append(Rule(head, body)) for signature in rule_head_signatures(head): arity2signature = rules.signature2rules.setdefault(arity, {}) arity2signature.setdefault(signature, set()).add(index) remove_memo_arity(solver, rules, arity) yield cont, arity_rules if index==0: del rules.arity2rules[arity] del rules.signature2rules[arity] else: del arity_rules[-1] for signature in rule_head_signatures(head): arity2signature[signature].remove(index) if arity2signature[signature]==set(): del arity2signature[signature]
def assert_(solver, rules, head, body, klass=UserFunction): rules = getvalue(rules, solver.env, {}) if not isinstance(rules, klass): raise ValueError(rules) arity = len(head) arity_rules = rules.arity2rules.setdefault(arity, []) index = len(arity_rules) arity_rules.append(Rule(head, body)) for signature in rule_head_signatures(head): arity2signature = rules.signature2rules.setdefault(arity, {}) arity2signature.setdefault(signature, set()).add(index) remove_memo_arity(solver, rules, arity) yield cont, arity_rules if index==0: del rules.arity2rules[arity] del rules.signature2rules[arity] else: del arity_rules[-1] for signature in rule_head_signatures(head): arity2signature[signature].remove(index) if arity2signature[signature]==set(): del arity2signature[signature]
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
def pred(solver, cont, var0, var1): if binary(getvalue(var0, solver.env), getvalue(var1, solver.env)): yield cont, True
def times_more_cont(value, solver): matched_list = getvalue(temp_result, solver.env) if result is not None else None yield make_repeat_cont(solver, cont, item, 0, matched_list, template, result, mode), value
def replace_def(solver, cont, rules, head, bodies, klass=UserFunction): rules = getvalue(rules, solver.env) if isinstance(rules, Var): new_rules = [(head,)+tuple(body) for body in bodies] arity2rules, signature2rules = make_rules(new_rules) solver.env[rules] = klass(arity2rules, signature2rules, solver.env, False) yield cont, rules del solver.env.bindings[rules] return if not isinstance(rules, klass): raise ValueError arity = len(head) new_indexes = set(range(len(bodies))) if arity not in rules.arity2rules: rules.arity2rules[arity] = [Rule(head, body) for body in bodies] rules.signature2rules[arity] = {} for signature in rule_head_signatures(head): rules.signature2rules[arity][signature] = new_indexes yield cont, rules.arity2rules[arity] del rules.arity2rules[arity] del rules.signature2rules[arity] return arity_rules = rules.arity2rules[arity] old_arity_rules = None index = 0 arity_signatures = rules.signature2rules[arity] del_indexes = [] while index<len(arity_rules): rule = arity_rules[index] if match(head, rule.head): if old_arity_rules is None: old_arity_rules = arity_rules[:] old_arity_signatures = deepcopy(arity_signatures) new_indexes_start = index new_indexes = set(range(index, index+len(bodies))) del arity_rules[index] for signature in rule_head_signatures(rule.head): arity_signatures[signature].remove(index) for body in bodies: arity_rules.insert(index, Rule(head, body)) new_indexes_map = {} for signature in rule_head_signatures(head): new_indexes_map[signature] = new_indexes index += len(bodies) else: del arity_rules[index] del_indexes.append(index) else: index += 1 if old_arity_rules is not None: delta = 0 modify_dict = {} i = 0 delta = 0 while i < index: if i in del_indexes: delta -= 1 elif i==new_indexes_start: delta += len(bodies)-1 else: modify_dict[i] = i+delta i += 1 for sign in arity_signatures: arity_signatures[sign] = set([modify_dict[i] for i in arity_signatures[sign] if i not in del_indexes]) arity_signatures[sign] |= new_indexes_map.get(sign, set()) remove_memo_head(solver, rules, head) yield cont, arity_rules # backtracking rules.arity2rules[arity] = old_arity_rules rules.signature2rules[arity] = old_arity_signatures else: yield cont, arity_rules
def replace_def(solver, rules, head, bodies, klass=UserFunction): rules = getvalue(rules, solver.env, {}) if isinstance(rules, Var): new_rules = [(head,)+tuple(body) for body in bodies] arity2rules, signature2rules = make_rules(new_rules) solver.env[rules] = klass(arity2rules, signature2rules, solver.env, False) yield cont, rules del solver.env.bindings[rules] return if not isinstance(rules, klass): raise ValueError arity = len(head) new_indexes = set(range(len(bodies))) if arity not in rules.arity2rules: rules.arity2rules[arity] = [Rule(head, body) for body in bodies] rules.signature2rules[arity] = {} for signature in rule_head_signatures(head): rules.signature2rules[arity][signature] = new_indexes yield cont, rules.arity2rules[arity] del rules.arity2rules[arity] del rules.signature2rules[arity] return arity_rules = rules.arity2rules[arity] old_arity_rules = None index = 0 arity_signatures = rules.signature2rules[arity] del_indexes = [] while index<len(arity_rules): rule = arity_rules[index] if match(head, rule.head): if old_arity_rules is None: old_arity_rules = arity_rules[:] old_arity_signatures = deepcopy(arity_signatures) new_indexes_start = index new_indexes = set(range(index, index+len(bodies))) del arity_rules[index] for signature in rule_head_signatures(rule.head): arity_signatures[signature].remove(index) for body in bodies: arity_rules.insert(index, Rule(head, body)) new_indexes_map = {} for signature in rule_head_signatures(head): new_indexes_map[signature] = new_indexes index += len(bodies) else: del arity_rules[index] del_indexes.append(index) else: index += 1 if old_arity_rules is not None: delta = 0 modify_dict = {} i = 0 delta = 0 while i < index: if i in del_indexes: delta -= 1 elif i==new_indexes_start: delta += len(bodies)-1 else: modify_dict[i] = i+delta i += 1 for sign in arity_signatures: arity_signatures[sign] = set([modify_dict[i] for i in arity_signatures[sign] if i not in del_indexes]) arity_signatures[sign] |= new_indexes_map.get(sign, set()) remove_memo_head(solver, rules, head) yield cont, arity_rules # backtracking rules.arity2rules[arity] = old_arity_rules rules.signature2rules[arity] = old_arity_signatures else: yield cont, arity_rules