Backward chainer takes super long in this case
alexander-gabriel opened this issue · 3 comments
The Backward Chainer takes over 4 seconds in this scenarios with only 10 waypoints. This time increases only marginally with 100 or 200 waypoints.
To run this, you need to create a 9-fold fuzzy and in the pln/opencog/pln/rules/propositional/fuzzy-conjunction-introduction.scm
file and adjust the path to the file in the script.
#!/usr/bin/env python
import time
from opencog.type_constructors import *
from opencog.bindlink import execute_atom, evaluate_atom
from opencog.ure import BackwardChainer, ForwardChainer
from opencog.utilities import initialize_opencog
from opencog.atomspace import AtomSpace, types, TruthValue, create_child_atomspace
from opencog.logger import create_logger, Logger,log
from opencog.scheme_wrapper import scheme_eval
TRUE = TruthValue(1.0, 1.0)
def identical_formula(A, B):
# rospy.loginfo("identical_formula({},{})".format(A,B))
link = IdenticalLink(A,B)
# out = A.get_out()
if A == B:
link.tv = TruthValue(1, 1)
else:
link.tv = TruthValue(0, 1)
return link
def build_deduction_rulebase():
rbs = ConceptNode("deduction-rule-base")
execute_code = \
'''
(use-modules (opencog))
(use-modules (opencog logger) (opencog ure) (opencog exec))
(load-from-path "/home/rasberry/git/pln/opencog/pln/rules/propositional/fuzzy-conjunction-introduction.scm")
(define rbs (Concept "deduction-rule-base"))
(ure-set-complexity-penalty rbs 0.1)
'''
scheme_eval(atomspace, execute_code)
MemberLink(DefinedSchemaNode("fuzzy-conjunction-introduction-9ary-rule"), rbs)
return rbs
def print_results(query,results):
print("Query:\n{:}\n\nResults:\n{:}\n\nDetails:\n--------".format(query, results))
if query.type_name == "GetLink":
for setlink in results.get_out():
for result in setlink.get_out():
print("Result Truth: {:}".format(result.tv))
print("Result:\n{:}".format(result))
print("------------------------\n")
elif query.type_name == "AndLink":
for result in results.get_out():
print("Result Truth: {:}".format(result.tv))
print("Result:\n{:}".format(result))
for condition in result.get_out():
print("------------------------")
print("Condition:{:}".format(condition))
print("Condition Truth: {:}".format(condition.tv))
if condition.type_name == "NotLink":
subcondition = condition.get_out()[0]
print(" Subcondition: {:}".format(subcondition))
print(" Subcondition Truth: {:}".format(subcondition.tv))
print("-----------------------------------------------------")
else:
for result in results.get_out():
print("Result Truth: {:}".format(result.tv))
print("Result:\n{:}".format(result))
print("------------------------\n")
if __name__ == '__main__':
atomspace = AtomSpace()
initialize_opencog(atomspace)
rbs = build_deduction_rulebase()
for index in range(1,10,1):
odd = "wp_{:d}".format(index)
even = "wp_{:d}".format(index+1)
o = ConceptNode(odd).truth_value(1.0, 1.0)
e = ConceptNode(even).truth_value(1.0, 1.0)
# print("creating link {}<->{}".format(o,e))
EvaluationLink(PredicateNode("leads_to"), ListLink(o, e)).truth_value(1.0, 1.0)
EvaluationLink(PredicateNode("leads_to"), ListLink(e, o)).truth_value(1.0, 1.0)
wp5 = ConceptNode("wp_5")
wp6 = ConceptNode("wp_6")
true = ConceptNode("true").truth_value(1.0, 1.0)
false = ConceptNode("false").truth_value(1.0, 1.0)
seen_picking = ConceptNode("seen_picking").truth_value(1.0, 1.0)
called_robot = ConceptNode("called_robot").truth_value(1.0, 1.0)
approaching = ConceptNode("approaching").truth_value(1.0, 1.0)
movement = ConceptNode("movement").truth_value(1.0, 1.0)
human = ConceptNode("human").truth_value(1.0, 1.0)
alice = ConceptNode("alice").truth_value(1.0, 1.0)
InheritanceLink(alice, human).truth_value(1.0, 1.0)
StateLink(alice, wp5).truth_value(1.0, 1.0)
StateLink(ListLink(alice, seen_picking), false).truth_value(1.0, 1.0)
StateLink(ListLink(alice, called_robot), false).truth_value(1.0, 1.0)
StateLink(ListLink(alice, movement), approaching)
robot = ConceptNode("bob").truth_value(1.0, 1.0)
StateLink(robot, wp6).truth_value(1.0, 1.0)
variables = VariableList(
TypedVariableLink(VariableNode("person"), TypeNode("ConceptNode")),
TypedVariableLink(VariableNode("person_location"), TypeNode("ConceptNode")),
TypedVariableLink(VariableNode("origin"), TypeNode("ConceptNode")),
TypedVariableLink(VariableNode("destination"), TypeNode("ConceptNode")),
TypedVariableLink(VariableNode("nobody"), TypeNode("ConceptNode"))
)
query = AndLink(
InheritanceLink(VariableNode("person"), human),
StateLink(VariableNode("person"), VariableNode("person_location")),
StateLink(ListLink(VariableNode("person"), movement), approaching),
StateLink(robot, VariableNode("origin")),
StateLink(ListLink(VariableNode("person"), seen_picking), false),
StateLink(ListLink(VariableNode("person"), called_robot), false),
EvaluationLink(
PredicateNode("leads_to"),
ListLink(VariableNode("person_location"), VariableNode("origin"))
),
EvaluationLink(
PredicateNode("leads_to"),
ListLink(VariableNode("origin"), VariableNode("destination"))
),
AbsentLink(
StateLink(VariableNode("nobody"), VariableNode("destination"))
)
)
start_time = time.time()
# query = GetLink(variables, query)
chainer = BackwardChainer(_as=atomspace,
rbs=rbs, trace_as=None, control_as=None, focus_set=None,
target=query, vardecl=variables)
chainer.do_chain()
print("The BackwardChainer took {:.2f}\n--------------".format(time.time()-start_time))
results = chainer.get_results()
print_results(query, results)
To make this more clear: there is only one rule involved which has to be applied only once. And there are only 21 concepts and about 30 links
@alexander-gabriel, I think the problem is with unification that tries all permutations since And is unordered.
Sidenote: you no longer need to generate multiple rules for multiple arities since Glob is now supported by the URE. I (or someone else) need(s) to update these rules...
If you could attach the log file (with debug or fine level) that would be helpful.
I'm closing, would rather have a simpler more narrowed issue for this problem.