Linear Equation Solver ====================== You can use defworld library not only for interactive storytelling, but also for rule-based application. In this example, I explain how to build a linear equation solver using defworld. A linear equation is an equation in which each term is either a constant or the product of a constant and a single variable, e.g. 2x + 3 = 5. Solving methods are quite easy: subtract a same number from both side or divide both side by a same number repeatedly until the unknown remains solely on left side and a constant on right side. Terminal condition ^^^^^^^^^^^^^^^^^^ Let's define the terminal condition, first. :: Rule('x = b', [ Not(solution()), # not yet solved equation(x, b) # x = b ],[ solved(b) # the solution is b ]), ``solution`` is a :class:`defworld.patterns.Template` for the solution, defined by the following:: solution = Template('solution', Entity) ``equation`` is a :class:`defworld.patterns.Template` for an :class:`defworld.patterns.Entity` represents the equation. :: equation = Template('equation', Entity) ``solved`` is also a function returns an :class:`defworld.patterns.Entity`. :: @Func def solved(x): print x.value return solution(value=x) This function is called when the rule 'x = b' is fired. That's why ``solved`` is decorated by :class:`defworld.patterns.Func`. To sum up, the 'x = b' rule is fired when the equation is not yet solved and is in the form of 'x = b'. Once the rule is fired, the solution is appended on the agent's working memory and printed out. Subtracting a same number from both side ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If there is an equation *x + 2 = 5*, you just subtract 2 from both side to solve this equation. In this section, I show you how to implement this rule. :: Rule('expr + a = b', [ Not(solution()), # not yet solved equation(add(expr, a), b) # expr + a = b ],[ equation(expr, Sub(b, a)) # expr = b - a ]), That's it. ``add`` is a function returns a :class:`defworld.patterns.Fact` represents addition, defined by the following:: add = Template('add') ``Sub`` is a function decorated by :class:`defworld.patterns.Func` which returns the difference between two value. Full source code ^^^^^^^^^^^^^^^^ This is the full source code. :: from defworld.agent import Agent from defworld.basic import Var from defworld.patterns import Entity, Func, Not, Rule, Template if __name__ == '__main__': solution = Template('solution', Entity) a = Var('a') b = Var('b') expr = Var('expr') x = Entity('unknown') product = Template('product') add = Template('add') equation = Template('equation', Entity) @Func def Div(a, b): return a/b @Func def Sub(a, b): return a-b @Func def solved(x): print x.value return solution(x) agent = Agent([ equation(add(product(2,x), 3), 5) # 2x + 3 = 5 ],[ Rule('x = b', [ Not(solution()), # not yet solved equation(x, b) # x = b ],[ solved(b) # the solution is b ]), Rule('a * expr = b', [ Not(solution()), # not yet solved equation(product(a, expr), b) # a * expr = b ],[ equation(expr, Div(b, a)) # expr = b / a ]), Rule('expr + a = b', [ Not(solution()), # not yet solved equation(add(expr, a), b) # expr + a = b ],[ equation(expr, Sub(b, a)) # expr = b - a ]), ]) agent.match() agent.run() # print 1