The Mħπ rules system provides a flexible and extensible way to define and apply mathematical transformations. This system is at the core of the symbolic computation engine, allowing for everything from basic algebraic simplification to complex operations specific to mathematical physics.
Rules are defined to match specific patterns in an expression and then apply a transformation. This allows for a declarative style of programming where the mathematical properties of the system are expressed as a set of rules.
The following is a list of the rules that have been implemented in the new system so far, categorized by their domain.
src/rules/algebraic.rs
)These rules define fundamental algebraic properties of operations.
AdditiveIdentityRule
: a + 0 → a
MultiplicativeIdentityRule
: a * 1 → a
MultiplicativeZeroRule
: a * 0 → 0
PowerOfOneRule
: a^1 → a
PowerOfZeroRule
: a^0 → 1
PowerOfPowerRule
: (a^b)^c → a^(b*c)
CombineLikeTermsRule
: Combines like terms in sums (2x + 3x → 5x
) and products (x^2 * x^3 → x^5
). This is a key canonicalization rule.DistributeMulOverAddRule
: Expands products over sums: a*(b+c) → a*b + a*c
. (Expansion pass only).DistributeNegativeRule
: A safe, canonicalizing distribution: -(a+b) -> -a-b
.FactorCommonTermsRule
: Factors out common terms: a*b + a*c → a*(b+c)
. (Factoring pass only).SimplifyRationalRule
: Simplifies rational numbers to their lowest terms.ImaginaryPowerRule
: Simplifies powers of i
, e.g., i^2 → -1
, i^3 → -i
.DistributePowerOverMulRule
: Distributes powers over products: (a*b)^n → a^n * b^n
.src/rules/evaluative.rs
)These rules compute definite numeric results from expressions.
FactorialRule
: Evaluates factorials of non-negative integers: 3! → 6
.GammaRule
: Evaluates the Gamma function for positive integers: Γ(4) → 3! → 6
.EvaluateBuiltinFunctionsRule
: Evaluates built-in functions at special points: sin(0) → 0
, ln(1) → 0
.EvaluateNumericExpressionsRule
: Pre-calculates purely numeric sub-expressions: 2+3 → 5
, (3/2)^2 → 9/4
.src/rules/calculus.rs
)DerivativeRule
: Evaluates Derivative
expressions by applying the rules of differentiation.IntegralRule
: Evaluates Integral
expressions by applying known integration rules.src/rules/trigonometric.rs
)PythagoreanIdentityRule
: sin²(x) + cos²(x) → 1
.EulerIdentityRule
: e^(i*π) → -1
. (Expansion pass only).LogExpIdentityRule
: ln(e^x) → x
and e^(ln(x)) → x
.CanonicalizeExpRule
: Converts exp(x)
to its canonical form e^x
to allow power-based rules to apply consistently.src/rules/quantum.rs
, src/rules/gauge.rs
)These rules are specific to quantum mechanics, QFT, and gauge theories.
CommutatorRule
: Simplifies commutators using identities ([A,A]→0
, [x,p]→iħ
, Lie algebra) or expands them ([A,B]→AB-BA
).AntiCommutatorRule
: Simplifies anti-commutators using identities or expands them ({A,B}→AB+BA
).CliffordAlgebraRule
: Simplifies adjacent products of gamma matrices: γ¹γ¹ → -1
.SimplifyGammaProductRule
: Simplifies products of non-adjacent identical gamma matrices: γ^μ ... γ^μ → η^μμ ...
. Crucial for QFT proofs.AdjointRule
: Applies properties of the Hermitian conjugate: (AB)† → B†A†
, (A+B)† → A†+B†
, i† → -i
.AdjointOfDerivativeRule
: Correctly computes the adjoint of a partial derivative: (∂μ)† → -∂μ
.BakerCampbellHausdorffRule
: Simplifies e^A * e^B
when [A,B]
is a c-number.ExpandCovariantDerivativeRule
: Expands D_μ
into its partial derivative and connection term (∂_μ + igA_μ
). (Expansion pass only).To extend the capabilities of the Mħπ engine, you can add new rules. This section details the properties of a rule and the process for implementing a new one.
Each rule has several properties that define its behavior and its place in the simplification process. These are defined by the SimplificationRule
trait.
name
: A unique, stable name for the rule (e.g., "AdditiveIdentity"
).description
: A short, human-readable description of what the rule does.long_description
: A more detailed explanation of the rule, its purpose, and its application.kind
: The conceptual category of the rule. This is a RuleKind
enum, which can be one of:
Simplification
: Reduces expression complexity (e.g., x + 0 -> x
).Expansion
: Expands expressions (e.g., a*(b+c) -> a*b + a*c
).Identity
: Applies a known mathematical identity (e.g., sin(x)^2 + cos(x)^2 -> 1
).Evaluation
: Computes a definite numeric result (e.g., 3! -> 6
).Factoring
: Factors expressions (e.g., a*b + a*c -> a*(b+c)
).domain
: The mathematical domain the rule applies to. This is a RuleDomain
enum, which can be one of:
Algebraic
Trigonometric
Calculus
Quantum
Evaluative
Gauge
priority
: A u32
value that determines the order of application for rules within the same pass. Higher numbers are applied first.passes
: A Vec<ApplicationPass>
that specifies which simplification pass(es) the rule should be applied in. The ApplicationPass
enum has the following variants:
Expansion
: Runs once at the beginning to expand expressions.Main
: The main simplification loop, which runs repeatedly until no more rules can be applied.Factoring
: A final pass for factoring and cleanup.conflicts_with
: A list of rule names that this rule conflicts with. The simplification engine will ensure that conflicting rules are not applied in a way that would cause loops or other issues.To implement a new rule, you need to create a Rust struct and implement the SimplificationRule
trait for it.
Here is a template for a new rule:
use crate::rules::{SimplificationRule, RuleKind, RuleDomain, ApplicationPass};
use crate::expr::SymbolicExpr;
use crate::calculus::Context;
pub struct MyNewRule;
impl SimplificationRule for MyNewRule {
fn name(&self) -> &'static str { "MyNewRule" }
fn description(&self) -> &'static str { "A brief description of my new rule." }
fn long_description(&self) -> &'static str {
"A more detailed description of what this rule does and how it works."
}
fn kind(&self) -> RuleKind { RuleKind::Simplification }
fn domain(&self) -> RuleDomain { RuleDomain::Algebraic }
fn priority(&self) -> u32 { 100 } // Higher numbers run first
fn passes(&self) -> Vec<ApplicationPass> { vec![ApplicationPass::Main] }
fn applies_to(&self, expr: &SymbolicExpr, ctx: &Context) -> bool {
// Logic to check if the rule can be applied to the given expression.
// For example, pattern matching on the expression structure.
// This check should be as fast as possible.
true // Placeholder
}
fn apply(&self, expr: &SymbolicExpr, ctx: &mut Context) -> Option<SymbolicExpr> {
// Logic to transform the expression.
// If the rule applies, return Some(new_expr).
// Otherwise, return None.
None // Placeholder
}
}
src/rules/algebraic.rs
), or add to an existing one.SimplificationRule
trait.name
, kind
, domain
, priority
, and passes
.applies_to
method to define the pattern your rule should match. This is crucial for performance, as it prevents the apply
method from being called unnecessarily.apply
method to define the transformation that your rule performs.RuleRegistry::new()
function in src/rules/mod.rs
.src/rules/presets.rs
.