pub enum Expr {
Show 14 variants
Const(f64),
Var(usize),
Binary(BinOp, Box<Expr>, Box<Expr>),
Unary(UnaryOp, Box<Expr>),
Sum(Vec<Expr>),
Cse(Rc<Expr>),
Funcall {
id: usize,
args: Vec<FuncallArg>,
},
Compare(CmpOp, Box<Expr>, Box<Expr>),
And(Box<Expr>, Box<Expr>),
Or(Box<Expr>, Box<Expr>),
Not(Box<Expr>),
Cond {
cond: Box<Expr>,
then_: Box<Expr>,
else_: Box<Expr>,
},
MinList(Vec<Expr>),
MaxList(Vec<Expr>),
}Variants§
Const(f64)
Numeric constant.
Var(usize)
Variable reference (0-based index into x).
Binary(BinOp, Box<Expr>, Box<Expr>)
Binary op: args = [lhs, rhs].
Unary(UnaryOp, Box<Expr>)
Unary op.
Sum(Vec<Expr>)
n-ary sum (opcode o54 — variadic; we may emit it from o0
folding optimization, but the parser treats o0 as binary).
Cse(Rc<Expr>)
Reference to a common subexpression (.nl V segment). The
payload is a shared body; many references to the same CSE share
one Rc, so the parsed problem is a DAG. Walking through Cse
is mathematically equivalent to inlining the body at each
occurrence (every reference is an independent occurrence in the
chain rule), so eval/grad/collect_vars just recurse into the
inner Expr.
Funcall
AMPL imported (external) function call. id matches an entry in
NlProblem.imported_funcs; resolution to a live shared library
happens when the tape is built (see nl_external::ExternalResolver).
Compare(CmpOp, Box<Expr>, Box<Expr>)
Relational comparison (o22/o23/o24/o28/o29/o30).
Evaluates to 1.0 when the comparison holds, else 0.0. The
result is piecewise-constant, so it has zero derivative
everywhere (the kink at equality is ignored — standard
subgradient-free treatment, matching ASL).
And(Box<Expr>, Box<Expr>)
Logical AND (o21). 1.0 iff both operands are nonzero.
Zero derivative (piecewise constant).
Or(Box<Expr>, Box<Expr>)
Logical OR (o20). 1.0 iff either operand is nonzero.
Zero derivative (piecewise constant).
Not(Box<Expr>)
Logical NOT (o34). 1.0 iff the operand is zero.
Zero derivative (piecewise constant).
Cond
if-then-else (o35 OPIFnl). Evaluates cond; when it is
nonzero the value and all derivatives flow through then_,
otherwise through else_. The branch switch is a non-smooth
event the derivative ignores (it differentiates only the
active branch), exactly as ASL/IPOPT does for if.
MinList(Vec<Expr>)
n-ary minimum (o11 MINLIST). Value is the smallest operand.
Piecewise linear: the derivative flows through whichever operand
is currently smallest (a subgradient; ties resolve to the first
such operand), and the second derivative is identically zero —
the standard AD treatment for min/max, matching ASL/IPOPT.
MaxList(Vec<Expr>)
n-ary maximum (o12 MAXLIST). Value is the largest operand;
derivative routing mirrors Expr::MinList.
Trait Implementations§
Auto Trait Implementations§
impl !Send for Expr
impl !Sync for Expr
impl Freeze for Expr
impl RefUnwindSafe for Expr
impl Unpin for Expr
impl UnsafeUnpin for Expr
impl UnwindSafe for Expr
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T, U> Imply<T> for U
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more