diff options
Diffstat (limited to 'src/algebra/op.spad.pamphlet')
-rw-r--r-- | src/algebra/op.spad.pamphlet | 541 |
1 files changed, 541 insertions, 0 deletions
diff --git a/src/algebra/op.spad.pamphlet b/src/algebra/op.spad.pamphlet new file mode 100644 index 00000000..19d4218e --- /dev/null +++ b/src/algebra/op.spad.pamphlet @@ -0,0 +1,541 @@ +\documentclass{article} +\usepackage{axiom} +\begin{document} +\title{\$SPAD/src/algebra op.spad} +\author{Manuel Bronstein} +\maketitle +\begin{abstract} +\end{abstract} +\eject +\tableofcontents +\eject +\section{domain BOP BasicOperator} +<<domain BOP BasicOperator>>= +)abbrev domain BOP BasicOperator +++ Basic system operators +++ Author: Manuel Bronstein +++ Date Created: 22 March 1988 +++ Date Last Updated: 11 October 1993 +++ Description: +++ A basic operator is an object that can be applied to a list of +++ arguments from a set, the result being a kernel over that set. +++ Keywords: operator, kernel. +BasicOperator(): Exports == Implementation where + O ==> OutputForm + P ==> AssociationList(String, None) + L ==> List Record(key:String, entry:None) + SEX ==> InputForm +-- some internal properties + LESS? ==> "%less?" + EQUAL? ==> "%equal?" + WEIGHT ==> "%weight" + DISPLAY ==> "%display" + SEXPR ==> "%input" + + Exports ==> OrderedSet with + name : $ -> Symbol + ++ name(op) returns the name of op. + properties: $ -> P + ++ properties(op) returns the list of all the properties + ++ currently attached to op. + copy : $ -> $ + ++ copy(op) returns a copy of op. + operator : Symbol -> $ + ++ operator(f) makes f into an operator with arbitrary arity. + operator : (Symbol, NonNegativeInteger) -> $ + ++ operator(f, n) makes f into an n-ary operator. + arity : $ -> Union(NonNegativeInteger, "failed") + ++ arity(op) returns n if op is n-ary, and + ++ "failed" if op has arbitrary arity. + nullary? : $ -> Boolean + ++ nullary?(op) tests if op is nullary. + unary? : $ -> Boolean + ++ unary?(op) tests if op is unary. + nary? : $ -> Boolean + ++ nary?(op) tests if op has arbitrary arity. + weight : $ -> NonNegativeInteger + ++ weight(op) returns the weight attached to op. + weight : ($, NonNegativeInteger) -> $ + ++ weight(op, n) attaches the weight n to op. + equality : ($, ($, $) -> Boolean) -> $ + ++ equality(op, foo?) attaches foo? as the "%equal?" property + ++ to op. If op1 and op2 have the same name, and one of them + ++ has an "%equal?" property f, then \spad{f(op1, op2)} is called to + ++ decide whether op1 and op2 should be considered equal. + comparison : ($, ($, $) -> Boolean) -> $ + ++ comparison(op, foo?) attaches foo? as the "%less?" property + ++ to op. If op1 and op2 have the same name, and one of them + ++ has a "%less?" property f, then \spad{f(op1, op2)} is called to + ++ decide whether \spad{op1 < op2}. + display : $ -> Union(List O -> O, "failed") + ++ display(op) returns the "%display" property of op if + ++ it has one attached, and "failed" otherwise. + display : ($, List O -> O) -> $ + ++ display(op, foo) attaches foo as the "%display" property + ++ of op. If op has a "%display" property f, then \spad{op(a1,...,an)} + ++ gets converted to OutputForm as \spad{f(a1,...,an)}. + display : ($, O -> O) -> $ + ++ display(op, foo) attaches foo as the "%display" property + ++ of op. If op has a "%display" property f, then \spad{op(a)} + ++ gets converted to OutputForm as \spad{f(a)}. + ++ Argument op must be unary. + input : ($, List SEX -> SEX) -> $ + ++ input(op, foo) attaches foo as the "%input" property + ++ of op. If op has a "%input" property f, then \spad{op(a1,...,an)} + ++ gets converted to InputForm as \spad{f(a1,...,an)}. + input : $ -> Union(List SEX -> SEX, "failed") + ++ input(op) returns the "%input" property of op if + ++ it has one attached, "failed" otherwise. + is? : ($, Symbol) -> Boolean + ++ is?(op, s) tests if the name of op is s. + has? : ($, String) -> Boolean + ++ has?(op, s) tests if property s is attached to op. + assert : ($, String) -> $ + ++ assert(op, s) attaches property s to op. + ++ Argument op is modified "in place", i.e. no copy is made. + deleteProperty_!: ($, String) -> $ + ++ deleteProperty!(op, s) unattaches property s from op. + ++ Argument op is modified "in place", i.e. no copy is made. + property : ($, String) -> Union(None, "failed") + ++ property(op, s) returns the value of property s if + ++ it is attached to op, and "failed" otherwise. + setProperty : ($, String, None) -> $ + ++ setProperty(op, s, v) attaches property s to op, + ++ and sets its value to v. + ++ Argument op is modified "in place", i.e. no copy is made. + setProperties : ($, P) -> $ + ++ setProperties(op, l) sets the property list of op to l. + ++ Argument op is modified "in place", i.e. no copy is made. + + Implementation ==> add + -- if narg < 0 then the operator ahs variable arity. + Rep := Record(opname:Symbol, narg:SingleInteger, props:P) + + oper: (Symbol, SingleInteger, P) -> $ + + is?(op, s) == name(op) = s + name op == op.opname + properties op == op.props + setProperties(op, l) == (op.props := l; op) + operator s == oper(s, -1::SingleInteger, table()) + operator(s, n) == oper(s, n::Integer::SingleInteger, table()) + property(op, name) == search(name, op.props) + assert(op, s) == setProperty(op, s, NIL$Lisp) + has?(op, name) == key?(name, op.props) + oper(se, n, prop) == [se, n, prop] + weight(op, n) == setProperty(op, WEIGHT, n pretend None) + nullary? op == zero?(op.narg) +-- unary? op == one?(op.narg) + unary? op == ((op.narg) = 1) + nary? op == negative?(op.narg) + equality(op, func) == setProperty(op, EQUAL?, func pretend None) + comparison(op, func) == setProperty(op, LESS?, func pretend None) + display(op:$, f:O -> O) == display(op, f first #1) + deleteProperty_!(op, name) == (remove_!(name, properties op); op) + setProperty(op, name, valu) == (op.props.name := valu; op) + coerce(op:$):OutputForm == name(op)::OutputForm + input(op:$, f:List SEX -> SEX) == setProperty(op, SEXPR, f pretend None) + display(op:$, f:List O -> O) == setProperty(op, DISPLAY, f pretend None) + + display op == + (u := property(op, DISPLAY)) case "failed" => "failed" + (u::None) pretend (List O -> O) + + input op == + (u := property(op, SEXPR)) case "failed" => "failed" + (u::None) pretend (List SEX -> SEX) + + arity op == + negative?(n := op.narg) => "failed" + convert(n)@Integer :: NonNegativeInteger + + copy op == + oper(name op, op.narg, + table([[r.key, r.entry] for r in entries(properties op)@L]$L)) + +-- property EQUAL? contains a function f: (BOP, BOP) -> Boolean +-- such that f(o1, o2) is true iff o1 = o2 + op1 = op2 == + name(op1) ^= name(op2) => false + op1.narg ^= op2.narg => false + brace(keys properties op1)^=$Set(String) brace(keys properties op2) => false + (func := property(op1, EQUAL?)) case None => + ((func::None) pretend (($, $) -> Boolean)) (op1, op2) + true + +-- property WEIGHT allows one to change the ordering around +-- by default, every operator has weigth 1 + weight op == + (w := property(op, WEIGHT)) case "failed" => 1 + (w::None) pretend NonNegativeInteger + +-- property LESS? contains a function f: (BOP, BOP) -> Boolean +-- such that f(o1, o2) is true iff o1 < o2 + op1 < op2 == + (w1 := weight op1) ^= (w2 := weight op2) => w1 < w2 + op1.narg ^= op2.narg => op1.narg < op2.narg + name(op1) ^= name(op2) => name(op1) < name(op2) + n1 := #(k1 := brace(keys(properties op1))$Set(String)) + n2 := #(k2 := brace(keys(properties op2))$Set(String)) + n1 ^= n2 => n1 < n2 + not zero?(n1 := #(d1 := difference(k1, k2))) => + n1 ^= (n2 := #(d2 := difference(k2, k1))) => n1 < n2 + inspect(d1) < inspect(d2) + (func := property(op1, LESS?)) case None => + ((func::None) pretend (($, $) -> Boolean)) (op1, op2) + (func := property(op1, EQUAL?)) case None => + not(((func::None) pretend (($, $) -> Boolean)) (op1, op2)) + false + +@ +\section{package BOP1 BasicOperatorFunctions1} +<<package BOP1 BasicOperatorFunctions1>>= +)abbrev package BOP1 BasicOperatorFunctions1 +++ Tools to set/get common properties of operators +++ Author: Manuel Bronstein +++ Date Created: 28 Mar 1988 +++ Date Last Updated: 15 May 1990 +++ Description: +++ This package exports functions to set some commonly used properties +++ of operators, including properties which contain functions. +++ Keywords: operator. +BasicOperatorFunctions1(A:SetCategory): Exports == Implementation where + OP ==> BasicOperator + EVAL ==> "%eval" + CONST ==> "%constant" + DIFF ==> "%diff" + + Exports ==> with + evaluate : (OP, List A) -> Union(A, "failed") + ++ evaluate(op, [a1,...,an]) checks if op has an "%eval" + ++ property f. If it has, then \spad{f(a1,...,an)} is returned, and + ++ "failed" otherwise. + evaluate : (OP, List A -> A) -> OP + ++ evaluate(op, foo) attaches foo as the "%eval" property + ++ of op. If op has an "%eval" property f, then applying op + ++ to \spad{(a1,...,an)} returns the result of \spad{f(a1,...,an)}. + evaluate : (OP, A -> A) -> OP + ++ evaluate(op, foo) attaches foo as the "%eval" property + ++ of op. If op has an "%eval" property f, then applying op + ++ to a returns the result of \spad{f(a)}. Argument op must be unary. + evaluate : OP -> Union(List A -> A, "failed") + ++ evaluate(op) returns the value of the "%eval" property of + ++ op if it has one, and "failed" otherwise. + derivative : (OP, List (List A -> A)) -> OP + ++ derivative(op, [foo1,...,foon]) attaches [foo1,...,foon] as + ++ the "%diff" property of op. If op has an "%diff" property + ++ \spad{[f1,...,fn]} then applying a derivation D to \spad{op(a1,...,an)} + ++ returns \spad{f1(a1,...,an) * D(a1) + ... + fn(a1,...,an) * D(an)}. + derivative : (OP, A -> A) -> OP + ++ derivative(op, foo) attaches foo as the "%diff" property + ++ of op. If op has an "%diff" property f, then applying a + ++ derivation D to op(a) returns \spad{f(a) * D(a)}. Argument op must be unary. + derivative : OP -> Union(List(List A -> A), "failed") + ++ derivative(op) returns the value of the "%diff" property of + ++ op if it has one, and "failed" otherwise. + if A has OrderedSet then + constantOperator: A -> OP + ++ constantOperator(a) returns a nullary operator op + ++ such that \spad{op()} always evaluate to \spad{a}. + constantOpIfCan : OP -> Union(A, "failed") + ++ constantOpIfCan(op) returns \spad{a} if op is the constant + ++ nullary operator always returning \spad{a}, "failed" otherwise. + + Implementation ==> add + evaluate(op:OP, func:A -> A) == evaluate(op, func first #1) + + evaluate op == + (func := property(op, EVAL)) case "failed" => "failed" + (func::None) pretend (List A -> A) + + evaluate(op:OP, args:List A) == + (func := property(op, EVAL)) case "failed" => "failed" + ((func::None) pretend (List A -> A)) args + + evaluate(op:OP, func:List A -> A) == + setProperty(op, EVAL, func pretend None) + + derivative op == + (func := property(op, DIFF)) case "failed" => "failed" + ((func::None) pretend List(List A -> A)) + + derivative(op:OP, grad:List(List A -> A)) == + setProperty(op, DIFF, grad pretend None) + + derivative(op:OP, f:A -> A) == + unary? op or nary? op => + derivative(op, [f first #1]$List(List A -> A)) + error "Operator is not unary" + + if A has OrderedSet then + cdisp : (OutputForm, List OutputForm) -> OutputForm + csex : (InputForm, List InputForm) -> InputForm + eqconst?: (OP, OP) -> Boolean + ltconst?: (OP, OP) -> Boolean + constOp : A -> OP + + opconst:OP := + comparison(equality(operator("constant"::Symbol, 0), eqconst?), + ltconst?) + + cdisp(a, l) == a + csex(a, l) == a + + eqconst?(a, b) == + (va := property(a, CONST)) case "failed" => not has?(b, CONST) + ((vb := property(b, CONST)) case None) and + ((va::None) pretend A) = ((vb::None) pretend A) + + ltconst?(a, b) == + (va := property(a, CONST)) case "failed" => has?(b, CONST) + ((vb := property(b, CONST)) case None) and + ((va::None) pretend A) < ((vb::None) pretend A) + + constOp a == + setProperty(display(copy opconst, cdisp(a::OutputForm, #1)), + CONST, a pretend None) + + constantOpIfCan op == + is?(op, "constant"::Symbol) and + ((u := property(op, CONST)) case None) => (u::None) pretend A + "failed" + + if A has ConvertibleTo InputForm then + constantOperator a == input(constOp a, csex(convert a, #1)) + else + constantOperator a == constOp a + +@ +\section{package COMMONOP CommonOperators} +<<package COMMONOP CommonOperators>>= +)abbrev package COMMONOP CommonOperators +++ Provides commonly used operators +++ Author: Manuel Bronstein +++ Date Created: 25 Mar 1988 +++ Date Last Updated: 2 December 1994 +++ Description: +++ This package exports the elementary operators, with some semantics +++ already attached to them. The semantics that is attached here is not +++ dependent on the set in which the operators will be applied. +++ Keywords: operator. +CommonOperators(): Exports == Implementation where + OP ==> BasicOperator + O ==> OutputForm + POWER ==> "%power"::Symbol + ALGOP ==> "%alg" + EVEN ==> "even" + ODD ==> "odd" + DUMMYVAR ==> "%dummyVar" + + Exports ==> with + operator: Symbol -> OP + ++ operator(s) returns an operator with name s, with the + ++ appropriate semantics if s is known. If s is not known, + ++ the result has no semantics. + + Implementation ==> add + dpi : List O -> O + dgamma : List O -> O + dquote : List O -> O + dexp : O -> O + dfact : O -> O + startUp : Boolean -> Void + setDummyVar: (OP, NonNegativeInteger) -> OP + + brandNew?:Reference(Boolean) := ref true + + opalg := operator("rootOf"::Symbol, 2)$OP + oproot := operator("nthRoot"::Symbol, 2) + oppi := operator("pi"::Symbol, 0) + oplog := operator("log"::Symbol, 1) + opexp := operator("exp"::Symbol, 1) + opabs := operator("abs"::Symbol, 1) + opsin := operator("sin"::Symbol, 1) + opcos := operator("cos"::Symbol, 1) + optan := operator("tan"::Symbol, 1) + opcot := operator("cot"::Symbol, 1) + opsec := operator("sec"::Symbol, 1) + opcsc := operator("csc"::Symbol, 1) + opasin := operator("asin"::Symbol, 1) + opacos := operator("acos"::Symbol, 1) + opatan := operator("atan"::Symbol, 1) + opacot := operator("acot"::Symbol, 1) + opasec := operator("asec"::Symbol, 1) + opacsc := operator("acsc"::Symbol, 1) + opsinh := operator("sinh"::Symbol, 1) + opcosh := operator("cosh"::Symbol, 1) + optanh := operator("tanh"::Symbol, 1) + opcoth := operator("coth"::Symbol, 1) + opsech := operator("sech"::Symbol, 1) + opcsch := operator("csch"::Symbol, 1) + opasinh := operator("asinh"::Symbol, 1) + opacosh := operator("acosh"::Symbol, 1) + opatanh := operator("atanh"::Symbol, 1) + opacoth := operator("acoth"::Symbol, 1) + opasech := operator("asech"::Symbol, 1) + opacsch := operator("acsch"::Symbol, 1) + opbox := operator("%box"::Symbol)$OP + oppren := operator("%paren"::Symbol)$OP + opquote := operator("applyQuote"::Symbol)$OP + opdiff := operator("%diff"::Symbol, 3) + opsi := operator("Si"::Symbol, 1) + opci := operator("Ci"::Symbol, 1) + opei := operator("Ei"::Symbol, 1) + opli := operator("li"::Symbol, 1) + operf := operator("erf"::Symbol, 1) + opli2 := operator("dilog"::Symbol, 1) + opGamma := operator("Gamma"::Symbol, 1) + opGamma2 := operator("Gamma2"::Symbol, 2) + opBeta := operator("Beta"::Symbol, 2) + opdigamma := operator("digamma"::Symbol, 1) + oppolygamma := operator("polygamma"::Symbol, 2) + opBesselJ := operator("besselJ"::Symbol, 2) + opBesselY := operator("besselY"::Symbol, 2) + opBesselI := operator("besselI"::Symbol, 2) + opBesselK := operator("besselK"::Symbol, 2) + opAiryAi := operator("airyAi"::Symbol, 1) + opAiryBi := operator("airyBi"::Symbol , 1) + opint := operator("integral"::Symbol, 3) + opdint := operator("%defint"::Symbol, 5) + opfact := operator("factorial"::Symbol, 1) + opperm := operator("permutation"::Symbol, 2) + opbinom := operator("binomial"::Symbol, 2) + oppow := operator(POWER, 2) + opsum := operator("summation"::Symbol, 3) + opdsum := operator("%defsum"::Symbol, 5) + opprod := operator("product"::Symbol, 3) + opdprod := operator("%defprod"::Symbol, 5) + + algop := [oproot, opalg]$List(OP) + rtrigop := [opsin, opcos, optan, opcot, opsec, opcsc, + opasin, opacos, opatan, opacot, opasec, opacsc] + htrigop := [opsinh, opcosh, optanh, opcoth, opsech, opcsch, + opasinh, opacosh, opatanh, opacoth, opasech, opacsch] + trigop := concat(rtrigop, htrigop) + elemop := concat(trigop, [oppi, oplog, opexp]) + primop := [opei, opli, opsi, opci, operf, opli2, opint, opdint] + combop := [opfact, opperm, opbinom, oppow, + opsum, opdsum, opprod, opdprod] + specop := [opGamma, opGamma2, opBeta, opdigamma, oppolygamma, opabs, + opBesselJ, opBesselY, opBesselI, opBesselK] + anyop := [oppren, opdiff, opbox, opquote] + allop := concat(concat(concat(concat(concat( + algop,elemop),primop),combop),specop),anyop) + +-- odd and even operators, must be maintained current! + evenop := [opcos, opsec, opcosh, opsech, opabs] + oddop := [opsin, opcsc, optan, opcot, opasin, opacsc, opatan, + opsinh, opcsch, optanh, opcoth, opasinh, opacsch,opatanh,opacoth, + opsi, operf] + +-- operators whose second argument is a dummy variable + dummyvarop1 := [opdiff,opalg, opint, opsum, opprod] +-- operators whose second and third arguments are dummy variables + dummyvarop2 := [opdint, opdsum, opdprod] + + operator s == + if (deref brandNew?) then startUp false + for op in allop repeat + is?(op, s) => return copy op + operator(s)$OP + + dpi l == "%pi"::Symbol::O + dfact x == postfix("!"::Symbol::O, (ATOM(x)$Lisp => x; paren x)) + dquote l == prefix(quote(first(l)::O), rest l) + dgamma l == prefix(hconcat("|"::Symbol::O, overbar(" "::Symbol::O)), l) + setDummyVar(op, n) == setProperty(op, DUMMYVAR, n pretend None) + + dexp x == + e := "%e"::Symbol::O + x = 1::O => e + e ** x + + startUp b == + brandNew?() := b + display(oppren, paren) + display(opbox, commaSeparate) + display(oppi, dpi) + display(opexp, dexp) + display(opGamma, dgamma) + display(opGamma2, dgamma) + display(opfact, dfact) + display(opquote, dquote) + display(opperm, supersub("A"::Symbol::O, #1)) + display(opbinom, binomial(first #1, second #1)) + display(oppow, first(#1) ** second(#1)) + display(opsum, sum(first #1, second #1, third #1)) + display(opprod, prod(first #1, second #1, third #1)) + display(opint, int(first #1 * hconcat("d"::Symbol::O, second #1), + empty(), third #1)) + input(oppren, convert concat(convert("("::Symbol)@InputForm, + concat(#1, convert(")"::Symbol)@InputForm))) + input(oppow, convert concat(convert("**"::Symbol)@InputForm, #1)) + input(oproot, + convert [convert("**"::Symbol)@InputForm, first #1, 1 / second #1]) + for op in algop repeat assert(op, ALGOP) + for op in rtrigop repeat assert(op, "rtrig") + for op in htrigop repeat assert(op, "htrig") + for op in trigop repeat assert(op, "trig") + for op in elemop repeat assert(op, "elem") + for op in primop repeat assert(op, "prim") + for op in combop repeat assert(op, "comb") + for op in specop repeat assert(op, "special") + for op in anyop repeat assert(op, "any") + for op in evenop repeat assert(op, EVEN) + for op in oddop repeat assert(op, ODD) + for op in dummyvarop1 repeat setDummyVar(op, 1) + for op in dummyvarop2 repeat setDummyVar(op, 2) + assert(oppren, "linear") + void + +@ +\section{License} +<<license>>= +--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +--All rights reserved. +-- +--Redistribution and use in source and binary forms, with or without +--modification, are permitted provided that the following conditions are +--met: +-- +-- - Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- - Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in +-- the documentation and/or other materials provided with the +-- distribution. +-- +-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the +-- names of its contributors may be used to endorse or promote products +-- derived from this software without specific prior written permission. +-- +--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +@ +<<*>>= +<<license>> + +-- SPAD files for the functional world should be compiled in the +-- following order: +-- +-- OP kl expr function + +<<domain BOP BasicOperator>> +<<package BOP1 BasicOperatorFunctions1>> +<<package COMMONOP CommonOperators>> +@ +\eject +\begin{thebibliography}{99} +\bibitem{1} nothing +\end{thebibliography} +\end{document} |