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())
}
さらに進む
中断 (abort) せずにコンテキストを検査する
ミュータブルな型には 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、演算子は、コンテキストが異なると中断 (abort) します。 - 別のペイロード型. ミュータブル層では、
Polynomial(p)はミュータブルなContextPolynomialを受け取ります。 - 束縛はアリティを信頼する. イミュータブル層と同様です。
次のステップ
- mutable/context API と mutable/context の設計。
- immut/context チュートリアル では代入と部分評価を詳しく説明しています。