Waldek Hebisch <[EMAIL PROTECTED]> writes:
> So, basically you say that we should check number of argument at place
> of use. I see another possibility: add third argument to isExpt, giving
> expected number of arguments.
Actually, I now have looked closer at the code and have a rather different
suggestion. The main point is that we should not check for the name of the
operator, but rather for identity. Currently we allow to have different
operators with the same name, although I believe that this feature is unused.
I'm not sure whether we should disable this feature altogether. But I'm pretty
sure that we should require, for example in inroot, that the operator is
*identical* (in the sense of =$BOP, which is a little bit weaker than EQ$List)
to operator("nthRoot"::Symbol)$CommonOperators.
Note that the algebra is set up in a way that this works. Below a text I wrote
today morning without internet access, which explains the details.
Dear Waldek,
I looked a little into the isExpt issue and the relations to dealing with
operators. I found the following surprising:
is?(k, op) and is?(k, sy) (both implemented in Kernel) have *different*
semantics: the former does not only check the name, but actually identity.
Thus, modifying COMBF as below, also cures the exp^log x problem. However, I
do not think this is the real fix. I'd prefer to do it as follows:
* remove is? entirely from BasicOperator, Kernel and ExpressionSpace, because
it's name is misleading.
* remove the two-argument form of isExpt.
* spell out occurrences of isExpt(a, op). I think the following translation
would be acceptable.
(u := isExpt(x, oproot)) case Record(var:K, exponent:Z) =>
pr := u::Record(var:K, exponent:Z)
(first argument(pr.var)) **
(pr.exponent /$Fraction(Z)
(n * retract(second argument(pr.var))@Z))
becomes (untested...):
EXPTREC ==> Record(var:K, exponent:Z)
(u := isExpt(x)) case EXPTREC and
operator (pr := u::EXPTREC).var = oproot =>
(first argument(pr.var)) **
(pr.exponent /$Fraction(Z)
(n * retract(second argument(pr.var))@Z))
I think that testing for equality is correct most of the time...
* replace is?(op, sy) by op.name = sy and is?(op1, op2) by op1 = op2, as
appropriate. Most of the time it should become the second form, I think.
If this looks good to you, I can post a patch in a few hours.
Martin
Index: combfunc.spad.pamphlet
===================================================================
--- combfunc.spad.pamphlet (revision 393)
+++ combfunc.spad.pamphlet (working copy)
@@ -51,9 +51,6 @@
++ Provides combinatorial functions over an integral domain.
++ Keywords: combinatorial, function, factorial.
++ Examples: )r COMBF INPUT
-
-
-
CombinatorialFunction(R, F): Exports == Implementation where
R: Join(OrderedSet, IntegralDomain)
F: FunctionSpace R
@@ -65,8 +62,6 @@
SMP ==> SparseMultivariatePolynomial(R, K)
Z ==> Integer
- POWER ==> "%power"::Symbol
- OPEXP ==> "exp"::Symbol
SPECIALDIFF ==> "%specialDiff"
SPECIALDISP ==> "%specialDisp"
SPECIALEQUAL ==> "%specialEqual"
@@ -221,7 +216,8 @@
opdsum := operator("%defsum"::Symbol)$CommonOperators
opprod := operator("product"::Symbol)$CommonOperators
opdprod := operator("%defprod"::Symbol)$CommonOperators
- oppow := operator(POWER::Symbol)$CommonOperators
+ oppow := operator("%power"::Symbol)$CommonOperators
+ opexp := operator("exp"::Symbol)$CommonOperators
factorial x == opfact x
binomial(x, y) == opbinom [x, y]
@@ -239,7 +235,7 @@
x ** y ==
-- Do some basic simplifications
- is?(x,POWER) =>
+ is?(x,"%power"::Symbol) =>
args : List F := argument first kernels x
not(#args = 2) => error "Too many arguments to **"
number?(first args) and number?(y) =>
@@ -458,7 +455,7 @@
is?(op, "%defsum"::Symbol) => opdsum
is?(op, "product"::Symbol) => opprod
is?(op, "%defprod"::Symbol) => opdprod
- is?(op, POWER) => oppow
+ is?(op, "%power"::Symbol) => oppow
error "Not a combinatorial operator"
iprod l ==
@@ -517,7 +514,7 @@
*/[eval(first l,k::K,i::F) for i in r1::Z .. r2::Z]
iiipow l ==
- (u := isExpt(x := first l, OPEXP)) case "failed" => kernel(oppow, l)
+ (u := isExpt(x := first l, opexp)) case "failed" => kernel(oppow, l)
rec := u::Record(var: K, exponent: Z)
y := first argument(rec.var)
(r := retractIfCan(y)@Union(Fraction Z, "failed")) case
@@ -540,14 +537,11 @@
zero?(x := first l) =>
zero? second l => error "0 ** 0"
0
--- one? x or zero?(n := second l) => 1
- (x = 1) or zero?(n: F := second l) => 1
--- one? n => x
- (n = 1) => x
- (u := isExpt(x, OPEXP)) case "failed" => kernel(oppow, l)
+ one? x or zero?(n := second l) => 1
+ one? n => x
+ (u := isExpt(x, opexp)) case "failed" => kernel(oppow, l)
rec := u::Record(var: K, exponent: Z)
--- one?(y := first argument(rec.var)) or y = -1 =>
- ((y := first argument(rec.var))=1) or y = -1 =>
+ one?(y := first argument(rec.var)) or y = -1 =>
(operator(rec.var)) (rec.exponent * y * n)
kernel(oppow, l)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"FriCAS - computer algebra system" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/fricas-devel?hl=en
-~----------~----~----~----~------~----~------~--~---