Examples & Tutorials

Comprehensive examples demonstrating Symmetrica's capabilities.

New! Check out our Complete Examples Catalog with all 13 runnable examples, source code links, and detailed instructions.

Building Expressions

Basic Operations

use expr_core::Store;

let mut st = Store::new();
let x = st.sym("x");
let y = st.sym("y");

// Addition
let sum = st.add(vec![x, y, st.int(5)]);
println!("{}", st.to_string(sum));  // 5 + x + y

// Multiplication
let product = st.mul(vec![st.int(2), x, y]);
println!("{}", st.to_string(product));  // 2 * x * y

// Power
let squared = st.pow(x, st.int(2));
println!("{}", st.to_string(squared));  // x^2

// Rational numbers
let half = st.rat(1, 2);
let expr = st.mul(vec![half, x]);
println!("{}", st.to_string(expr));  // 1/2 * x

Nested Expressions

// Build (x + 1)² * (y - 2)
let x_plus_1 = st.add(vec![x, st.int(1)]);
let squared = st.pow(x_plus_1, st.int(2));
let y_minus_2 = st.add(vec![y, st.int(-2)]);
let result = st.mul(vec![squared, y_minus_2]);

println!("{}", st.to_string(result));
// (1 + x)^2 * (-2 + y)

Functions

// Trigonometric functions
let sin_x = st.func("sin", vec![x]);
let cos_x = st.func("cos", vec![x]);

// Exponential and logarithm
let exp_x = st.func("exp", vec![x]);
let ln_x = st.func("ln", vec![x]);

// Composition
let sin_squared = st.pow(st.func("sin", vec![x]), st.int(2));
println!("{}", st.to_string(sin_squared));
// sin(x)^2

Simplification

Like Terms

use simplify::simplify;

// Collect like terms
let expr = st.add(vec![x, x, x]);
let result = simplify(&mut st, expr);
println!("{}", st.to_string(result));  // 3 * x

// Combine powers
let expr = st.mul(vec![
    st.pow(x, st.int(2)),
    st.pow(x, st.int(3))
]);
let result = simplify(&mut st, expr);
println!("{}", st.to_string(result));  // x^5

Logarithm Rules

use assumptions::{Context, Prop};

let mut ctx = Context::new();
ctx.assume("x", Prop::Positive);
ctx.assume("y", Prop::Positive);

// ln(x * y) → ln(x) + ln(y)
let product = st.mul(vec![x, y]);
let ln_product = st.func("ln", vec![product]);
let result = simplify_with(&mut st, ln_product, &ctx);
println!("{}", st.to_string(result));
// ln(x) + ln(y)

Trigonometric Identities

// exp(ln(x)) → x (with positive assumption)
ctx.assume("x", Prop::Positive);
let ln_x = st.func("ln", vec![x]);
let exp_ln = st.func("exp", vec![ln_x]);
let result = simplify_with(&mut st, exp_ln, &ctx);
println!("{}", st.to_string(result));  // x

Substitution

Symbol Substitution

use pattern::subst_symbol;

// Substitute x → 2y + 1 in x² + 3x
let expr = st.add(vec![
    st.pow(x, st.int(2)),
    st.mul(vec![st.int(3), x])
]);

let two_y_plus_1 = st.add(vec![
    st.mul(vec![st.int(2), y]),
    st.int(1)
]);

let result = subst_symbol(&mut st, expr, "x", two_y_plus_1);
let simplified = simplify(&mut st, result);
println!("{}", st.to_string(simplified));
// 1 + 8 * y + 6 * y^2 + 4 * y^2

Function Composition

// f(x) = x², g(x) = x + 1
// Compute f(g(x))
let f = st.pow(x, st.int(2));
let g = st.add(vec![x, st.int(1)]);
let composition = subst_symbol(&mut st, f, "x", g);
println!("{}", st.to_string(composition));
// (1 + x)^2

Differentiation

Basic Derivatives

use calculus::diff;

// d/dx (x³ + 2x² + x + 1)
let expr = st.add(vec![
    st.pow(x, st.int(3)),
    st.mul(vec![st.int(2), st.pow(x, st.int(2))]),
    x,
    st.int(1)
]);

let derivative = diff(&mut st, expr, "x");
let result = simplify(&mut st, derivative);
println!("{}", st.to_string(result));
// 1 + 4 * x + 3 * x^2

Chain Rule

// d/dx sin(x²)
let x_squared = st.pow(x, st.int(2));
let expr = st.func("sin", vec![x_squared]);
let derivative = diff(&mut st, expr, "x");
println!("{}", st.to_string(derivative));
// cos(x^2) * 2 * x

Product Rule

// d/dx (x² * sin(x))
let x_squared = st.pow(x, st.int(2));
let sin_x = st.func("sin", vec![x]);
let expr = st.mul(vec![x_squared, sin_x]);
let derivative = diff(&mut st, expr, "x");
let result = simplify(&mut st, derivative);
println!("{}", st.to_string(result));

Integration

Power Rule

use calculus::integrate;

// ∫ x² dx
let expr = st.pow(x, st.int(2));
let integral = integrate(&mut st, expr, "x").unwrap();
println!("{}", st.to_string(integral));
// 1/3 * x^3

// ∫ 1/x dx
let inv_x = st.pow(x, st.int(-1));
let integral = integrate(&mut st, inv_x, "x").unwrap();
println!("{}", st.to_string(integral));
// ln(x)

Trigonometric Integrals

