|
|
last edited 11 years ago by test1 |
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 | ||
Editor: Bill Page
Time: 2008/07/07 13:48:20 GMT-7 |
||
Note: Re: will be problematic |
added:
From BillPage Mon Jul 7 13:48:14 -0700 2008
From: Bill Page
Date: Mon, 07 Jul 2008 13:48:14 -0700
Subject: Re: will be problematic
Message-ID: <20080707134814-0700@axiom-wiki.newsynthesis.org>
I agree that the type 'Union(Variable d,Integer)' alone is not
sufficient for symbolic computation. But although it might look
strange, in fact a result of 'Polynomial Integer' for '2*d' is
not really a problem. Remember that the use of 'Integer' in
'Polynomial Integer' does not mean that evaluation of the
polynomial yields an 'Integer' - it means only that the domain
of the coefficients of the polynomial are integers (i.e. that
2 is an integer), it says nothing about 'd':
\begin{axiom}
p:=2*d
eval(p,d=3.14)
\end{axiom}
But there is still a problem since I can write:
\begin{axiom}
a:Union(Variable a,Integer)
a:=3.14
p:=2*a
eval(p,a=3.14)
\end{axiom}
and Axiom does not complain about the 'eval' request because
as far as 'Polynomial Integer' is concerned 'd' is just a
Symbol.
In the case of the example 'Indeterminant' domain, evaluation
of symbolic expressions is always delayed so an appropriate
'eval' operation could be defined that properly respects the
type.
Symbolic Integers
A simple form of symbolic computation using just Variable and Integer.
axioma:Union(Variable a,Integer)
axiomb:Union(Variable b,Integer)
axiomc:=a*3-b*2
(1) |
axiomp:UP(x,Integer):=x*2-7
(2) |
axiompc := p c
(3) |
axiomf(x)==x^3-x^2+1
axiomfb := f b
Compiling function f with type Variable b -> Polynomial Integer
(4) |
axioma:=1
(5) |
axiomb:=-3
(6) |
axiomc
(7) |
axiomeval(pc,['a=a,'b=b])
(8) |
axiomeval(c,['a=a,'b=b])
(9) |
axiomeval(fb,['a=a,'b=b])
(10) |
axioma:=3.14 -- not permitted!Cannot convert right-hand side of assignment 3.14
to an object of the type Union(Variable a,Integer) of the left-hand side. a:='b -- not permitted!
Cannot convert right-hand side of assignment b
to an object of the type Union(Variable a,Integer) of the left-hand side.
For more complex cases it is necessary to define a new domain of "indeterminants". These are symbols and unevaluated expressions that can be evaluated at a later time. This domain is modeled after InputForm? which provides all of the basic functionality.
spad)abbrev domain INDET Indeterminant ++ Description: ++ Based on InputForm Indeterminant(): Join(SExpressionCategory(String,Symbol,Integer,DoubleFloat,OutputForm), ConvertibleTo SExpression) with eval: % -> Any ++ eval(f) passes f to the interpreter. binary : (%, List %) -> % ++ \spad{binary(op, [a1,...,an])} returns the input form ++ corresponding to \spad{a1 op a2 op ... op an}. function : (%, List Symbol, Symbol) -> % ++ \spad{function(code, [x1,...,xn], f)} returns the input form ++ corresponding to \spad{f(x1,...,xn) == code}. lambda : (%, List Symbol) -> % ++ \spad{lambda(code, [x1,...,xn])} returns the input form ++ corresponding to \spad{(x1,...,xn) +-> code} if \spad{n > 1}, ++ or to \spad{x1 +-> code} if \spad{n = 1}. "+" : (%, %) -> % ++ \spad{a + b} returns the input form corresponding to \spad{a + b}. "-" : (%, %) -> % ++ \spad{a - b} returns the input form corresponding to \spad{a - b}. "-" : % -> % ++ \spad{-a} returns the input form corresponding to \spad{-a}. "*" : (%, %) -> % ++ \spad{a * b} returns the input form corresponding to \spad{a * b}. "/" : (%, %) -> % ++ \spad{a / b} returns the input form corresponding to \spad{a / b}. "**" : (%, NonNegativeInteger) -> % ++ \spad{a ** b} returns the input form corresponding to \spad{a ** b}. "**" : (%, Integer) -> % ++ \spad{a ** b} returns the input form corresponding to \spad{a ** b}. unparse : % -> String ++ unparse(f) returns a string s such that the parser ++ would transform s to f. ++ Error: if f is not the parsed form of a string. declare : List % -> Symbol ++ declare(t) returns a name f such that f has been ++ declared to the interpreter to be of type t, but has ++ not been assigned a value yet. ++ Note: t should be created as \spad{devaluate(T)$Lisp} where T is the ++ actual type of f (this hack is required for the case where ++ T is a mapping type). compile : (Symbol, List %) -> Symbol ++ \spad{compile(f, [t1,...,tn])} forces the interpreter to compile ++ the function f with signature \spad{(t1,...,tn) -> ?}. ++ returns the symbol f if successful. ++ Error: if f was not defined beforehand in the interpreter, ++ or if the ti's are not valid types, or if the compiler fails. coerce : Integer -> % == SExpression add Rep := SExpressionmkProperOp: Symbol -> % strsym : % -> String tuplify : List Symbol -> %
coerce(x:Integer):% == convert(x) coerce(x:%):OutputForm == expr x
convert(x:%):SExpression == x pretend SExpression
conv(ll : List %): % == convert(ll pretend List SExpression)$SExpression pretend %
lambda(f,l) == conv([convert("+->"::Symbol),tuplify l,f]$List(%))
eval x == v := interpret(x)$Lisp mkObj(unwrap(objVal(v)$Lisp)$Lisp, objMode(v)$Lisp)$Lisp
convert(x:DoubleFloat):% == convert(x)$Rep
strsym s == string? s => string s symbol? s => string symbol s error "strsym: form is neither a string or symbol"
unparse x == atom?(s:% := form2String(x)$Lisp) => strsym s concat [strsym a for a in destruct s]
declare signature == declare(name := new()$Symbol, signature)$Lisp name
compile(name, types) == symbol car cdr car selectLocalMms(mkProperOp name, convert(name)@%, types, nil$List(%))$Lisp
mkProperOp name == op := mkAtree(nme := convert(name)@%)$Lisp transferPropsToNode(nme, op)$Lisp convert op
binary(op, args) == (n := #args) < 2 => error "Need at least 2 arguments" n = 2 => convert([op, first args, last args]$List(%)) convert([op, first args, binary(op, rest args)]$List(%))
tuplify l == empty? rest l => convert first l conv concat(convert("Tuple"::Symbol), [convert x for x in l]$List(%))
function(f, l, name) == nn := convert(new(1 + #l, convert(nil()$List(%)))$List(%))@% conv([convert("DEF"::Symbol), conv(cons(convert(name)@%, [convert(x)@% for x in l])), nn, nn, f]$List(%))
s1 + s2 == conv [convert("+"::Symbol), s1, s2]$List(%)
s1 - s2 == conv [convert("-"::Symbol), s1, s2]$List(%)
_-(s1) == conv [convert("-"::Symbol), s1]$List(%)
s1 * s2 == conv [convert("*"::Symbol), s1, s2]$List(%)
s1:% ** n:Integer == conv [convert("**"::Symbol), s1, convert n]$List(%)
s1:% ** n:NonNegativeInteger == s1 ** (n::Integer)
s1 / s2 == conv [convert("/"::Symbol), s1, s2]$List(%)
Compiling FriCAS source code from file /var/zope2/var/LatexWiki/7483143363411555740-25px002.spad using old system compiler. INDET abbreviates domain Indeterminant ------------------------------------------------------------------------ initializing NRLIB INDET for Indeterminant compiling into NRLIB INDET compiling exported coerce : Integer -> $ Time: 0.04 SEC.compiling exported coerce : $ -> OutputForm Time: 0.01 SEC.
compiling exported convert : $ -> SExpression INDET;convert;$Se;3 is replaced by x Time: 0 SEC.
compiling local conv : List $ -> $ Time: 0.10 SEC.
compiling exported lambda : ($,List Symbol) -> $ Time: 0.01 SEC.
compiling exported eval : $ -> Any Time: 0 SEC.
compiling exported convert : DoubleFloat -> $ Time: 0 SEC.
compiling local strsym : $ -> String Time: 0.02 SEC.
compiling exported unparse : $ -> String Time: 0.06 SEC.
compiling exported declare : List $ -> Symbol Time: 0.01 SEC.
compiling exported compile : (Symbol,List $) -> Symbol Time: 0 SEC.
compiling local mkProperOp : Symbol -> $ Time: 0 SEC.
compiling exported binary : ($,List $) -> $ Time: 0.04 SEC.
compiling local tuplify : List Symbol -> $ Time: 0.07 SEC.
compiling exported function : ($,List Symbol,Symbol) -> $ Time: 0.03 SEC.
compiling exported + : ($,$) -> $ Time: 0.01 SEC.
compiling exported - : ($,$) -> $ Time: 0 SEC.
compiling exported - : $ -> $ Time: 0.01 SEC.
compiling exported * : ($,$) -> $ Time: 0.06 SEC.
compiling exported ** : ($,Integer) -> $ Time: 0.01 SEC.
compiling exported ** : ($,NonNegativeInteger) -> $ Time: 0 SEC.
compiling exported / : ($,$) -> $ Time: 0.01 SEC.
(time taken in buildFunctor: 1)
;;; *** |Indeterminant| REDEFINED
;;; *** |Indeterminant| REDEFINED Time: 0.01 SEC.
Warnings: [1] conv: pretend$ -- should replace by @
Cumulative Statistics for Constructor Indeterminant Time: 0.50 seconds
finalizing NRLIB INDET Processing Indeterminant for Browser database: --------(eval ((Any) %))--------- --------(binary (% % (List %)))--------- --------(function (% % (List (Symbol)) (Symbol)))--------- --------(lambda (% % (List (Symbol))))--------- --------(+ (% % %))--------- --------(- (% % %))--------- --------(- (% %))--------- --------(* (% % %))--------- --------(/ (% % %))--------- --------(** (% % (NonNegativeInteger)))--------- --------(** (% % (Integer)))--------- --------(unparse ((String) %))--------- --------(declare ((Symbol) (List %)))--------- --------(compile ((Symbol) (Symbol) (List %)))--------- --->-->Indeterminant((coerce (% (Integer)))): Not documented!!!! --------constructor--------- ------------------------------------------------------------------------ Indeterminant is now explicitly exposed in frame initial Indeterminant will be automatically loaded when needed from /var/zope2/var/LatexWiki/INDET.NRLIB/code
Symbolic Matrices
axiom)clear allAll user variables and function definitions have been cleared.
axiomm:Union(Indeterminant,Matrix Integer)
axiomn:Union(Indeterminant,Matrix Integer)
axioma:Union(Indeterminant,Integer)
axiomb:Union(Indeterminant,Integer)
axiomab:=(3*a+b)*(a-2*b)
(11) |
axioma:=1$Integer -- because 0 and 1 can be symbolic!
(12) |
axiomeval ab
(13) |
axiomb:=0$Integer
(14) |
axioma:=-10
(15) |
axiomeval ab
(16) |
axiommn1:= m*n-n*m
(17) |
axiommn2:=(m+n)*(m-n-1)
(18) |
axiomm:=matrix [[1,2],[3,4]]
(19) |
axiomn:=matrix [[-1,-2],[-3,4]]
(20) |
axiomeval mn1
(21) |
axiomeval mn2
(22) |
axiom)clear all
All user variables and function definitions have been cleared.
axiomd: Union(Variable d, Float)
axiomd*2
(23) |
will be problematic, and the assignment between symbolic integers is not allowed.
axioma: Union(Variable a, Integer)
axiomb: Union(Variable b, Integer)
axiomb:=aa is declared as being in Union(Variable a,Integer) but has not been given a value.
Union(Variable d,Integer)
alone is not
sufficient for symbolic computation. But although it might look
strange, in fact a result of Polynomial Integer
for 2*d
is
not really a problem. Remember that the use of Integer
in
Polynomial Integer
does not mean that evaluation of the
polynomial yields an Integer
- it means only that the domain
of the coefficients of the polynomial are integers (i.e. that
2 is an integer), it says nothing about 'd':
axiomp:=2*d
(1) |
axiomeval(p,d=3.14)
(2) |
But there is still a problem since I can write:
axioma:Union(Variable a,Integer)
axioma:=3.14Cannot convert right-hand side of assignment 3.14
to an object of the type Union(Variable a,Integer) of the left-hand side. p:=2*a
(3) |
axiomeval(p,a=3.14)
(4) |
and Axiom does not complain about the eval
request because
as far as Polynomial Integer
is concerned d
is just a
Symbol.
In the case of the example Indeterminant
domain, evaluation
of symbolic expressions is always delayed so an appropriate
eval
operation could be defined that properly respects the
type.