Solver

Introduction

One of the most important features of the Brain4it language is homoiconicity, which means that code and data are represented in the same way. Homoiconicity allows a program to manage code as easily as it manages data, so it can create or modify other programs or even change itself at runtime.

This module takes advantage of this feature to implement a transformation rule engine to solve mathematical equations algebraically.

How it works?

The rules variable contains a list of transformation rules with this format:

(...
  "<rule_name>" =>
  (
    "<rule_description>"
    <matching_expression>
    <apply_condition>
    <replacing_expression>
  )
  ...
)

Where:

Examples:

(...
  "rule6" =>
  (
    "Redundant negative operator"
    (- (- x?))
    true
    x?
  )
  ...
  "rule7" =>
  (
    "Join sum operators"
    (+ a... (+ b...) c...)
    true
    (+ a... b... c...)
  )
  ...
  "rule10" =>
  (
    "Sum numbers"
    (+ a... x? b... y? c...)
    (if
      (and
        (= (type-of x?) "number")
        (= (type-of y?) "number")
      )
      (do
        (set match_map$/res (+ x? y?))
        true
      )
      false
    )
    (+ res a... b... c...)
  )
  ...
  "rule16" =>
  (
    "Sum element twice"
    (+ a... x? b... x? c...)
    true
    (+ a... b... c... (* 2 x?))
  )
  ...
  "rule28" =>
  (
    "Sort variables lexicografically"
    (fn? a... x? y? b...)
    (and
      (or (= fn? +) (= fn? *))
      (= (type-of x?) "reference")
      (= (type-of y?) "reference")
      (> (string x?) (string y?))
    )
    (fn? a... y? x? b...)
  )
  ...
)

Usually, these transformation rules try to reduce or simplify the input expression.

The transformation engine is implemented by the apply_rules and apply_rule functions, that successively apply the rules of transformation on the input expression until it can no longer be transformed.

This module offers 4 functions to transform (reduce) a mathematical expression:

Examples:

(reduceq (* (+ 3 x) (* 2 x)))
(+ (* 2 (pow x 2)) (* 6 x))
(reduceqt (* (+ 3 x) (* 2 x)))
(
  (* (+ 3 x) (* 2 x))
  "Join product operators"
  (* (+ 3 x) 2 x)
  "Multiply sum terms (right)"
  (* (+ (* 2 3) (* 2 (+ x))) x)
  "Redundant sum operator"
  (* (+ (* 2 3) (* 2 x)) x)
  "Multiply numbers"
  (* (+ (* 6) (* 2 x)) x)
  "Redundant product operator"
  (* (+ 6 (* 2 x)) x)
  "Multiply sum terms (right)"
  (* (+ (* x 6) (* x (+ (* 2 x)))))
  "Redundant sum operator"
  (* (+ (* x 6) (* x (* 2 x))))
  "Redundant product operator"
  (+ (* x 6) (* x (* 2 x)))
  "Join product operators"
  (+ (* x 6) (* x 2 x))
  "Multiply element by itself"
  (+ (* x 6) (* 2 (pow x 2)))
  "Put number in front of expression in multiply"
  (+ (* 6 x) (* 2 (pow x 2)))
  "Sort terms by power (1 power)"
  (+ (* 2 (pow x 2)) (* 6 x))
)

Solving an equation is a particular case of reduction. For example, if we want to solve this equation:

2 * x + b = 7

Then we should type this command:

(reduceq (solve x (+ (* 2 x) b) 7))
(solved x (+ (* -0.5 b) 3.5))
Download module
Top