// ∫ sin(x) dx
let expr = st.func("sin", vec![x]);
let integral = integrate(&mut st, expr, "x").unwrap();
println!("{}", st.to_string(integral));
// -cos(x)

// ∫ sin(2x) dx
let two_x = st.mul(vec![st.int(2), x]);
let expr = st.func("sin", vec![two_x]);
let integral = integrate(&mut st, expr, "x").unwrap();
println!("{}", st.to_string(integral));
// -1/2 * cos(2 * x)

Integration by Parts

// ∫ x * ln(x) dx
let ln_x = st.func("ln", vec![x]);
let expr = st.mul(vec![x, ln_x]);
let integral = integrate(&mut st, expr, "x").unwrap();
let result = simplify(&mut st, integral);
println!("{}", st.to_string(result));

Series Expansion

use calculus::maclaurin;

// Taylor series for exp(x) at 0
let expr = st.func("exp", vec![x]);
let series = maclaurin(&st, expr, "x", 5).unwrap();

// Print coefficients
for (k, (n, d)) in series.coeffs.iter().enumerate() {
    if *n != 0 {
        if *d == 1 {
            println!("x^{}: {}", k, n);
        } else {
            println!("x^{}: {}/{}", k, n, d);
        }
    }
}
// x^0: 1
// x^1: 1
// x^2: 1/2
// x^3: 1/6
// x^4: 1/24
// x^5: 1/120

Polynomial Operations

Factorization

use polys::factor;

// Factor x² - 1
let expr = st.add(vec![
    st.pow(x, st.int(2)),
    st.int(-1)
]);

let factors = factor(&st, expr, "x").unwrap();
for factor in factors {
    println!("{}", st.to_string(factor));
}
// (x - 1) * (x + 1)

Partial Fractions

use polys::partial_fractions_simple;

// Decompose (2x + 3) / (x² + 3x + 2)
let num = st.add(vec![st.mul(vec![st.int(2), x]), st.int(3)]);
let den = st.add(vec![
    st.pow(x, st.int(2)),
    st.mul(vec![st.int(3), x]),
    st.int(2)
]);

let result = partial_fractions_simple(&mut st, num, den, "x").unwrap();
println!("{}", st.to_string(result));

Equation Solving

Quadratic Equations

use solver::solve_univariate;

// Solve x² - 5x + 6 = 0
let eq = st.add(vec![
    st.pow(x, st.int(2)),
    st.mul(vec![st.int(-5), x]),
    st.int(6)
]);

let roots = solve_univariate(&mut st, eq, "x").unwrap();
for root in roots {
    println!("x = {}", st.to_string(root));
}
// x = 2, x = 3

Cubic Equations

// Solve x³ - 6x² + 11x - 6 = 0
let eq = st.add(vec![
    st.pow(x, st.int(3)),
    st.mul(vec![st.int(-6), st.pow(x, st.int(2))]),
    st.mul(vec![st.int(11), x]),
    st.int(-6)
]);

let roots = solve_univariate(&mut st, eq, "x").unwrap();
for root in roots {
    println!("x = {}", st.to_string(root));
}
// x = 1, x = 2, x = 3

Matrix Operations

use matrix::{Matrix, determinant, solve_system};

// Create a 2×2 matrix
let mat = Matrix::from_rows(vec![
    vec![st.int(2), st.int(1)],
    vec![st.int(1), st.int(3)]
]);

// Compute determinant
let det = determinant(&mut st, &mat);
println!("det = {}", st.to_string(det));  // 5

// Solve Ax = b
let b = vec![st.int(5), st.int(6)];
let solution = solve_system(&mut st, &mat, &b).unwrap();
for (i, val) in solution.iter().enumerate() {
    println!("x_{} = {}", i, st.to_string(*val));
}

Pattern Matching

use pattern::ac::{match_expr, Pat};
use std::collections::HashMap;

// Pattern: x + ?a
let pattern = Pat::Add(vec![
    Pat::Symbol("x".into()),
    Pat::Any("a".into())
]);

// Expression: x + 5
let expr = st.add(vec![x, st.int(5)]);

// Match
if let Some(bindings) = match_expr(&st, &pattern, expr) {
    let a_value = bindings.get("a").unwrap();
    println!("Matched! a = {}", st.to_string(*a_value));
}

Domain-Aware Simplification

use assumptions::{Context, Prop};
use simplify::simplify_with;

let mut ctx = Context::new();
ctx.assume("x", Prop::Positive);

// √(x²) with x > 0
let x_squared = st.pow(x, st.int(2));
let sqrt = st.pow(x_squared, st.rat(1, 2));
let result = simplify_with(&mut st, sqrt, &ctx);
println!("{}", st.to_string(result));  // x

// Without assumption (real but sign unknown)
ctx = Context::new();
ctx.assume("x", Prop::Real);
let result = simplify_with(&mut st, sqrt, &ctx);
println!("{}", st.to_string(result));  // abs(x)

Piecewise Functions

// Define absolute value: |x| = piecewise((x >= 0, x), (else, -x))
let zero = st.int(0);
let cond = st.func(">=", vec![x, zero]);
let neg_x = st.mul(vec![st.int(-1), x]);
let else_cond = st.func("else", vec![]);

let abs_x = st.piecewise(vec![(cond, x), (else_cond, neg_x)]);

// Simplify with True condition
let true_cond = st.func("True", vec![]);
let pw = st.piecewise(vec![(true_cond, x)]);
let result = simplify(&mut st, pw);
println!("{}", st.to_string(result));  // x (collapsed)
Tip: All examples are available in the examples directory of the repository. You can run them with cargo run --example example_name.