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 seplist_bultin(solver, cont, item, separator): for _ in unify(result, [], solver.env): yield cont, True separator1 = deref(separator, solver.env) item1 = deref(item, solver.env) yield solver.cont(item1, lazy_repeat_result_cont( (and_p, separator1, item1), cont, 1, [], deref(template, solver.env), deref(result, solver.env))), []
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, template, result): separator1 = deref(separator, solver.env) item1 = deref(item, solver.env) for c, _ in solver.exp_run_cont(item1, cont): yield greedy_repeat_result_cont( (and_p, separator1, item1), c, 1, [], deref(template, solver.env), deref(result, solver.env)), [] return for _ in unify(result, [], solver.env): yield cont, True
def or_p(solver, cont, *calls): if len(calls)==0: yield value_cont(None, cont), True call0 = deref(calls[0], solver.env) if call0[0]==if_p: # A -> B; C if_clause = deref(call0[1], solver.env) then_clause = deref(call0[2], solver.env) calls = ((and_p, if_clause, (Cut, ), then_clause),)+calls[1:] for call in calls: yield solver.cont(call, cont), True
def if_p(solver, cont, if_clause, then_clause): # This unusual semantics is part of the ISO and all de-facto Prolog standards. # see SWI-Prolog help. if_clause = deref(if_clause, solver.env) then_clause = deref(then_clause, solver.env) @mycont(cont) def if_p_cont(value, solver): ## if not value: return # important! logic predicate if_p decide whether to continue by the fail or succeed of the condition. yield solver.cont(then_clause, cont), True yield solver.cont(if_clause, if_p_cont), True
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 between(solver, cont, *exps): lower, upper, mid = exps lower = deref(lower, solver.env) if isinstance(lower, Var): error.throw_instantiation_error() upper = deref(upper, solver.env) if isinstance(upper, Var): error.throw_instantiation_error() mid = deref(mid, solver.env) if not isinstance(mid, Var): if lower<=mid<=upper: yield cont, True else: return for x in range(lower, upper+1): for y in mid.unify(x, solver.env): 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 seplist_times_less_bultin(solver, cont, item, separator, template, result): expect_times = deref(expect_times, solver.env) if not isinstance(expect_times, int): raise ValueError(expect_times) if expect_times==0: if result is None: yield cont, True else: for _ in unify(result, []): yield cont, True 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 if mode==greedy: matched = False for c, v in solver.exp_run_cont(item, cont): matched = True next_cont = make_times_less_cont(solver, cont, item1, separator1, expect_times1-1, 1, [], template1, result1, mode) yield c, v if not matched: if result1 is None: yield cont, True else: for _ in unify(result1, []): yield cont, True elif mode==nongreedy: for c, v in solver.exp_run_cont(item, cont): next_cont = make_times_less_cont(solver, cont, item1, separator1, expect_times1-1, 1, [], template1, result1, mode) yield c, v if result1 is None: yield cont, True else: for _ in unify(result1, []): yield cont, True else: #mode==lazy if result1 is None: yield cont, True else: for _ in unify(result1, []): yield cont, True for c, v in solver.exp_run_cont(item, cont): next_cont = make_times_less_cont(solver, cont, item1, separator1, expect_times1-1, 1, [], template1, result1, mode) yield c, v
def follow_chars(solver, cont, chars): chars = deref(chars, solver.env) assert isinstance(chars, str) if not eoi_(solver.parse_state) \ and next_char_(solver.parse_state) not in chars: return yield cont, True
def char(solver, cont, argument): argument = deref(argument, solver.env) text, pos = solver.parse_state if pos==len(text): return for _ in unify(argument, text[pos], solver.env): solver.parse_state = text, pos+1 yield cont, text[pos] solver.parse_state = text, pos
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 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 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 concat(solver, cont, sequence1, sequence2, result): sequence1 = deref(sequence1, solver.env) sequence2 = deref(sequence2, solver.env) result = deref(result, solver.env) if isinstance(sequence1, Var): index = 0 if isinstance(sequence2, Var): for index in range(1, len(result)): for _ in sequence1.unify(result[:index], solver.env): for __ in sequence2.unify(result[index:], solver.env): yield cont, True else: if result.endswith(sequence2): for _ in sequence1.unify(result[:len(sequence2)], solver.env): yield cont, True else: if isinstance(sequence2, Var): if result.startswith(sequence1): for _ in sequence2.unify(result[len(sequence1):], solver.env): yield cont, True else: for _ in unify(result, sequence1+sequence2, solver.env): yield cont, True
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 setvalue(solver, cont, var, value): # necessary to deref, see Colosure.deref for the reason if isinstance(var, ClosureVar): var = var.var var = deref(var, solver.env) assert isinstance(var, Var) @mycont(cont) def setvalue_cont(value, solver): old = var.getvalue(solver.env) var.setvalue(value, solver.env) yield cont, True var.setvalue(old, solver.env) yield solver.cont(value, setvalue_cont), True
def literal(solver, cont, arg0): arg0 = deref(arg0, solver.env) assert isinstance(arg0, str) text, pos = solver.parse_state p = pos for char in arg0: if p>=len(text): return if char!=text[p]: return p += 1 solver.parse_state = text, p yield cont, True solver.parse_state = text, pos
def call(solver, args=None, kwargs=None): args = deref(args, solver.env) kwargs = deref(kwargs, solver.env) syntax_result, pos = solver.parse_state if pos==len(syntax_result): return try: if syntax_result[pos][0]!=__call__: return except: return if args is not None: for _ in unify(args, syntax_result[pos][1], solver.env): if kwargs is not None: for _ in unify(kwargs, syntax_result[pos][2], solver.env): solver.parse_state = syntax_result, pos+1 yield cont, True else: solver.parse_state = syntax_result, pos+1 yield cont, True else: solver.parse_state = syntax_result, pos+1 yield cont, True solver.parse_state = syntax_result, pos
def define_global(solver, cont, var, value): if isinstance(var, ClosureVar): var = var.var value = deref(value, solver.env) @mycont(cont) def define_cont(value, solver): bindings = solver.global_env.bindings try: old = bindings[var] yield cont, value binsings[old] = value except: bindings[var] = value yield cont, value del bindings[var] yield solver.cont(value, define_cont), True
def func(solver, argument=None): argument = deref(argument, solver.env) syntax_result, pos = solver.parse_state ## print syntax_result, syntax_result[pos][1] if pos==len(syntax_result): return try: if syntax_result[pos][0]!=attr: return except: return if argument is not None: for _ in unify(argument, syntax_result[pos][1], solver.env): solver.parse_state = syntax_result, pos+1 yield cont, True else: solver.parse_state = syntax_result, pos+1 yield cont, True solver.parse_state = syntax_result, pos
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 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 lead_string(solver, cont, string): strArgument = deref(strArgument, solver.env) assert isinstance(strArgument, str) if not parsed_(solver.parse_state).endwith(strArgument):return yield cont, True
def any_bultin(solver, cont, item, template, result): yield lazy_repeat_result_cont( deref(item, solver.env), cont, 0, [], deref(template, solver.env), deref(result, solver.env)), []
def not_lead_chars(solver, cont, chars): chars = deref(chars, solver.env) assert isinstance(chars, str) if last_char_(solver.parse_state) in chars: return yield cont, True
def make_repeat_cont(solver, cont, item, matched_times, matched_list, template, result, mode): if result is None: if mode==greedy: return greedy_repeat_cont(deref(item, solver.env), cont) elif mode==nongreedy: return nongreedy_repeat_cont(deref(item, solver.env), cont) else:# mode==lazy: return lazy_repeat_cont(deref(item, solver.env), cont) else: if mode==greedy: return greedy_repeat_result_cont( deref(item, solver.env), cont, matched_times, matched_list, deref(template, solver.env), deref(result, solver.env)) elif mode==nongreedy: return nongreedy_repeat_result_cont( deref(item, solver.env), cont, matched_times, matched_list, deref(template, solver.env), deref(result, solver.env)) else: # mode==lazy return lazy_repeat_result_cont( deref(item, solver.env), cont, matched_times, matched_list, deref(template, solver.env), deref(result, solver.env))
def some_bultin(solver, cont, item): yield solver.cont(item, lazy_repeat_cont( deref(item, solver.env), cont)), []
def some_bultin(solver, cont, item, template, result): yield solver.cont(item, lazy_repeat_result_cont( deref(item, solver.env), cont, 1, [], 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) yield solver.cont(item1, lazy_repeat_cont( (and_p, separator1, item1), cont)), []