it.grypho.scala.leonardo
Members list
Packages
Domain analysis as a user-facing question.
Domain analysis as a user-facing question.
The analysis itself lives in scalar (scalar.domainOf, scalar.singularitiesOf), because scalar.integrate and scalar.Limit have to be able to call it as a guard. It therefore answers in a neutral DomainSet, which is not a predicate in the language. This package is the other half of that split: it renders a DomainSet into the relation nodes a user reads — _Comparison, and, or, _Bool.
A separate package rather than nodes in equation, for two reasons: a domain is not a relation, and the project's convention is one package per domain. It imports core + scalar + equation + logic, which is acyclic — nothing imports it but parser.
What cannot be rendered stays symbolic. tan's excluded points and the Gamma poles are infinite sets, and the language has no quantifier, so domain(tan(x), x) does not reduce. Emitting a truncated list of exclusions would read as exhaustive, which is the failure mode this package exists to avoid.
Attributes
Vector calculus — scalar and vector fields over an ordered coordinate tuple.
Vector calculus — scalar and vector fields over an ordered coordinate tuple.
The differential operators grad, div, curl and laplacian, plus the multivariate derivative surface jacobian and hessian. Imports core + scalar + matrix, which is acyclic: nothing imports this package but parser. No equation import is needed — every operator returns a matrix or a scalar, never a relation.
A vector field is an n×1 matrix._Matrix, not a new carrier. The symbolic matrix already holds arbitrary _Expression cells, so every existing matrix operation applies to a field unchanged, and derive already distributes over it element-wise (_Matrix is _ElementWise). This is the argument that kept distributions out of a bespoke container elsewhere in this library: a new carrier is only worth it when something must read the value as one.
The operators are compositions of derive; the content here is the shape rules. Each one is a line of arithmetic over partial derivatives, so what the code actually spends its effort on is refusing the ill-shaped cases — a curl outside three dimensions, a component/coordinate count mismatch, a repeated coordinate. That is the rule that an analysis must describe what the library computes, applied to a domain where the wrong answer would look perfectly plausible.
The coordinate tuple is explicit and ordered, never inferred. grad(f) alone is meaningless: the order of the result's components has to come from somewhere, and reading it off freeVars would have to invent a convention (alphabetical? first-seen?) under which grad(x*y) and grad(y*x) could disagree. Every node therefore carries its Vector[_Variable].
Those variables follow the scalar._Taylor convention, not the binder convention: they appear free in the result — a gradient is a function of position — so they are excluded from children (so substitute cannot rewrite the coordinates the answer is phrased in) but are not binders in the _Derivative sense. _SolveSystem supplies only the list-shaped plumbing; _Taylor and domain._Domain supply the semantics.
Cartesian only for now (CoordinateSystem). The field ships from the start so the node shape is final and the curvilinear systems — cylindrical and spherical, via the general orthogonal curvilinear formulas — lands as an eval change and nothing else. Any other system stays symbolic rather than being answered with the Cartesian formula, which would be a confidently wrong result rather than an obviously missing one.
Attributes
Type members
Classlikes
Attributes
- Supertypes
-
class Objecttrait Matchableclass Any
Value members
Concrete methods
Demo entry point: parses a fixed list of expressions and prints each parse result.
Demo entry point: parses a fixed list of expressions and prints each parse result.
Run with sbt run (selects this main when prompted) or sbt "runMain it.grypho.scala.leonardo.main". For the interactive REPL use sbt "runMain it.grypho.scala.leonardo.cli.repl" instead.