sums,
products,and
variableswithout worrying about how these are to be represented. Only afterward will we address the representation problem.
| is_variable(e) |
Is e a variable?
|
| is_same_variable(v1, v2) |
Are v1 and
v2 the same variable?
|
| is_sum(e) |
Is e a sum?
|
| addend(e) |
Addend of the sum e.
|
| augend(e) |
Augend of the sum e.
|
| make_sum(a1, a2) |
Construct the sum of a1 and
a2.
|
| is_product(e) |
Is e a product?
|
| multiplier(e) |
Multiplier of the product e.
|
| multiplicand(e) |
Multiplicand of the product e.
|
| make_product(m1, m2) |
Construct the product of m1 and
m2.
|
function deriv(exp, variable) {
return is_number(exp)
? 0
: is_variable(exp)
? is_same_variable(exp, variable) ? 1 : 0
: is_sum(exp)
? make_sum(deriv(addend(exp), variable),
deriv(augend(exp), variable))
: is_product(exp)
? make_sum(make_product(multiplier(exp),
deriv(multiplicand(exp),
variable)),
make_product(deriv(multiplier(exp),
variable),
multiplicand(exp)))
: error(exp, "unknown expression type -- deriv");
}
function is_variable(x) { return is_string(x); }
function is_same_variable(v1, v2) {
return is_variable(v1) && is_variable(v2) && v1 === v2;
}
function make_sum(a1, a2) { return list("+", a1, a2); }
function make_product(m1, m2) { return list("*", m1, m2); }
function is_sum(x) {
return is_pair(x) && head(x) === "+";
}
function addend(s) { return head(tail(s)); }
function augend(s) { return head(tail(tail(s))); }
function is_product(x) {
return is_pair(x) && head(x) === "*";
}
function multiplier(s) { return head(tail(s)); }
function multiplicand(s) { return head(tail(tail(s))); }
deriv(list("+", "x", 3), "x");
list("+", 1, 0)deriv(list("*", "x", "y"), "x");
list("+", list("*", "x", 0), list("*", 1, "y"))deriv(list("*", list("*", "x", "y"), list("+", "x", 3)), "x");
list("+", list("*", list("*", "x", "y"), list("+", 1, 0)),
list("*", list("+", list("*", "x", 0), list("*", 1, "y")),
list("+", "x", 3)))
function make_sum(a1, a2) {
return number_equal(a1, 0)
? a2
: number_equal(a2, 0)
? a1
: is_number(a1) && is_number(a2)
? a1 + a2
: list("+", a1, a2);
}
function number_equal(exp, num) {
return is_number(exp) && exp === num;
}
function make_product(m1, m2) {
return number_equal(m1, 0) || number_equal(m2, 0)
? 0
: number_equal(m1, 1)
? m2
: number_equal(m2, 1)
? m1
: is_number(m1) && is_number(m2)
? m1 * m2
: list("*", m1, m2);
}
deriv(list("+", "x", 3), "x");
1
deriv(list("*", "x", "y"), "x");
"y"
deriv(list("*", list("*", "x", "y"), list("+", "x", 3)), "x");
list("+", list("*", "x", "y"), list("*", "y", list("+", "x", 3)))simplest.The problem of algebraic simplification is complex because, among other reasons, a form that may be simplest for one purpose may not be for another.
function base(e) {
return head(tail(e));
}
function exponent(e) {
return head(tail(tail(e)));
}
function make_exp(base, exp) {
return number_equal(exp, 0)
? 1
: number_equal(exp, 1)
? base
: list("**", base, exp);
}
function is_exp(x) {
return is_pair(x) && head(x) === "**";
}
function deriv(exp, variable) {
return is_number(exp)
? 0
: is_variable(exp)
? (is_same_variable(exp, variable) ? 1 : 0)
: is_sum(exp)
? make_sum(deriv(addend(exp), variable),
deriv(augend(exp), variable))
: is_product(exp)
? make_sum(make_product(multiplier(exp),
deriv(multiplicand(exp),
variable)),
make_product(deriv(multiplier(exp),
variable),
multiplicand(exp)))
: is_exp(exp)
? make_product(make_product(exponent(exp),
make_exp(
base(exp),
exponent(exp) - 1)),
deriv(base(exp), variable))
: error(exp, "unknown expression type -- deriv");
}
deriv(list("*", "x", "y", list("+", "x", 3)), "x");
function augend(s) {
return accumulate(make_sum, 0, tail(tail(s)));
}
function multiplicand(s) {
return accumulate(make_product, 1, tail(tail(s)));
}
list("x", "+", list(3, "*", list("x", "+", list("y", "+", 2))))
list("x", "+", 3, "*", list("x", "+", "y", "+", 2))function make_sum(a1, a2) {
return number_equal(a1, 0)
? a2
: number_equal(a2, 0)
? a1
: is_number(a1) && is_number(a2)
? a1 + a2
: list(a1, "+", a2);
}
function is_sum(x) {
return is_pair(x) && head(tail(x)) === "+";
}
function addend(s) {
return head(s);
}
function augend(s) {
return head(tail(tail(s)));
}
function make_product(m1, m2) {
return number_equal(m1, 0) || number_equal(m2, 0)
? 0
: number_equal(m1, 1)
? m2
: number_equal(m2, 1)
? m1
: is_number(m1) && is_number(m2)
? m1 * m2
: list(m1, "*", m2);
}
function is_product(x) {
return is_pair(x) && head(tail(x)) === "*";
}
function multiplier(s) {
return head(s);
}
function multiplicand(s) {
return head(tail(tail(s)));
}
function deriv(exp, variable) {
return is_number(exp)
? 0
: is_variable(exp)
? (is_same_variable(exp, variable) ? 1 : 0)
: is_sum(exp)
? make_sum(deriv(addend(exp), variable),
deriv(augend(exp), variable))
: is_product(exp)
? make_sum(make_product(multiplier(exp),
deriv(multiplicand(exp),
variable)),
make_product(deriv(multiplier(
exp),
variable),
multiplicand(exp)))
: error(exp, "unknown expression type -- deriv");
}
function items_before_first(op, s) {
return is_string(head(s)) && head(s) === op
? null
: pair(head(s),
items_before_first(op, tail(s)));
}
function items_after_first(op, s) {
return is_string(head(s)) && head(s) === op
? tail(s)
: items_after_first(op, tail(s));
}
function simplify_unary_list(s) {
return is_pair(s) && is_null(tail(s))
? head(s)
: s;
}
function contains_plus(s) {
return is_null(s)
? false
: is_string(head(s)) && head(s) === "+"
? true
: contains_plus(tail(s));
}
function make_sum(a1, a2) {
return number_equal(a1, 0)
? a2
: number_equal(a2, 0)
? a1
: is_number(a1) && is_number(a2)
? a1 + a2
: list(a1, "+", a2);
}
// a sequence of terms and operators is a sum
// if and only if at least one + operator occurs
function is_sum(x) {
return is_pair(x) && contains_plus(x);
}
function addend(s) {
return simplify_unary_list(items_before_first("+", s));
}
function augend(s) {
return simplify_unary_list(items_after_first("+", s));
}
function make_product(m1, m2) {
return number_equal(m1, 0) || number_equal(m2, 0)
? 0
: number_equal(m1, 1)
? m2
: number_equal(m2, 1)
? m1
: is_number(m1) && is_number(m2)
? m1 * m2
: list(m1, "*", m2);
}
// a sequence of terms and operators is a product
// if and only if no + operator occurs
function is_product(x) {
return is_pair(x) && ! contains_plus(x);
}
function multiplier(s) {
return simplify_unary_list(items_before_first("*", s));
}
function multiplicand(s) {
return simplify_unary_list(items_after_first("*", s));
}
function deriv(exp, variable) {
return is_number(exp)
? 0
: is_variable(exp)
? (is_same_variable(exp, variable) ? 1 : 0)
: is_sum(exp)
? make_sum(deriv(addend(exp), variable),
deriv(augend(exp), variable))
: is_product(exp)
? make_sum(make_product(multiplier(exp),
deriv(multiplicand(exp),
variable)),
make_product(deriv(multiplier(exp),
variable),
multiplicand(exp)))
: error(exp, "unknown expression type -- deriv");
}