mutable/context 教程

本教程展示如何原地累加命名变量多项式,以及如何使用与不可变层相同的调用对其进行代换和求值。

快速开始

moon add Luna-Flow/luna-poly@0.2.0
import {
  "Luna-Flow/luna-poly/mutable",
}
test "mutable context quick start" {
  let ctx = @mutable.VariableContext::from_names(["x"])
  let x = ctx.require_variable("x")
  let p = @mutable.ContextPolynomial::from_named_terms_as_sparse(ctx, [([(x, 1U)], 2)])
  p.add_inplace(@mutable.ContextPolynomial::constant(ctx, 1))
  inspect(p, content="1 + 2 * x")
  inspect(p.eval_named([(x, 4)]), content="9")
}

日常任务

累加乘积之和

test "accumulate" {
  let ctx = @mutable.VariableContext::from_names(["a", "b"])
  let a : @mutable.ContextPolynomial[Int] = @mutable.ContextPolynomial::variable(ctx, ctx.require_variable("a"))
  let b : @mutable.ContextPolynomial[Int] = @mutable.ContextPolynomial::variable(ctx, ctx.require_variable("b"))
  let total = @mutable.ContextPolynomial::constant(ctx, 0)
  for k in 1..<=3 {
    let term = a.pow(k.reinterpret_as_uint())
    term.mul_inplace(b)
    total.add_inplace(term)
  }
  inspect(total, content="1 * a * b + 1 * a^2 * b + 1 * a^3 * b")
}

代换与求值

代换返回新的多项式,接收者保持原样:

test "substitute" {
  let ctx = @mutable.VariableContext::from_names(["x", "y"])
  let x = ctx.require_variable("x")
  let y = ctx.require_variable("y")
  let p = @mutable.ContextPolynomial::from_named_terms_as_sparse(ctx, [([(x, 2U)], 1), ([(y, 1U)], 1)])
  let q = p.eval_partial([(y, 5)])
  inspect(q, content="5 + 1 * x^2")
  inspect(p, content="1 * y + 1 * x^2")
  let named = p.substitute_names([(x.to_type_theory_name(), Scalar(3))])
  inspect(named, content="9 + 1 * y")
}

快照与重置

test "snapshot" {
  let ctx = @mutable.VariableContext::from_names(["x"])
  let x = ctx.require_variable("x")
  let p = @mutable.ContextPolynomial::from_named_terms_as_terms(ctx, [([(x, 3U)], 1)])
  let saved = p.copy()
  let frozen = p.to_immut()
  p.clear()
  inspect(saved, content="1 * x^3")
  inspect(frozen, content="1 * x^3")
  assert_true(p.is_zero())
}

深入了解

不中止地检查上下文

可变类型没有 add_checked;请使用操作记录:

test "checked through ops" {
  let ops = @mutable.ContextPolynomial::ops()
  let p = @mutable.ContextPolynomial::constant(@mutable.VariableContext::from_names(["x"]), 1)
  let q = @mutable.ContextPolynomial::constant(@mutable.VariableContext::from_names(["t"]), 1)
  assert_true(ops.add_checked(p, q) is None)
  assert_true(ops.add_checked(p, p) is Some(_))
}

常见陷阱

  • 上下文不匹配会中止(abort)。当上下文不同时,add_inplace、mul_inplace 和运算符都会中止。
  • 独立的载荷类型。在可变层中,Polynomial(p) 接收一个可变的 ContextPolynomial。
  • 绑定时信任元数,与不可变层相同。

后续步骤