123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 |
- omfuncs!*:=
- '((oma . (omaIR))
- (oms . (omsIR))
- (omi . (omiIR))
- (omv . (omvIR))
- (omf . (omfIR))
- (omstr . (omstrIR))
- (ombind . (ombindIR))
- (omattr . (omattrIR)));
- symbolic procedure om2ir();
- begin scalar res;
- % Initialisation of important variables used by the lexer.
- res:=nil;
- FLUID '(safe_atts char ch atts count temp space temp2);
- space:=int2id(32);
- count:=0;
- ch:=readch();
- temp2:=nil;
- % Begining of lexing and parsing
- lex();
- if char='(o m o b j) then <<
- lex();
- res:=omobj();
- >>
- else errorML("<omobj>",2);
- lex();
- if char='(!/ o m o b j) then
- terpri()
- else errorML("</omobj>",19);
- return res;
- end;
- symbolic procedure omobj();
- begin scalar aa, res;
- % We check what the OpenMath tag is and call the appropriate function. The relationship
- % between OpenMath tag and function to be called is in table omfuncs!*.
- if (aa:=assoc(compress!* char, omfuncs!*)) then return apply(cadr aa, nil);
- end;
- % The following function recursively reads in objects as defined in
- % the OpenMath grammar in the OpenMath standard.
- symbolic procedure omobjs();
- begin scalar obj, objs;
- if char neq '(!/ o m a) then <<
- obj:=omobj();
- lex();
- objs:=omobjs();
- if obj eq nil then
- return append(obj, objs)
- else
- return cons(obj, objs);
- >>;
- end;
- % Checks if the current token is equivalent to the given tag.
- symbolic procedure checkTag(tag);
- begin;
- if char neq tag then errorML("Problem", "problem");
- end;
- % This function returns the symbol read within an <OMS> tag.
- % It will also check in the mmleq!* table what the equivalent
- % MathML symbol is. If there isnt any it encodes the symbol
- % for use in a <semantic> tag.
- symbolic procedure omsIR();
- begin scalar cd, name, sem, aa, bb, cd, attr, symb, validcd;
- attr:=nil;
- % We read in from the input the name and CD contained
- % in the OMS tag.
- name:= intern find(atts, 'name);
- cd:= intern find(atts, 'cd);
- % We check if the symbol has a MathML equivalent
- % in the mmleq!* table.
- % But when dealing with a vector, REDUCE works differently
- % hence we have to deal with vectors independently.
- if explode name = '(v e c t o r) then aa:='(vectorml linalg1)
- else aa:=member (intern name, mmleq!*);
- % If nothing was found, we check to see if we are
- % dealing with a special case.
- % If so, we retrieve from the table special_cases!*
- % the equivalent MathML symbol and the correct
- % attribute to add.
-
- if aa=nil then <<
- if (aa:=assoc(name, special_cases!*)) then <<
- attr:=car reverse aa;
- if attr neq nil then attr:=list attr;
- aa:=cadr reverse aa . reverse cddr reverse cdr aa
- >>
- else
- % Here we call special case functions
- % because the tranlation needs some care.
- if (bb:=assoc(name, special_cases2!*)) neq nil then <<
- return apply(cadr bb, cddr bb)
- >>;
- >>;
- % We now check if aa is still nothing, or if the CD
- % given in the input does not match one of the CDs
- % contained in aa which map to MathML. If so, we
- % envelope the input into a semantic tag.
- if aa neq nil then validcd:= assoc(car aa, valid_om!*);
- if validcd neq nil then validcd:=cadr validcd;
- %debug("validcd: ",validcd);
- if aa eq nil OR cd=validcd eq nil then <<
- sem:=encodeIR(name);
- return sem;
- >>;
- % If we are dealing with a vector, we change it to IR rep which
- % is vectorml
- return list(car aa, attr);
- end;
- % The following function encodes an unknown symbol into a
- % valid representation for use within <semantic> tags.
- symbolic procedure encodeIR(name);
- begin scalar sem;
- sem:=append(char, cons('! , atts));
- sem:=delall('!$, sem);
- return cons('semantic, list cons(name, list sem));
- end;
- lisp operator om2mml;
- symbolic procedure omiIR();
- begin scalar int;
- lex();
- int := compress char;
- lex();
- return int;
- end;
- symbolic procedure omvIR();
- begin scalar name;
- name:=find(atts, 'name);
- if find(atts, 'hex) neq nil then errorML("wrong att", 2);
- if find(atts, 'dec) neq nil then errorML("wrong att", 2);
- return name;
- end;
- symbolic procedure variablesIR();
- begin scalar var, vars;
- if char neq '(!/ o m b v a r) then <<
- var:=omvIR();
- lex();
- vars:=variablesIR();
- if var eq nil then
- return append(var, vars)
- else
- return cons(var, vars);
- >>;
- end;
- symbolic procedure omfIR();
- begin scalar float;
- float:=find(atts, 'dec);
- if find(atts, 'name) neq nil then errorML("wrong att", 2);
- return float;
- end;
- symbolic procedure omstrIR();
- begin scalar str;
- lex();
- str := compress char;
- lex();
- return cons('string, list str);
- end;
- symbolic procedure omaIR();
- begin scalar obj, elems;
- lex();
- obj:=omobj();
- % If we are dealing with a matrix the following code
- % is not executed because the MatrixIR function
- % does the input reading and checks when it has
- % reached the closing </OMA> tag.
- if car obj neq 'matrix then <<
- lex();
- elems:=omobjs();
- checkTag('(!/ o m a));
- >>;
- return append(obj, elems);
- end;
- symbolic procedure ombindIR();
- begin scalar symb, vars, obj;
- lex();
- symb:=omobj();
- lex();
- vars:=toBvarIR variablesIR();
- lex();
- obj:=omobj();
- lex();
- checkTag('(!/ o m b i n d));
- return append(symb , append(vars, list obj));
- end;
- symbolic procedure omattrIR();
- begin scalar omatp, var;
- lex();
- omatp:=omatpIR();
- lex();
- var:=omobj();
- lex();
- checkTag('(!/ o m a t t r));
- if PAIRP omatp then if cadar omatp = 'csymbol then return (var . list nil);
- if NUMBERP var then return list('cn, omatp, var);
- return list('ci, omatp, var);
- end;
- symbolic procedure omatpIR();
- begin scalar symb ,obj;
- lex();
- symb:=car omsIR();
- lex();
- obj:=car omobj();
- lex();
- checkTag('(!/ o m a t p));
- return list (symb . list obj);
- end;
- % The following function transforms a list of variables
- % into a list of bvar constructs. ie: (x y)->((bvar x 1)(bvar y 1))
- symbolic procedure toBvarIR(bv);
- begin;
- if bv neq nil then return cons(cons('bvar, list(car bv, 1)), toBvarIR(cdr bv));
- end;
- % From here onwards, functions necessary to deal with
- % OpenMath special operators are defined. This is where
- % matrix, int, sum, prod, diff etc... are treated.
- symbolic procedure matrixIR();
- begin scalar res;
- lex();
- res:=omobjs();
- if caadr cadr res = 'matrixcolumn then res := 'matrixcolumn . list matrixelems(res)
- else res := 'matrixrow . list matrixelems(res);
- return 'matrix . nil . res;
- end;
- symbolic procedure matrixelems(elem);
- if elem neq nil then cons(cddr car elem, matrixelems cdr elem);
- symbolic procedure sum_prodIR();
- begin scalar var, fun, int, name;
- name:=intern find(atts, 'name);
- lex();
- int:=omobj();
- int:='lowupperlimit . (cdr int);
- lex();
- fun:=omobj();
- var:=lambdaVar fun;
- fun:=lambdaFun fun;
- return append(list(name , nil) , append(var , int . list fun));
- return name . nil . var . int . list fun;
- end;
- symbolic procedure integralIR();
- begin scalar int, fun, var, tag;
- tag:=intern find(atts, 'name);
- var:=list '(bvar x 1);
- int:=nil;
- % if dealing with defint, determine the interval
- % and store inside variable int
- if tag = 'defint then <<
- lex();
- int:=omobj();
- >>;
- lex();
- fun:=omobj();
- if PAIRP fun then if car fun = 'lambda then <<
- var:=lambdaVar fun;
- fun:=lambdaFun fun;
- >>;
- return append(list(tag , nil) , append(var , list fun));
- end;
- symbolic procedure partialdiffIR();
- begin scalar lis, fun, var, tag, vars;
- tag:=intern find(atts, 'name);
- lex();
- lis:=omobj();
- if car lis='list then lis:=cddr lis
- else errorML("",3);
- lex();
- fun:=omobj();
- if PAIRP fun then
- if car fun = 'lambda then <<
- var:=lambdaVar fun;
- fun:=lambdaFun fun;
- vars:= pdiffvars(lis, var);
- >>;
-
- return append(list('partialdiff , nil) , append(vars , list fun));
- end;
- symbolic procedure pdiffvars(ind, v);
- begin;
- return if ind neq nil then nth(v, car ind) . pdiffvars(cdr ind, v);
- end;
- symbolic procedure selectIR();
- begin scalar name, cd, a,b, c, tag;
- name:=intern find(atts, 'name);
- cd:=intern find(atts, 'cd);
- tag:=list 'selector;
- if member(cd, '(linalg3)) eq nil then tag:=encodeIR(name);
- lex();
- a:=omobj();
- if name='matrix_selector then <<
- lex();
- b:=omobj();
- >>;
- lex();
- c:=omobj();
- if name='matrix_selector then <<
- return append(tag, nil . c . a . list b);
- >>;
- return append(tag, nil . c . list a);
- end;
- symbolic procedure limitIR();
- begin scalar val, type, cd, fun, var, res, tag;
- cd:=intern find(atts, 'cd);
- tag:=list 'limit;
- if member(cd, '(limit1)) eq nil then tag:=encodeIR('limit);
- lex();
- val:=omobj();
- lex();
- type:=omobj();
- lex();
- fun:=omobj();
-
- % Extract the necessary information from the OpenMath read in just above.
- type:=caadr type;
- if member(type, '(below above both_sides null)) eq nil then errorML("wrong method of approach", 2);
- if type='null then type:='both_sides;
- var:= lambdaVar fun;
- fun:= lambdaFun fun;
- % Transform that information into intermediate representation.
- res:= append(tag, (nil . var ));
- if type neq 'both_sides then
- res:= append(res , list ('condition . list ('tendsto . list ('type . list type) . cadr car var . list val)))
- else
- res:= append(res , list ('condition . list ('tendsto . nil . cadr car var . list val)));
- res:= append(res, list fun);
- return res;
- end;
- symbolic procedure numIR();
- begin scalar base, a1, a2, tag;
- tag:=intern find(atts, 'name);
- lex();
- a1:=omobj();
- lex();
- a2:=omobj();
- if tag = 'complex_cartesian then <<
- if IDP a1 OR IDP a2 then return 'plus . nil . a1 . list ('times . nil . a2 . list '!&imaginaryi!;)
- >>;
- if tag = 'complex_polar then <<
- if IDP a1 OR IDP a2 then return 'times . nil . a1 . list ('exp . nil . list ('times . nil . a2 . list '!&imaginaryi!;))
- >>;
- if tag = 'rational then <<
- if IDP a1 OR IDP a2 then return 'divide . nil . a1 . list a2;
- >>;
- return tag . nil . a1. list a2;
- end;
- % The following function deals with OpenMath symbols
- % not taking any arguments such as false, true, zero, etc...
- symbolic procedure unaryIR(validcd, tag);
- begin scalar name, cd;
- name:=intern find(atts, 'name);
- cd:=intern find(atts, 'cd);
- if cd neq validcd then return encodeIR name;
- return tag;
- end;
- % Returns the first main variable of a lambda expression
- symbolic procedure lambdaVar(l);
- begin;
- return cdr reverse cddr l;
- end;
- symbolic procedure lambdaVar2(l);
- begin;
- return cadr caddr l;
- end;
- % Returns the function of a lambda expression
- symbolic procedure lambdaFun(l);
- begin;
- return car reverse l;
- end;
- % This function is the one the user types to
- % translate OpenMath to MathML.
- symbolic procedure om2mml();
- begin scalar ir;
- ir:=om2ir();
- terpri!* t;
- princ "Intermediate representation:";
- terpri!* t;
- princ ir;
- terpri!* t;
- ir2mml ir;
- end;
- end;
|