/usr/share/axiom-20170501/src/algebra/KERNEL.spad is in axiom-source 20170501-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | )abbrev domain KERNEL Kernel
++ Author: Manuel Bronstein
++ Date Created: 22 March 1988
++ Date Last Updated: 10 August 1994
++ Description:
++ A kernel over a set S is an operator applied to a given list
++ of arguments from S.
Kernel(S) : SIG == CODE where
S : OrderedSet
O ==> OutputForm
N ==> NonNegativeInteger
OP ==> BasicOperator
SYMBOL ==> "%symbol"
PMPRED ==> "%pmpredicate"
PMOPT ==> "%pmoptional"
PMMULT ==> "%pmmultiple"
PMCONST ==> "%pmconstant"
SPECIALDISP ==> "%specialDisp"
SPECIALEQUAL ==> "%specialEqual"
SPECIALINPUT ==> "%specialInput"
SIG ==> Join(CachableSet, Patternable S) with
name : % -> Symbol
++ name(op(a1,...,an)) returns the name of op.
operator : % -> OP
++ operator(op(a1,...,an)) returns the operator op.
argument : % -> List S
++ argument(op(a1,...,an)) returns \spad{[a1,...,an]}.
height : % -> N
++ height(k) returns the nesting level of k.
kernel : (OP, List S, N) -> %
++ kernel(op, [a1,...,an], m) returns the kernel \spad{op(a1,...,an)}
++ of nesting level m.
++ Error: if op is k-ary for some k not equal to m.
kernel : Symbol -> %
++ kernel(x) returns x viewed as a kernel.
symbolIfCan : % -> Union(Symbol, "failed")
++ symbolIfCan(k) returns k viewed as a symbol if k is a symbol, and
++ "failed" otherwise.
is? : (%, OP) -> Boolean
++ is?(op(a1,...,an), f) tests if op = f.
is? : (%, Symbol) -> Boolean
++ is?(op(a1,...,an), s) tests if the name of op is s.
if S has ConvertibleTo InputForm then ConvertibleTo InputForm
CODE ==> add
import SortedCache(%)
Rep := Record(op:OP, arg:List S, nest:N, posit:N)
clearCache()
B2Z : Boolean -> Integer
triage: (%, %) -> Integer
preds : OP -> List Any
is?(k:%, s:Symbol) == is?(operator k, s)
is?(k:%, o:OP) == (operator k) = o
name k == name operator k
height k == k.nest
operator k == k.op
argument k == k.arg
position k == k.posit
setPosition(k, n) == k.posit := n
B2Z flag == (flag => -1; 1)
kernel s == kernel(assert(operator(s,0),SYMBOL), nil(), 1)
preds o ==
(u := property(o, PMPRED)) case "failed" => nil()
(u::None) pretend List(Any)
symbolIfCan k ==
has?(operator k, SYMBOL) => name operator k
"failed"
k1 = k2 ==
if k1.posit = 0 then enterInCache(k1, triage)
if k2.posit = 0 then enterInCache(k2, triage)
k1.posit = k2.posit
k1 < k2 ==
if k1.posit = 0 then enterInCache(k1, triage)
if k2.posit = 0 then enterInCache(k2, triage)
k1.posit < k2.posit
kernel(fn, x, n) ==
((u := arity fn) case N) and (#x ^= u::N)
=> error "Wrong number of arguments"
enterInCache([fn, x, n, 0]$Rep, triage)
-- SPECIALDISP contains a map List S -> OutputForm
-- it is used when the converting the arguments first is not good,
-- for instance with formal derivatives.
coerce(k:%):OutputForm ==
(v := symbolIfCan k) case Symbol => v::Symbol::OutputForm
(f := property(o := operator k, SPECIALDISP)) case None =>
((f::None) pretend (List S -> OutputForm)) (argument k)
l := [x::OutputForm for x in argument k]$List(OutputForm)
(u := display o) case "failed" => prefix(name(o)::OutputForm, l)
(u::(List OutputForm -> OutputForm)) l
triage(k1, k2) ==
k1.nest ^= k2.nest => B2Z(k1.nest < k2.nest)
k1.op ^= k2.op => B2Z(k1.op < k2.op)
(n1 := #(argument k1)) ^= (n2 := #(argument k2)) => B2Z(n1 < n2)
((func := property(operator k1, SPECIALEQUAL)) case None) and
(((func::None) pretend ((%, %) -> Boolean)) (k1, k2)) => 0
for x1 in argument(k1) for x2 in argument(k2) repeat
x1 ^= x2 => return B2Z(x1 < x2)
0
if S has ConvertibleTo InputForm then
convert(k:%):InputForm ==
(v := symbolIfCan k) case Symbol => convert(v::Symbol)@InputForm
(f := property(o := operator k, SPECIALINPUT)) case None =>
((f::None) pretend (List S -> InputForm)) (argument k)
l := [convert x for x in argument k]$List(InputForm)
(u := input operator k) case "failed" =>
convert concat(convert name operator k, l)
(u::(List InputForm -> InputForm)) l
if S has ConvertibleTo Pattern Integer then
convert(k:%):Pattern(Integer) ==
o := operator k
(v := symbolIfCan k) case Symbol =>
s := patternVariable(v::Symbol,
has?(o, PMCONST), has?(o, PMOPT), has?(o, PMMULT))
empty?(l := preds o) => s
setPredicates(s, l)
o [convert x for x in k.arg]$List(Pattern Integer)
if S has ConvertibleTo Pattern Float then
convert(k:%):Pattern(Float) ==
o := operator k
(v := symbolIfCan k) case Symbol =>
s := patternVariable(v::Symbol,
has?(o, PMCONST), has?(o, PMOPT), has?(o, PMMULT))
empty?(l := preds o) => s
setPredicates(s, l)
o [convert x for x in k.arg]$List(Pattern Float)
|