aboutsummaryrefslogtreecommitdiff
path: root/src/algebra/op.spad.pamphlet
diff options
context:
space:
mode:
Diffstat (limited to 'src/algebra/op.spad.pamphlet')
-rw-r--r--src/algebra/op.spad.pamphlet541
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}