示例#1
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
示例#2
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
示例#3
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
示例#4
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
示例#5
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
示例#6
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