示例#1
0
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
示例#2
0
文件: rule.py 项目: charyorde/dao
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]
示例#3
0
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]
示例#4
0
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]
示例#5
0
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
示例#6
0
文件: rule.py 项目: charyorde/dao
 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
示例#7
0
文件: rule.py 项目: charyorde/dao
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]
示例#8
0
文件: rule.py 项目: charyorde/dao
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
示例#9
0
文件: rule.py 项目: charyorde/dao
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
示例#10
0
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
示例#11
0
文件: matcher.py 项目: charyorde/dao
 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
示例#12
0
文件: matcher.py 项目: charyorde/dao
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), []
示例#13
0
文件: matcher.py 项目: charyorde/dao
 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
示例#14
0
文件: matcher.py 项目: charyorde/dao
 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
示例#15
0
文件: matcher.py 项目: charyorde/dao
 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
示例#16
0
文件: matcher.py 项目: charyorde/dao
 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)), []
示例#17
0
文件: matcher.py 项目: charyorde/dao
 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
示例#18
0
文件: rule.py 项目: charyorde/dao
 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
示例#19
0
文件: matcher.py 项目: charyorde/dao
 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
示例#20
0
文件: matcher.py 项目: charyorde/dao
 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
示例#21
0
文件: control.py 项目: charyorde/dao
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
示例#22
0
文件: matcher.py 项目: charyorde/dao
 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))), []
示例#23
0
文件: matcher.py 项目: charyorde/dao
 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
示例#24
0
文件: matcher.py 项目: charyorde/dao
 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
示例#25
0
文件: matcher.py 项目: charyorde/dao
 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
示例#26
0
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
示例#27
0
文件: rule.py 项目: charyorde/dao
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
示例#28
0
文件: rule.py 项目: charyorde/dao
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
示例#29
0
文件: matcher.py 项目: charyorde/dao
 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
示例#30
0
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
示例#31
0
文件: matcher.py 项目: charyorde/dao
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
示例#32
0
文件: rule.py 项目: charyorde/dao
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]
示例#33
0
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]
示例#34
0
文件: rule.py 项目: charyorde/dao
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
示例#35
0
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
示例#36
0
文件: arith.py 项目: charyorde/dao
 def pred(solver, cont, var0, var1):
   if binary(getvalue(var0, solver.env), 
               getvalue(var1, solver.env)):
     yield cont, True
示例#37
0
文件: matcher.py 项目: charyorde/dao
 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
示例#38
0
文件: rule.py 项目: charyorde/dao
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
示例#39
0
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