def new_rule(atomspace, action_str, pre_str, post_str): action_l = action_str.split() action = actions[action_l[0]] vars = {} for v_str in action_l[1:]: vars[v_str] = atomspace.add(t.VariableNode, v_str) preconditions = parse_conditions_list(vars, pre_str) preconditions.append(actionDone_template(atomspace, action_template(action, parse_params(vars, action_l)))) postconditions = parse_conditions_list(vars, post_str) pil = T('PredictiveImplicationLink', T('SimultaneousAndLink', preconditions ), T('SimultaneousAndLink', postconditions ) ) atom_from_tree(pil, atomspace).tv = TruthValue(1, confidence_to_count(1)) print pil return pil
def crispModusPonensFormula(tvs): (sAB, nAB), (sA, nA) = tv_seq_to_tv_tuple_seq(tvs) true = 0.5 if all(x >= true for x in [sAB, nAB, sA, nA]): return [TruthValue(1, confidence_to_count(0.99))] else: return [TruthValue(0, 0)]
def crispModusPonensFormula(tvs, U): (sAB, nAB), (sA, nA) = tvs true = 0.1 if all(x > true for x in [sAB, nAB, sA, nA]): return (1, confidence_to_count(1)) else: return (0, 0)
def planning_rules(atomspace): '''A bunch of dubious hacks for using PLN as a STRIPS-style planner. Which isn't a great idea anyway''' rules = [] # Used by planning. An ExecutionLink indicates an action being performed, so we can # assume that the action will be performed as part of the plan (i.e. if any action # occurs in the plan, set the TV to full probability and confidence). #r = Rule(T('ExecutionLink', 1, 2), # [], # name = 'PerformAction', # tv = TruthValue(1.0,confidence_to_count(1.0))) #rules.append(r) # TOdo this should be actionSuccess not just actionDone r = Rule(actionDone_template(atomspace), [], name = 'PerformAction', tv = TruthValue(1.0,confidence_to_count(1.0))) rules.append(r) # If something is true at the current time, you can use it as the start of the plan. # First find the latest time (hack) current_time = 0 for time in atomspace.get_atoms_by_type(t.TimeNode): timestamp = int(time.name) if timestamp > current_time: current_time = timestamp current_time_node = atomspace.add(t.TimeNode, str(current_time)) # Then create the Rule # It's essential to store the template so it will have the same variables in both # the head and the goal template = evaluation_link_template() r = Rule(template, [T('AtTimeLink', current_time_node, template)], name = 'AtCurrentTime' ) rules.append(r) # A hacky rule for determining SequentialAndLinks. It doesn't check that the things # happen after each other. It's just intended to find results from the PerformAction # or AtCurrentTime rules. type = 'SequentialAndLink' for size in xrange(10): args = [new_var() for i in xrange(size+1)] rules.append(Rule(T(type, args), args, type[:-4], formula = formulas.andSymmetricFormula)) # A hacky rule for determining SimultaneousAndlinks. type = 'SimultaneousAndLink' for size in xrange(11): args = [new_var() for i in xrange(size+1)] rules.append(Rule(T(type, args), args, type[:-4], formula = formulas.andSymmetricFormula)) return rules
def andSymmetricFormula(tvs, U): total_strength = 1.0 total_confidence = 1.0 for (s, n) in tvs: total_strength *= s total_confidence *= count_to_confidence(n) return (total_strength, confidence_to_count(total_confidence))
def andSymmetricFormula(tvs): total_strength = 1.0 total_confidence = 1.0 for tv in tvs: total_strength *= tv.mean total_confidence *= count_to_confidence(tv.count) return [TruthValue(total_strength, confidence_to_count(total_confidence))]
def do_planning(space, target): a = space rl = T('ReferenceLink', a.add_node(t.ConceptNode, 'plan_selected_demand_goal'), target) atom_from_tree(rl, a) # hack print 'target' target_a = atom_from_tree(target, a) print target_a print target_a.tv target_a.tv = TruthValue(0, 0) print target_a chainer = Chainer(a, planning_mode=True) result_atoms = chainer.bc(target, 2000) print "planning result: ", result_atoms if result_atoms: res_Handle = result_atoms[0] res = tree_from_atom(Atom(res_Handle, a)) trail = chainer.trail(res) actions = chainer.extract_plan(trail) # set plan_success ps = T('EvaluationLink', a.add_node(t.PredicateNode, 'plan_success'), T('ListLink')) # set plan_action_list pal = T('ReferenceLink', a.add_node(t.ConceptNode, 'plan_action_list'), T('ListLink', actions)) ps_a = atom_from_tree(ps, a) pal_a = atom_from_tree(pal, a) print ps print pal ps_a.tv = TruthValue(1.0, confidence_to_count(1.0)) print ps_a.tv return result_atoms
def create_ASSOC(concept): # ASSOC(x, concept) = [Subset x concept - Subset(Not x, concept)]+ assoc_name = 'ASSOC(%s)' % (concept.op.name,) assoc_node = space.add_node(t.ConceptNode, assoc_name) template = T('SubsetLink', new_var(), concept) trees_tvs = match_wrapper(space, template, match_axiom) # for each x that is a subset of concept has_any_members = False for (tr, tv) in trees_tvs: #print tr, tv x = tr.args[0] if x.get_type() != t.ConceptNode: continue # Now find Subset(Not x, concept) template_not = T('SubsetLink', T('NotLink', x), concept ) not_candidates = match_wrapper(space, template_not, match_axiom) #print not_candidates assert len(not_candidates) < 2 if len(not_candidates) == 0: print 'missing link',template_not continue (_, tv_not) = not_candidates[0] assoc_strength = tv.mean - tv_not.mean # TODO obviously we're fudging the confidence values here if assoc_strength > 0: mem_tr = T('MemberLink', x, assoc_node ) mem_link = atom_from_tree(mem_tr, space) mem_link.tv = TruthValue(assoc_strength, confidence_to_count(1.0)) print mem_link has_any_members = True #assert has_any_members return T(assoc_node)
def do_planning(space, target): a = space rl = T('ReferenceLink', a.add_node(t.ConceptNode, 'plan_selected_demand_goal'), target) atom_from_tree(rl, a) # hack print 'target' target_a = atom_from_tree(target, a) print target_a print target_a.tv target_a.tv = TruthValue(0, 0) print target_a chainer = Chainer(a, planning_mode = True) result_atoms = chainer.bc(target, 2000) print "planning result: ", result_atoms if result_atoms: res_Handle = result_atoms[0] res = tree_from_atom(Atom(res_Handle, a)) trail = chainer.trail(res) actions = chainer.extract_plan(trail) # set plan_success ps = T('EvaluationLink', a.add_node(t.PredicateNode, 'plan_success'), T('ListLink')) # set plan_action_list pal = T('ReferenceLink', a.add_node(t.ConceptNode, 'plan_action_list'), T('ListLink', actions)) ps_a = atom_from_tree(ps, a) pal_a = atom_from_tree(pal, a) print ps print pal ps_a.tv = TruthValue(1.0, confidence_to_count(1.0)) print ps_a.tv return result_atoms
def do_planning(space, target, chainer=None): a = space rl = T('ReferenceLink', a.add_node(t.ConceptNode, 'plan_selected_demand_goal'), target) atom_from_tree(rl, a) # hack print 'target' target_a = atom_from_tree(target, a) print target_a print target_a.tv target_a.tv = TruthValue(0, 0) print target_a if chainer is None: chainer = Chainer(a, planning_mode=True) result_atoms = chainer.bc(target, 5000) print "inference result: ", result_atoms for res in chainer.results: trail = chainer.trail(res) actions = chainer.extract_plan(trail) print actions # set plan_success ps = T('EvaluationLink', a.add_node(t.PredicateNode, 'plan_success'), T('ListLink')) # set plan_action_list (but you should also delete the previous one! or is that done in C++?) pal = T('ReferenceLink', a.add_node(t.ConceptNode, 'plan_action_list'), T('ListLink', actions)) ps_a = atom_from_tree(ps, a) pal_a = atom_from_tree(pal, a) print ps print pal ps_a.tv = TruthValue(1.0, confidence_to_count(1.0)) print ps_a.tv return result_atoms
def do_planning(space, target, chainer = None): a = space rl = T('ReferenceLink', a.add_node(t.ConceptNode, 'plan_selected_demand_goal'), target) atom_from_tree(rl, a) # hack print 'target' target_a = atom_from_tree(target, a) print target_a print target_a.tv target_a.tv = TruthValue(0, 0) print target_a if chainer is None: chainer = Chainer(a, planning_mode = True) result_atoms = chainer.bc(target, 5000) print "inference result: ", result_atoms for res in chainer.results: trail = chainer.trail(res) actions = chainer.extract_plan(trail) print actions # set plan_success ps = T('EvaluationLink', a.add_node(t.PredicateNode, 'plan_success'), T('ListLink')) # set plan_action_list (but you should also delete the previous one! or is that done in C++?) pal = T('ReferenceLink', a.add_node(t.ConceptNode, 'plan_action_list'), T('ListLink', actions)) ps_a = atom_from_tree(ps, a) pal_a = atom_from_tree(pal, a) print ps print pal ps_a.tv = TruthValue(1.0, confidence_to_count(1.0)) print ps_a.tv return result_atoms
def match_neighbors(space,target): print 'match_neighbors',target template = T('EvaluationLink', space.add(t.PredicateNode,'neighbor'), T('ListLink', Var(1), Var(2) ) ) s = unify(template, target, {}) cube1 = s[Var(1)] #template = T('ImplicationLink', # Var(2), # Var(1) #) #s = unify(template, target, {}) #cube1 = s[Var(1)] def get_coords(expr): name = expr.op.name tuple_str = name[3:] coords = tuple(map(int, tuple_str[1:-1].split(','))) return coords if cube1.is_variable() or not isinstance(cube1.op, Atom): return [] (x,y,z) = get_coords(cube1) ns = [(x-1,y,z),(x+1,y,z),(x,y-1,z),(x,y+1,z)] # jumping onto a block ns += [(x,y,z+1) for n in ns] tv = TruthValue(1,confidence_to_count(1.0)) candidates = [] for n in ns: cube2 = Tree(space.add(t.ConceptNode, 'at %s' % str(n))) s = {Var(1):cube1, Var(2):cube2} cand = subst(s, template) candidates.append((cand,tv)) return candidates
def match_predicate(space,target): # Actually it would be much better to use the standard target for this rule # + unify to find the places #print 'match_predicate',target ll = target.args[1] #print ll (n1,n2,n3) = ll.args candidates = [] if (n1.get_type() == t.NumberNode and n2.get_type() == t.NumberNode): if (n3.get_type() == t.NumberNode): if int(n1.op.name) + int(n2.op.name) == int(n3.op.name): candidates.append((target, TruthValue(1.0,confidence_to_count(1.0)))) elif (n3.is_variable()): addition = int(n1.op.name) + int(n2.op.name) s = {n3: Tree(space.add(t.NumberNode,str(addition)))} c = subst(s, target) print '>>>match_predicate:c',c candidates.append((c, None)) return candidates
def new_rule(atomspace, action_str, pre_str, post_str): action_l = action_str.split() action = actions[action_l[0]] vars = {} for v_str in action_l[1:]: vars[v_str] = atomspace.add(t.VariableNode, v_str) preconditions = parse_conditions_list(vars, pre_str) preconditions.append( actionDone_template( atomspace, action_template(action, parse_params(vars, action_l)))) postconditions = parse_conditions_list(vars, post_str) pil = T('PredictiveImplicationLink', T('SimultaneousAndLink', preconditions), T('SimultaneousAndLink', postconditions)) atom_from_tree(pil, atomspace).tv = TruthValue(1, confidence_to_count(1)) print pil return pil
def blocksworld_rules(atomspace): for letter in 'ABC': blocks[letter] = atomspace.add(t.ObjectNode, 'movable_block_' + letter) for action_name in 'unstack stack pickup putdown start end'.split(' '): actions[action_name] = atomspace.add(t.SchemaNode, action_name) for predicate_name in 'clear on ontable handempty holding'.split(' '): predicates[predicate_name] = atomspace.add(t.PredicateNode, predicate_name) # top = new_var() # bottom = new_var() # # preconditions = [ # evaluation_link_template(predicates['clear'],[top]), # evaluation_link_template(predicates['on'],[top, bottom]), # evaluation_link_template(predicates['handempty'],[]) # ] # postconditions = [ # evaluation_link_template(predicates['holding'],[top]), # evaluation_link_template(predicates['clear'],[bottom]), # # what? # not_template(evaluation_link_template(predicates['clear'],[top])), # not_template(evaluation_link_template(predicates['on'],[top, bottom])), # not_template(evaluation_link_template(predicates['handempty'],[])) # ] # # pil = T('PredictiveImplicationLink', # T('SimultaneousAndLink', # preconditions, # actionDone_template(atomspace, action_template(actions['unstack'], [top, bottom])) # ), # T('SimultaneousAndLink', # postconditions # ) # ) # atom_from_tree(pil, atomspace) # new_rule([('clear',top), ('on',top, bottom), ('handempty')], # [('holding', top), ('clear', bottom), ('~clear', top), ('~on', top, bottom), ('~handempty')], # ('unstack', top, bottom) # ) # # new_rule([('holding',top), ('clear', bottom)], # [('on',top,bottom),('clear',top),('handempty'),('~holding',top),('~clear, bottom')], # ('stack',top, bottom) # ) new_rule( atomspace, 'unstack top bottom', 'clear top | on top bottom | handempty', 'holding top | clear bottom | ~clear top | ~on top bottom | ~handempty' ) new_rule( atomspace, 'stack top bottom', 'holding top | clear bottom', 'on top bottom | clear top | handempty | ~holding top | ~clear bottom') new_rule(atomspace, 'pickup block', 'ontable block | clear block | handempty', 'holding block | ~ontable block | ~clear block | ~handempty') new_rule(atomspace, 'putdown block', 'holding block', 'ontable block | clear block | handempty | ~holding block') initial_conditions_and = T( 'SimultaneousAndLink', #parse_conditions_list(blocks, 'on C A | handempty | ontable A | ontable B | clear B | clear C') parse_conditions_list( blocks, 'ontable C | handempty | ontable A | ontable B | clear B | clear C' )) atom = atom_from_tree(initial_conditions_and, atomspace) atom.tv = TruthValue(1, confidence_to_count(1))
def load_scm_file(a, filename): log.info("loading...") tree = Viz_Graph() ident_stack = [] atom_stack = [] root = None define_dict = { } try: f = open(filename, "r") for line_no, line in enumerate(f.readlines()): # code... ## parase scheme file line by line ## parase "define" temp = line.strip('\n ()') if temp.startswith('define'): temp = temp.split(' ') define_dict[temp[1]] = temp[2] continue ## if line.startswith('('): if tree.number_of_nodes() > 0: # deal with previous segment add_tree_to_atomspace(a, tree, root) tree.clear() # ident_stack[:] = [] atom_stack[:] = [] ## parase a new segment name = "" t = "" stv = None av = {} ident = line.find("(") if ident != -1: #log.debug(line.strip('\n')) ident_stack.append(ident) # the first: type name # the second: stv or av # the third: stv or av l = line line = line.strip(' ') line = line.strip('\n') elms = line.split('(') first = elms[1] try: second = elms[2] second = second.split(')')[0] second = dict_sub(second, define_dict) except Exception: second = None try: third = elms[3] third = third.split(')')[0] third = dict_sub(third, define_dict) except Exception: third = None #log.debug("********************" ) #log.debug("first:%s*"%first) #log.debug("second:%s*"%second) #log.debug("third:%s*"%third) #log.debug("********************" ) if second: second = second.strip() if second.find("av") != -1: temp = second.split(" ") av['sti'] = float(temp[1]) av['lti'] = float(temp[2]) av['vlti'] = float(temp[3]) elif second.find("stv") != -1: temp = second.split(" ") mean = float(temp[1]) confidence = float(temp[2]) # the value to stv! stv = TruthValue(mean,confidence_to_count(confidence)) if third: third = third.strip() if third.find("av") != -1: temp = third.split(" ") av['sti'] = float(temp[1]) av['lti'] = float(temp[2]) av['vlti'] = float(temp[3]) elif third.find("stv") != -1: temp = third.split(" ") mean = float(temp[1]) confidence = float(temp[2]) # the value to stv! stv = TruthValue(mean,confidence_to_count(confidence)) try: t = first[0:first.index(' ')] name = first[first.index(' ') + 1: -1].strip('"') #log.debug("**********atom**************" ) #log.debug("type: %s"%t+"*" ) #log.debug("name: %s"%name+"*") #log.debug("stv: %s"%stv) #log.debug("av: %s"%av) #log.debug("*****************************" ) except Exception: t = first.strip(' ') ## add nodes to segment tree is_node = True if name else False if is_node: # node try: node = FakeAtom(name_type_dict[t], name, stv, av) except KeyError: log.error("Unknown Atom type '%s' in line %s, pls add related type infomation to file 'types_inheritance.py' and OpenCog"% (t,line_no)) raise KeyError uni_node_id = tree.unique_id(name) tree.add_node(uni_node_id, atom = node) atom_stack.append(node) if l.startswith('('): root = uni_node_id else: # link uni_link_id = tree.unique_id(t) #print "link:%s**"%t try: link = FakeAtom(name_type_dict[t], uni_link_id, stv, av) except KeyError: log.error("Unknown Atom type '%s' in line %s"% (t,line_no)) raise KeyError atom_stack.append(link) tree.add_node( uni_link_id, atom = link) if l.startswith('('): root = uni_link_id ## add an edge(between link and node, or link to sub_link) to the segment tree now = ident_stack[-1] for i, prev_ident in reversed(list(enumerate(ident_stack))): if now > prev_ident: ## the ith is parent, the link if is_node: log.debug("%s -> %s"%(atom_stack[i].name, uni_node_id)) tree.add_edge(atom_stack[i].name, uni_node_id) else: log.debug("%s -> %s"%(atom_stack[i].name, uni_link_id)) tree.add_edge(atom_stack[i].name, uni_link_id) ## set the 'order' attribute tree.get_node_attr(atom_stack[i].name).setdefault('order',-1) tree.get_node_attr(atom_stack[i].name)['order'] += 1 order = tree.get_node_attr(atom_stack[i].name)['order'] if is_node: tree.set_edge_attr(atom_stack[i].name, uni_node_id, order = order) else: tree.set_edge_attr(atom_stack[i].name, uni_link_id, order = order) break ## deal with the last segment if tree.number_of_nodes() > 0: add_tree_to_atomspace(a, tree, root) tree.clear() log.info("loaded scm file sucessfully!" ) except IOError: log.error("failed to read file %s "%filename ) raise IOError else: f.close()
def blocksworld_rules(atomspace): for letter in 'ABC': blocks[letter] = atomspace.add(t.ObjectNode, 'movable_block_'+letter) for action_name in 'unstack stack pickup putdown start end'.split(' '): actions[action_name] = atomspace.add(t.SchemaNode, action_name) for predicate_name in 'clear on ontable handempty holding'.split(' '): predicates[predicate_name] = atomspace.add(t.PredicateNode,predicate_name) # top = new_var() # bottom = new_var() # # preconditions = [ # evaluation_link_template(predicates['clear'],[top]), # evaluation_link_template(predicates['on'],[top, bottom]), # evaluation_link_template(predicates['handempty'],[]) # ] # postconditions = [ # evaluation_link_template(predicates['holding'],[top]), # evaluation_link_template(predicates['clear'],[bottom]), # # what? # not_template(evaluation_link_template(predicates['clear'],[top])), # not_template(evaluation_link_template(predicates['on'],[top, bottom])), # not_template(evaluation_link_template(predicates['handempty'],[])) # ] # # pil = T('PredictiveImplicationLink', # T('SimultaneousAndLink', # preconditions, # actionDone_template(atomspace, action_template(actions['unstack'], [top, bottom])) # ), # T('SimultaneousAndLink', # postconditions # ) # ) # atom_from_tree(pil, atomspace) # new_rule([('clear',top), ('on',top, bottom), ('handempty')], # [('holding', top), ('clear', bottom), ('~clear', top), ('~on', top, bottom), ('~handempty')], # ('unstack', top, bottom) # ) # # new_rule([('holding',top), ('clear', bottom)], # [('on',top,bottom),('clear',top),('handempty'),('~holding',top),('~clear, bottom')], # ('stack',top, bottom) # ) new_rule(atomspace, 'unstack top bottom', 'clear top | on top bottom | handempty', 'holding top | clear bottom | ~clear top | ~on top bottom | ~handempty' ) new_rule(atomspace, 'stack top bottom', 'holding top | clear bottom', 'on top bottom | clear top | handempty | ~holding top | ~clear bottom' ) new_rule(atomspace, 'pickup block', 'ontable block | clear block | handempty', 'holding block | ~ontable block | ~clear block | ~handempty' ) new_rule(atomspace, 'putdown block', 'holding block', 'ontable block | clear block | handempty | ~holding block' ) initial_conditions_and = T('SimultaneousAndLink', #parse_conditions_list(blocks, 'on C A | handempty | ontable A | ontable B | clear B | clear C') parse_conditions_list(blocks, 'ontable C | handempty | ontable A | ontable B | clear B | clear C') ) atom = atom_from_tree(initial_conditions_and, atomspace) atom.tv = TruthValue(1,confidence_to_count(1))
def load_scm_file(a, filename): log.info("loading...") tree = Viz_Graph() ident_stack = [] atom_stack = [] root = None define_dict = {} try: f = open(filename, "r") for line_no, line in enumerate(f.readlines()): # code... ## parase scheme file line by line ## parase "define" temp = line.strip('\n ()') if temp.startswith('define'): temp = temp.split(' ') define_dict[temp[1]] = temp[2] continue ## if line.startswith('('): if tree.number_of_nodes() > 0: # deal with previous segment add_tree_to_atomspace(a, tree, root) tree.clear() # ident_stack[:] = [] atom_stack[:] = [] ## parase a new segment name = "" t = "" stv = None av = {} ident = line.find("(") if ident != -1: #log.debug(line.strip('\n')) ident_stack.append(ident) # the first: type name # the second: stv or av # the third: stv or av l = line line = line.strip(' ') line = line.strip('\n') elms = line.split('(') first = elms[1] try: second = elms[2] second = second.split(')')[0] second = dict_sub(second, define_dict) except Exception: second = None try: third = elms[3] third = third.split(')')[0] third = dict_sub(third, define_dict) except Exception: third = None #log.debug("********************" ) #log.debug("first:%s*"%first) #log.debug("second:%s*"%second) #log.debug("third:%s*"%third) #log.debug("********************" ) if second: second = second.strip() if second.find("av") != -1: temp = second.split(" ") av['sti'] = float(temp[1]) av['lti'] = float(temp[2]) av['vlti'] = float(temp[3]) elif second.find("stv") != -1: temp = second.split(" ") mean = float(temp[1]) confidence = float(temp[2]) # the value to stv! stv = TruthValue(mean, confidence_to_count(confidence)) if third: third = third.strip() if third.find("av") != -1: temp = third.split(" ") av['sti'] = float(temp[1]) av['lti'] = float(temp[2]) av['vlti'] = float(temp[3]) elif third.find("stv") != -1: temp = third.split(" ") mean = float(temp[1]) confidence = float(temp[2]) # the value to stv! stv = TruthValue(mean, confidence_to_count(confidence)) try: t = first[0:first.index(' ')] name = first[first.index(' ') + 1:-1].strip('"') #log.debug("**********atom**************" ) #log.debug("type: %s"%t+"*" ) #log.debug("name: %s"%name+"*") #log.debug("stv: %s"%stv) #log.debug("av: %s"%av) #log.debug("*****************************" ) except Exception: t = first.strip(' ') ## add nodes to segment tree is_node = True if name else False if is_node: # node try: node = FakeAtom(name_type_dict[t], name, stv, av) except KeyError: log.error( "Unknown Atom type '%s' in line %s, pls add related type infomation to file 'types_inheritance.py' and OpenCog" % (t, line_no)) raise KeyError uni_node_id = tree.unique_id(name) tree.add_node(uni_node_id, atom=node) atom_stack.append(node) if l.startswith('('): root = uni_node_id else: # link uni_link_id = tree.unique_id(t) #print "link:%s**"%t try: link = FakeAtom(name_type_dict[t], uni_link_id, stv, av) except KeyError: log.error("Unknown Atom type '%s' in line %s" % (t, line_no)) raise KeyError atom_stack.append(link) tree.add_node(uni_link_id, atom=link) if l.startswith('('): root = uni_link_id ## add an edge(between link and node, or link to sub_link) to the segment tree now = ident_stack[-1] for i, prev_ident in reversed(list(enumerate(ident_stack))): if now > prev_ident: ## the ith is parent, the link if is_node: log.debug("%s -> %s" % (atom_stack[i].name, uni_node_id)) tree.add_edge(atom_stack[i].name, uni_node_id) else: log.debug("%s -> %s" % (atom_stack[i].name, uni_link_id)) tree.add_edge(atom_stack[i].name, uni_link_id) ## set the 'order' attribute tree.get_node_attr(atom_stack[i].name).setdefault( 'order', -1) tree.get_node_attr(atom_stack[i].name)['order'] += 1 order = tree.get_node_attr(atom_stack[i].name)['order'] if is_node: tree.set_edge_attr(atom_stack[i].name, uni_node_id, order=order) else: tree.set_edge_attr(atom_stack[i].name, uni_link_id, order=order) break ## deal with the last segment if tree.number_of_nodes() > 0: add_tree_to_atomspace(a, tree, root) tree.clear() log.info("loaded scm file sucessfully!") except IOError: log.error("failed to read file %s " % filename) raise IOError else: f.close()
def match_subset(space, target): A, B = target.args #compatible = ((A.get_type() == t.ConceptNode and B.get_type() == t.ConceptNode) or # (A.get_type() == t.PredicateNode and B.get_type() == t.PredicateNode)) #if not compatible: # return [] if A.is_variable() or B.is_variable(): return [] print A, B def members(concept): '''For each member of concept, return the node and the strength of membership''' template = T('MemberLink', new_var(), concept) trees_tvs = match_wrapper(space, template, match_axiom) mems = [(tr.args[0], tv.mean) for (tr, tv) in trees_tvs] assert not (mems is None) return mems def all_member_links(): '''Find all ObjectNodes (or other nodes) that are members of any concept. Returns a set of nodes (each node is wrapped in the Tree class)''' template = T('MemberLink', new_var(), new_var()) trees_tvs = match_wrapper(space, template, match_axiom) mems = set(tr.args[0] for (tr, tv) in trees_tvs) return mems def non_members(concept): # Find the members of Not(A). # For example if A is 'the set of cats', then Not(A) is 'the set of things that aren't cats'. # So for every entity E in the world, (MemberLink E Not(cat)).tv.mean == 1 - (MemberLink E cat).tv.mean. # If the latter is not recorded in the AtomSpace, just assume it is 0. # Find all objects/etc that are members of anything # type: set(Tree) everything = all_member_links() # the type of members_of_concept is [(concept,frequency)] members_of_concept = members(concept) membershipStrengths = { member: strength for (member, strength) in members_of_concept } result = [] for object in everything: membershipStrength = 0 if object in membershipStrengths: membershipStrength = membershipStrengths[object] nonMembershipStrength = 1 - membershipStrength result.append((object, nonMembershipStrength)) return result def evals(concept): template = T('EvaluationLink', concept, T('ListLink', new_var())) trees_tvs = match_wrapper(space, template, match_axiom) mems = [(tr.args[1].args[0], tv.mean) for (tr, tv) in trees_tvs] return mems # Find the members of each concept # For single-argument predicates, this is the same as EvaluationLinks. # TODO: can't handle negated predicates in EvaluationLinks... # This means PredicateNodes can't be in IntensionalInheritanceLinks if A.get_type() == t.NotLink: # Members of Not(A) assert B.get_type() == t.ConceptNode memA = non_members(A) memB = members(B) else: # Members of A memA = members(A) + evals(A) memB = members(B) + evals(B) # memA = evals(A) # memB = evals(B) print memA print print memB # calculate P(x in B | x in A) = P(A^B) / P(A) # based on the fuzzy-weighted average #nodes_in_B = [m for (m,s) in memB] assert not (memB is None) nodesB = {member: strength for (member, strength) in memB} N_AB = 0 for (mA, sA) in memA: if mA in nodesB: sB = nodesB[mA] # min is the definition of fuzzy-AND N_AB += min(sA, sB) #N_AB = sum(s for (m, s) in memA if m in nodes_in_B) N_A = sum(s for (m, s) in memA) if N_A > 0: P = N_AB * 1.0 / N_A tv = TruthValue(P, confidence_to_count(1.0)) else: # If there are no items in A then conditional probability is not defined, so give a zero confidence tv = TruthValue(0, 0) return [(target, tv)]
def rules(a, deduction_types): '''This function sets up all the Rules available in PLN. The concept of a Rule is the same as in higher-order logic. For example, Modus Ponens requires an ImplicationLink $1->$2 as well as the premise of the ImplicationLink ($1) and will produce $2. Every Rule comes with its own formula for calculating TruthValues. PLN works by applying a series of Rules to some Atoms to create new ones.''' # This function creates a list of Rules using the Rule constructor. # See the Rule class for more explanation of the arguments used. # In every step of chaining, the backward chainer has a target Atom (usually with some variables) # it is trying to find. It will apply any Rule whose head unifies with the target. # The function is called every time a Chainer is constructed. rules = [] #path_rules(a) # PLN is able to do pathfinding (experimental). In the Minecraft world, there is a 3D grid # similar to that used by A*. This Rule determines the grid squares (or rather grid cubes) # that are next to a specified grid cube (i.e. the neighborhood, in the A* sense). # You can represent the grid as a network of OpenCog links, which is more suitable for PLN # than having an array (and more versatile in general). # This version of the Rule calculates the neighborhood dynamically. The function path_rules() # uses the simpler but much slower approach of adding thousands of links to the AtomSpace in advance. r = Rule( T( 'EvaluationLink', a.add(t.PredicateNode, 'neighbor'), T( 'ListLink', Var( 1 ), # a ConceptNode representing the coordinates in a tacky format Var(2))), [], name='Neighbors', match=match_neighbors) rules.append(r) #r = Rule(T('ImplicationLink', # Var(1), # Var(2) # ), # [], # name='Neighbors', # match=match_neighbors) #rules.append(r) # You can add a separate Rule for every axiom (i.e. every Atom which has a TruthValue when PLN starts). # It won't add a new Rule for atoms that are created during the inference, rather they will be added to # the Proof DAG. It's simple to have a separate Rule for each axiom, but it's slow because the chainer # will try to unify a target against every axiom Rule. #for obj in a.get_atoms_by_type(t.Atom): # # POLICY: Ignore all false things. This means you can never disprove something! But much more useful for planning! # if obj.tv.count > 0 and obj.tv.mean > 0: # tr = tree_from_atom(obj) # # A variable with a TV could just prove anything; that's evil! # if not tr.is_variable(): # # # tacky filter # if 'CHUNK' in str(tr): # continue # # r = Rule(tr, [], '[axiom]', tv = obj.tv) # rules.append(r) # Just lookup the rule rather than having separate rules. Would be faster # with a large number of atoms (i.e. more scalable). Some examples will break if # you use it due to bugs in the backward chainer. r = Rule(Var(123), [], name='Lookup', match=match_axiom_slow) rules.append(r) # A simple example Rule to test the mechanism. You're allowed to add a Rule which calls # any Python function to decide one of the Atoms. This one does the plus calculation. # The first two variables are the numbers to be added, and the third variable is the result. # i.e. the last variable is the return-value for the '+' function. This is a common pattern in # Prolog. r = Rule(T('EvaluationLink', a.add(t.PredicateNode, '+'), T('ListLink', Var(1), Var(2), Var(3))), [], name='PredicateEvaluation', match=match_predicate) rules.append(r) # The three main logical rules in PLN. The code creates different versions of the Rule # for different kinds of Links. # The classic Modus Ponens rule, used (and over-emphasized) in classical logic everywhere. for ty in ['ImplicationLink', 'PredictiveImplicationLink']: rules.append( Rule(Var(2), [T(ty, 1, 2), Var(1)], name='ModusPonens ' + ty, formula=formulas.modusPonensFormula)) # The PLN DeductionRule. Not to be confused with ModusPonens. for type in deduction_types: rules.append( Rule(T(type, 1, 3), [T(type, 1, 2), T(type, 2, 3), Var(1), Var(2), Var(3)], name='Deduction', formula=formulas.deductionSimpleFormula)) # PLN InversionRule, which reverses an ImplicationLink. It's based on Bayes' Theorem. for type in deduction_types: rules.append( Rule(T(type, 2, 1), [T(type, 1, 2), Var(1), Var(2)], name='Inversion', formula=formulas.inversionFormula)) # Calculating logical And/Or/Not. These have probabilities attached, # but they work similarly to the Boolean versions. type = 'AndLink' for size in xrange(5): args = [new_var() for i in xrange(size + 1)] rules.append( Rule(T(type, args), args, type[:-4], formula=formulas.andSymmetricFormula)) type = 'OrLink' for size in xrange(1, 2): args = [new_var() for i in xrange(size + 1)] rules.append( Rule(T(type, args), args, type[:-4], formula=formulas.orFormula)) # Calculate (NotLink A) using A. There's currently no Rule to find A using (NotLink A) rules.append( Rule(T('NotLink', 1), [Var(1)], name='Not', formula=formulas.notFormula)) # PLN's heuristic Rules to convert one kind of link to another. There are other # variations on this Rule defined in the PLN book, but not implemented yet. rules.append( Rule(T('InheritanceLink', 1, 2), [T('SubsetLink', 1, 2)], name='SubsetLink=>InheritanceLink', formula=formulas.ext2InhFormula)) # Used by planning. An ExecutionLink indicates an action being performed, so we can # assume that the action will be performed as part of the plan (i.e. if any action # occurs in the plan, set the TV to full probability and confidence). #r = Rule(T('ExecutionLink', 1, 2), # [], # name = 'PerformAction', # tv = TruthValue(1.0,confidence_to_count(1.0))) #rules.append(r) # TOdo this should be actionSuccess not just actionDone r = Rule(actionDone_template(a), [], name='PerformAction', tv=TruthValue(1.0, confidence_to_count(1.0))) rules.append(r) # If something is true at the current time, you can use it as the start of the plan. # First find the latest time (hack) current_time = 0 for time in a.get_atoms_by_type(t.TimeNode): timestamp = int(time.name) if timestamp > current_time: current_time = timestamp current_time_node = a.add(t.TimeNode, str(current_time)) # Then create the Rule # It's essential to store the template so it will have the same variables in both # the head and the goal template = evaluation_link_template() r = Rule(template, [T('AtTimeLink', current_time_node, template)], name='AtCurrentTime') rules.append(r) # # Producing ForAll/Bind/AverageLinks. # for type in ['ForAllLink', 'BindLink', 'AverageLink']: # rules.append(Rule(T(type, 1, 2), # [ Var(2) ], # name = type+' abstraction', # formula = formulas.identityFormula)) # This may cause weirdness with things matching too eagerly... # # Both of these rely on the policy that tree_from_atom replaces VariableNodes in the AtomSpace with the variables the tree class uses. # fact = new_var() # list_link = new_var() # r = Rule( # fact, # [T('ForAllLink', list_link, fact )], # name = 'ForAll' # ) # r.tv = True # rules.append(r) # If an Atom is available in an Average/ForAll quantifier, you want to be # able to produce the Atom itself and send it through the other steps of the # inference. for atom in a.get_atoms_by_type(t.AverageLink): # out[0] is the ListLink of VariableNodes, out[1] is the expression tr = tree_from_atom(atom.out[1]) r = Rule(tr, [], name='Average') r.tv = atom.tv rules.append(r) for atom in a.get_atoms_by_type(t.ForAllLink): # out[0] is the ListLink of VariableNodes, out[1] is the expression tr = tree_from_atom(atom.out[1]) r = Rule(tr, [], name='ForAll') r.tv = atom.tv rules.append(r) rules += temporal_rules(a) # Return every Rule specified above. return rules
def match_subset(space,target): A, B = target.args #compatible = ((A.get_type() == t.ConceptNode and B.get_type() == t.ConceptNode) or # (A.get_type() == t.PredicateNode and B.get_type() == t.PredicateNode)) #if not compatible: # return [] if A.is_variable() or B.is_variable(): return [] print A, B def members(concept): '''For each member of concept, return the node and the strength of membership''' template = T('MemberLink', new_var(), concept) trees_tvs = match_wrapper(space, template, match_axiom) mems = [(tr.args[0], tv.mean) for (tr, tv) in trees_tvs] assert not (mems is None) return mems def all_member_links(): '''Find all ObjectNodes (or other nodes) that are members of any concept. Returns a set of nodes (each node is wrapped in the Tree class)''' template = T('MemberLink', new_var(), new_var()) trees_tvs = match_wrapper(space, template, match_axiom) mems = set(tr.args[0] for (tr, tv) in trees_tvs) return mems def non_members(concept): # Find the members of Not(A). # For example if A is 'the set of cats', then Not(A) is 'the set of things that aren't cats'. # So for every entity E in the world, (MemberLink E Not(cat)).tv.mean == 1 - (MemberLink E cat).tv.mean. # If the latter is not recorded in the AtomSpace, just assume it is 0. # Find all objects/etc that are members of anything # type: set(Tree) everything = all_member_links() # the type of members_of_concept is [(concept,frequency)] members_of_concept = members(concept) membershipStrengths = {member:strength for (member, strength) in members_of_concept} result = [] for object in everything: membershipStrength = 0 if object in membershipStrengths: membershipStrength = membershipStrengths[object] nonMembershipStrength = 1 - membershipStrength result.append( (object,nonMembershipStrength) ) return result def evals(concept): template = T( 'EvaluationLink', concept, T('ListLink', new_var()) ) trees_tvs = match_wrapper(space, template, match_axiom) mems = [(tr.args[1].args[0], tv.mean) for (tr, tv) in trees_tvs] return mems # Find the members of each concept # For single-argument predicates, this is the same as EvaluationLinks. # TODO: can't handle negated predicates in EvaluationLinks... # This means PredicateNodes can't be in IntensionalInheritanceLinks if A.get_type() == t.NotLink: # Members of Not(A) assert B.get_type() == t.ConceptNode memA = non_members(A) memB = members(B) else: # Members of A memA = members(A) + evals(A) memB = members(B) + evals(B) # memA = evals(A) # memB = evals(B) print memA print print memB # calculate P(x in B | x in A) = P(A^B) / P(A) # based on the fuzzy-weighted average #nodes_in_B = [m for (m,s) in memB] assert not (memB is None) nodesB = {member:strength for (member,strength) in memB} N_AB = 0 for (mA, sA) in memA: if mA in nodesB: sB = nodesB[mA] # min is the definition of fuzzy-AND N_AB += min(sA,sB) #N_AB = sum(s for (m, s) in memA if m in nodes_in_B) N_A = sum(s for (m, s) in memA) if N_A > 0: P = N_AB*1.0 / N_A tv = TruthValue(P, confidence_to_count(1.0)) else: # If there are no items in A then conditional probability is not defined, so give a zero confidence tv = TruthValue(0,0) return [(target, tv)]
def rules(a, deduction_types): '''This function sets up all the Rules available in PLN. The concept of a Rule is the same as in higher-order logic. For example, Modus Ponens requires an ImplicationLink $1->$2 as well as the premise of the ImplicationLink ($1) and will produce $2. Every Rule comes with its own formula for calculating TruthValues. PLN works by applying a series of Rules to some Atoms to create new ones.''' # This function creates a list of Rules using the Rule constructor. # See the Rule class for more explanation of the arguments used. # In every step of chaining, the backward chainer has a target Atom (usually with some variables) # it is trying to find. It will apply any Rule whose head unifies with the target. # The function is called every time a Chainer is constructed. rules = [] #path_rules(a) # PLN is able to do pathfinding (experimental). In the Minecraft world, there is a 3D grid # similar to that used by A*. This Rule determines the grid squares (or rather grid cubes) # that are next to a specified grid cube (i.e. the neighborhood, in the A* sense). # You can represent the grid as a network of OpenCog links, which is more suitable for PLN # than having an array (and more versatile in general). # This version of the Rule calculates the neighborhood dynamically. The function path_rules() # uses the simpler but much slower approach of adding thousands of links to the AtomSpace in advance. r = Rule(T('EvaluationLink', a.add(t.PredicateNode,'neighbor'), T('ListLink', Var(1), # a ConceptNode representing the coordinates in a tacky format Var(2) )), [], name='Neighbors', match=match_neighbors) rules.append(r) #r = Rule(T('ImplicationLink', # Var(1), # Var(2) # ), # [], # name='Neighbors', # match=match_neighbors) #rules.append(r) # You can add a separate Rule for every axiom (i.e. every Atom which has a TruthValue when PLN starts). # It won't add a new Rule for atoms that are created during the inference, rather they will be added to # the Proof DAG. It's simple to have a separate Rule for each axiom, but it's slow because the chainer # will try to unify a target against every axiom Rule. #for obj in a.get_atoms_by_type(t.Atom): # # POLICY: Ignore all false things. This means you can never disprove something! But much more useful for planning! # if obj.tv.count > 0 and obj.tv.mean > 0: # tr = tree_from_atom(obj) # # A variable with a TV could just prove anything; that's evil! # if not tr.is_variable(): # # # tacky filter # if 'CHUNK' in str(tr): # continue # # r = Rule(tr, [], '[axiom]', tv = obj.tv) # rules.append(r) # Just lookup the rule rather than having separate rules. Would be faster # with a large number of atoms (i.e. more scalable). Some examples will break if # you use it due to bugs in the backward chainer. r = Rule(Var(123),[], name='Lookup', match=match_axiom_slow) rules.append(r) # A simple example Rule to test the mechanism. You're allowed to add a Rule which calls # any Python function to decide one of the Atoms. This one does the plus calculation. # The first two variables are the numbers to be added, and the third variable is the result. # i.e. the last variable is the return-value for the '+' function. This is a common pattern in # Prolog. r = Rule(T('EvaluationLink', a.add(t.PredicateNode,'+'), T('ListLink', Var(1), Var(2), Var(3))), [], name='PredicateEvaluation', match=match_predicate) rules.append(r) # The three main logical rules in PLN. The code creates different versions of the Rule # for different kinds of Links. # The classic Modus Ponens rule, used (and over-emphasized) in classical logic everywhere. for ty in ['ImplicationLink', 'PredictiveImplicationLink']: rules.append(Rule(Var(2), [T(ty, 1, 2), Var(1) ], name='ModusPonens '+ty, formula = formulas.modusPonensFormula)) # The PLN DeductionRule. Not to be confused with ModusPonens. for type in deduction_types: rules.append(Rule(T(type, 1,3), [T(type, 1, 2), T(type, 2, 3), Var(1), Var(2), Var(3)], name='Deduction', formula = formulas.deductionSimpleFormula)) # PLN InversionRule, which reverses an ImplicationLink. It's based on Bayes' Theorem. for type in deduction_types: rules.append(Rule( T(type, 2, 1), [T(type, 1, 2), Var(1), Var(2)], name='Inversion', formula = formulas.inversionFormula)) # Calculating logical And/Or/Not. These have probabilities attached, # but they work similarly to the Boolean versions. type = 'AndLink' for size in xrange(5): args = [new_var() for i in xrange(size+1)] rules.append(Rule(T(type, args), args, type[:-4], formula = formulas.andSymmetricFormula)) type = 'OrLink' for size in xrange(1,2): args = [new_var() for i in xrange(size+1)] rules.append(Rule(T(type, args), args, type[:-4], formula = formulas.orFormula)) # Calculate (NotLink A) using A. There's currently no Rule to find A using (NotLink A) rules.append(Rule(T('NotLink', 1), [ Var(1) ], name = 'Not', formula = formulas.notFormula)) # PLN's heuristic Rules to convert one kind of link to another. There are other # variations on this Rule defined in the PLN book, but not implemented yet. rules.append(Rule(T('InheritanceLink', 1, 2), [ T('SubsetLink', 1, 2) ], name = 'SubsetLink=>InheritanceLink', formula = formulas.ext2InhFormula)) # Used by planning. An ExecutionLink indicates an action being performed, so we can # assume that the action will be performed as part of the plan (i.e. if any action # occurs in the plan, set the TV to full probability and confidence). #r = Rule(T('ExecutionLink', 1, 2), # [], # name = 'PerformAction', # tv = TruthValue(1.0,confidence_to_count(1.0))) #rules.append(r) # TOdo this should be actionSuccess not just actionDone r = Rule(actionDone_template(a), [], name = 'PerformAction', tv = TruthValue(1.0,confidence_to_count(1.0))) rules.append(r) # If something is true at the current time, you can use it as the start of the plan. # First find the latest time (hack) current_time = 0 for time in a.get_atoms_by_type(t.TimeNode): timestamp = int(time.name) if timestamp > current_time: current_time = timestamp current_time_node = a.add(t.TimeNode, str(current_time)) # Then create the Rule # It's essential to store the template so it will have the same variables in both # the head and the goal template = evaluation_link_template() r = Rule(template, [T('AtTimeLink', current_time_node, template)], name = 'AtCurrentTime' ) rules.append(r) # # Producing ForAll/Bind/AverageLinks. # for type in ['ForAllLink', 'BindLink', 'AverageLink']: # rules.append(Rule(T(type, 1, 2), # [ Var(2) ], # name = type+' abstraction', # formula = formulas.identityFormula)) # This may cause weirdness with things matching too eagerly... # # Both of these rely on the policy that tree_from_atom replaces VariableNodes in the AtomSpace with the variables the tree class uses. # fact = new_var() # list_link = new_var() # r = Rule( # fact, # [T('ForAllLink', list_link, fact )], # name = 'ForAll' # ) # r.tv = True # rules.append(r) # If an Atom is available in an Average/ForAll quantifier, you want to be # able to produce the Atom itself and send it through the other steps of the # inference. for atom in a.get_atoms_by_type(t.AverageLink): # out[0] is the ListLink of VariableNodes, out[1] is the expression tr = tree_from_atom(atom.out[1]) r = Rule(tr, [], name='Average') r.tv = atom.tv rules.append(r) for atom in a.get_atoms_by_type(t.ForAllLink): # out[0] is the ListLink of VariableNodes, out[1] is the expression tr = tree_from_atom(atom.out[1]) r = Rule(tr, [], name='ForAll') r.tv = atom.tv rules.append(r) rules += temporal_rules(a) # Return every Rule specified above. return rules