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 defworld.patterns.Template for the solution, defined by the following:

solution = Template('solution', Entity)

equation is a defworld.patterns.Template for an defworld.patterns.Entity represents the equation.

equation = Template('equation', Entity)

solved is also a function returns an 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 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 defworld.patterns.Fact represents addition, defined by the following:

add = Template('add')

Sub is a function decorated by 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

Project Versions

Table Of Contents

Previous topic

Examples

This Page