Go to the first, previous, next, last section, table of contents.


書替え規則のその他特徴

書替え規則において、ある特定の「関数名」はマーカーとして機能します。 本節はそのようなマーカーの全リストです。 まずパターン中で働くマーカーのリスト、 次に規則の右辺で働くマーカーをリストします。

ただ一種のマーカー `import(x)' は、規則そのものとして働きます。 ここで `x' は変数名で、その変数にストアされた他の規則集合が、 インポート先の規則に継承されます。 例えば、`[f(a+b) := f(a) + f(b), f(a b) := a f(b) :: real(a)]' が 変数 `linearF' にストアされている状態で、 `[f(0) := 0, import(linearF)]' は3つの規則全てを適用します。 インポートした規則を若干修正することが可能で、 `import(x, v1, x1, v2, x2, ...)' は 規則集合 x をインポートして、 出現する @c{$v_1$} v1 (変数または関数名)を全て x1 に置換します(@c{$v_2$} v2 以降も同様)。 (@c{$v_1$} v1 が関数名ならば、@c{$x_1$} x1 も関数名か無名関数 `< >' でなければなりません。 Specifying Operators 参照 。) 例えば、`[g(0) := 0, import(linearF, f, g)]' は、 線形規則を f にではなく g に適用します。 `import(x)' はネストできますが、import-with-renaming 機能は 下位のインポートを適切にリネームできないかも知れません。

パターン中で許される特殊関数は下記のとおりです。

`quote(x)'
このパターンは x に厳密にマッチします。 x の中の変数名はメタ変数として解釈されません。 数値だけは、見かけでなく数値的な同等性が比較されるので `f(quote(12))'`f(12)' にも `f(12.0)' にもマッチします。 (書替え機構において、数値は常にこのように扱われます。 規則 `f(x,x) := g(x)'`f(12, 12.0)' にマッチします。 この場合、書替え結果は `g(12)'`g(12.0)' のどちらもあり得ます。)
`plain(x)'
x は関数呼出し `f(x1,x2,...)' でなければなりません。 このパターンは、 関数 f が指定の引数パターンで呼出される部分にマッチします。 この場合、関数 f の特性は考慮されませんから、 例えば `+' は交換性も結合性も無いとして扱われます。 quote とは異なり、 引数の `x1,x2,...' はパターンとして扱われます。 引数を同様に「plain 的」に扱いたい場合は、次のように それぞれ別の plain で囲んでやる必要があります。 `plain(plain(-a) + plain(b c))'
`opt(x,def)'
x は変数名でなければなりません。 この特殊関数は、関数の引数あるいはベクトルの要素として使用し、 その引数やベクトル要素がオプショナル(訳注: 任意に省略可能) であることを明示します。 `+', `-', `*', `&&', `||' の引数の場合、 または `/'`^' の第2引数の場合、 デフォルト値 def を省略できます。 パターン `x + opt(y)' は、 あるひとつの加算項 x とその他の項 y の和にマッチするし、 ターゲット式全体に x がマッチして y がゼロになるようなマッチングもあります。 他の演算子でも同様です。 一般的な関数では、デフォルト値 def を指定しなければなりません。 マッチングのとき、 オプショナル引数が抜かされていると def の値が採られます。 例えば、パターン `f(opt(a,0), b, opt(c,b))'`f(b)', `f(a,b)', `f(a,b,c)' にマッチします。 省略された引数に対して(訳注: 後で参照するとき)、 この例ではゼロや b がデフォルト値として供給されます。 後者の例では、 文字どおりの変数 b がデフォルトになることに注意してください。 それはメタ変数 b にマッチした式ではありません。 言換えれば、デフォルト値 def は実質的に quote されていると言えます。
`condition(x,c)'
This matches the pattern x, with the attached condition c. It is the same as `x :: c'.
`pand(x,y)'
This matches anything that matches both pattern x and pattern y. It is the same as `x &&& y'. Composing Patterns in Rewrite Rules 参照 .
`por(x,y)'
This matches anything that matches either pattern x or pattern y. It is the same as `x ||| y'.
`pnot(x)'
This matches anything that does not match pattern x. It is the same as `!!! x'.
`cons(h,t)'
This matches any vector of one or more elements. The first element is matched to h; a vector of the remaining elements is matched to t. Note that vectors of fixed length can also be matched as actual vectors: The rule `cons(a,cons(b,[])) := cons(a+b,[])' is equivalent to the rule `[a,b] := [a+b]'.
`rcons(t,h)'
This is like cons, except that the last element is matched to h, with the remaining elements matched to t.
`apply(f,args)'
This matches any function call. The name of the function, in the form of a variable, is matched to f. The arguments of the function, as a vector of zero or more objects, are matched to `args'. Constants, variables, and vectors do not match an apply pattern. For example, `apply(f,x)' matches any function call, `apply(quote(f),x)' matches any call to the function `f', `apply(f,[a,b])' matches any function call with exactly two arguments, and `apply(quote(f), cons(a,cons(b,x)))' matches any call to the function `f' with two or more arguments. Another way to implement the latter, if the rest of the rule does not need to refer to the first two arguments of `f' by name, would be `apply(quote(f), x :: vlen(x) >= 2)'. Here's a more interesting sample use of apply:
apply(f,[x+n])  :=  n + apply(f,[x])
   :: in(f, [floor,ceil,round,trunc]) :: integer(n)
Note, however, that this will be slower to match than a rule set with four separate rules. The reason is that Calc sorts the rules of a rule set according to top-level function name; if the top-level function is apply, Calc must try the rule for every single formula and sub-formula. If the top-level function in the pattern is, say, floor, then Calc invokes the rule only for sub-formulas which are calls to floor. Formulas normally written with operators like + are still considered function calls: apply(f,x) matches `a+b' with `f = add', `x = [a,b]'. You must use apply for meta-variables with function names on both sides of a rewrite rule: `apply(f, [x]) := f(x+1)' is not correct, because it rewrites `spam(6)' into `f(7)'. The righthand side should be `apply(f, [x+1])'. Also note that you will have to use no-simplify (m O) mode when entering this rule so that the apply isn't evaluated immediately to get the new rule `f(x) := f(x+1)'. Or, use s e to enter the rule without going through the stack, or enter the rule as `apply(f, [x]) := apply(f, [x+1]) :: 1'. 条件つきの書替え規則 参照 .
`select(x)'
This is used for applying rules to formulas with selections; Selections with Rewrite Rules 参照 .

規則の右辺で働く特殊関数は次のとおりです。

`quote(x)'
The notation `quote(x)' is changed to `x' when the righthand side is used. As far as the rewrite rule is concerned, quote is invisible. However, quote has the special property in Calc that its argument is not evaluated. Thus, while it will not work to put the rule `t(a) := typeof(a)' on the stack because `typeof(a)' is evaluated immediately to produce `t(a) := 100', you can use quote to protect the righthand side: `t(a) := quote(typeof(a))'. (条件つきの書替え規則 参照 , for another trick for protecting rules from evaluation.)
`plain(x)'
Special properties of and simplifications for the function call x are not used. One interesting case where plain is useful is the rule, `q(x) := quote(x)', trying to expand a shorthand notation for the quote function. This rule will not work as shown; instead of replacing `q(foo)' with `quote(foo)', it will replace it with `foo'! The correct rule would be `q(x) := plain(quote(x))'.
`cons(h,t)'
Where t is a vector, this is converted into an expanded vector during rewrite processing. Note that cons is a regular Calc function which normally does this anyway; the only way cons is treated specially by rewrites is that cons on the righthand side of a rule will be evaluated even if default simplifications have been turned off.
`rcons(t,h)'
Analogous to cons except putting h at the end of the vector t.
`apply(f,args)'
Where f is a variable and args is a vector, this is converted to a function call. Once again, note that apply is also a regular Calc function.
`eval(x)'
The formula x is handled in the usual way, then the default simplifications are applied to it even if they have been turned off normally. This allows you to treat any function similarly to the way cons and apply are always treated. However, there is a slight difference: `cons(2+3, [])' with default simplifications off will be converted to `[2+3]', whereas `eval(cons(2+3, []))' will be converted to `[5]'.
`evalsimp(x)'
The formula x has meta-variables substituted in the usual way, then algebraically simplified as if by the a s command.
`evalextsimp(x)'
The formula x has meta-variables substituted in the normal way, then "extendedly" simplified as if by the a e command.
`select(x)'
Selections with Rewrite Rules 参照 .

There are also some special functions you can use in conditions.

`let(v := x)'
The expression x is evaluated with meta-variables substituted. The a s command's simplifications are not applied by default, but x can include calls to evalsimp or evalextsimp as described above to invoke higher levels of simplification. The result of x is then bound to the meta-variable v. As usual, if this meta-variable has already been matched to something else the two values must be equal; if the meta-variable is new then it is bound to the result of the expression. This variable can then appear in later conditions, and on the righthand side of the rule. In fact, v may be any pattern in which case the result of evaluating x is matched to that pattern, binding any meta-variables that appear in that pattern. Note that let can only appear by itself as a condition, or as one term of an `&&' which is a whole condition: It cannot be inside an `||' term or otherwise buried. The alternate, equivalent form `let(v, x)' is also recognized. Note that the use of `:=' by let, while still being assignment-like in character, is unrelated to the use of `:=' in the main part of a rewrite rule. As an example, `f(a) := g(ia) :: let(ia := 1/a) :: constant(ia)' replaces `f(a)' with `g' of the inverse of `a', if that inverse exists and is constant. For example, if `a' is a singular matrix the operation `1/a' is left unsimplified and `constant(ia)' fails, but if `a' is an invertible matrix then the rule succeeds. Without let there would be no way to express this rule that didn't have to invert the matrix twice. Note that, because the meta-variable `ia' is otherwise unbound in this rule, the let condition itself always "succeeds" because no matter what `1/a' evaluates to, it can successfully be bound to ia. Here's another example, for integrating cosines of linear terms: `myint(cos(y),x) := sin(y)/b :: let([a,b,x] := lin(y,x))'. The lin function returns a 3-vector if its argument is linear, or leaves itself unevaluated if not. But an unevaluated lin call will not match the 3-vector on the lefthand side of the let, so this let both verifies that y is linear, and binds the coefficients a and b for use elsewhere in the rule. (It would have been possible to use `sin(a x + b)/b' for the righthand side instead, but using `sin(y)/b' avoids gratuitous rearrangement of the argument of the sine.) Similarly, here is a rule that implements an inverse-erf function. It uses root to search for a solution. If root succeeds, it will return a vector of two numbers where the first number is the desired solution. If no solution is found, root remains in symbolic form. So we use let to check that the result was indeed a vector.
ierf(x)  :=  y  :: let([y,z] := root(erf(a) = x, a, .5))
`matches(v,p)'
The meta-variable v, which must already have been matched to something elsewhere in the rule, is compared against pattern p. Since matches is a standard Calc function, it can appear anywhere in a condition. But if it appears alone or as a term of a top-level `&&', then you get the special extra feature that meta-variables which are bound to things inside p can be used elsewhere in the surrounding rewrite rule. The only real difference between `let(p := v)' and `matches(v, p)' is that the former evaluates `v' using the default simplifications, while the latter does not.
`remember'
This is actually a variable, not a function. If remember appears as a condition in a rule, then when that rule succeeds the original expression and rewritten expression are added to the front of the rule set that contained the rule. If the rule set was not stored in a variable, remember is ignored. The lefthand side is enclosed in quote in the added rule if it contains any variables. For example, the rule `f(n) := n f(n-1) :: remember' applied to `f(7)' will add the rule `f(7) := 7 f(6)' to the front of the rule set. The rule set EvalRules works slightly differently: There, the evaluation of `f(6)' will complete before the result is added to the rule set, in this case as `f(7) := 5040'. Thus remember is most useful inside EvalRules. It is up to you to ensure that the optimization performed by remember is safe. For example, the rule `foo(n) := n :: evalv(eatfoo) > 0 :: remember' is a bad idea (evalv is the function equivalent of the = command); if the variable eatfoo ever contains 1, rules like `foo(7) := 7' will be added to the rule set and will continue to operate even if eatfoo is later changed to 0.
`remember(c)'
Remember the match as described above, but only if condition c is true. For example, `remember(n % 4 = 0)' in the above factorial rule remembers only every fourth result. Note that `remember(1)' is equivalent to `remember', and `remember(0)' has no effect.


Go to the first, previous, next, last section, table of contents.     利用度数