GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
########################################################################### ## #W xmltree.gi OpenMath Package Andrew Solomon #W Marco Costantini ## #Y Copyright (C) 1999, 2000, 2001, 2006 #Y School Math and Comp. Sci., University of St. Andrews, Scotland #Y Copyright (C) 2004, 2005, 2006 Marco Costantini ## ## The main function in this file converts the OpenMath XML into a tree ## (using the function ParseTreeXMLString from package GapDoc) and ## parses it. ## BindGlobal( "OMTempVars", rec( OMBIND := rec( ), OMREF := rec( ) ) ); MakeReadWriteGlobal("OMTempVars"); BindGlobal( "OMIsNotDummyLeaf", node -> not node.name = "PCDATA" and not node.name = "XMLCOMMENT"); BindGlobal( "OMObjects", rec( # Basic OpenMath objects OMB := function ( node ) return node.content[1].content; end, OMF := function ( node ) if not IsBound( node.attributes.dec ) then Error( "hexadecimal encoding of floats is not supported" ); fi; if CompareVersionNumbers( GAPInfo.Version, "4.5.0") then return Float( node.attributes.dec ); else return Float( node.attributes.dec ); fi; end, OMI := function ( node ) node.content[1].content := ReplacedString( node.content[1].content, " ", "" ); node.content[1].content := ReplacedString( node.content[1].content, "\n", "" ); node.content[1].content := ReplacedString( node.content[1].content, "\t", "" ); node.content[1].content := ReplacedString( node.content[1].content, "\r", "" ); if 'x' in node.content[1].content then return IntHexString( ReplacedString( node.content[1].content, "x", "" ) ); else return Int( node.content[1].content ); fi; end, OMSTR := function ( node ) local string; if node.content <> 0 then string := Concatenation( List( node.content, x -> x.content ) ); ConvertToStringRep( string ); else string := ""; fi; return string; end, OMS := function ( node ) # this is just a nullary symbol return OMsymLookup( [ node.attributes.cd, node.attributes.name ] ); end, OMV := function ( node ) if IsBound( OMTempVars.OMBIND.(node.attributes.name) ) then return OMTempVars.OMBIND.(node.attributes.name); fi; # a variable is returned as the string of its name return node.attributes.name; end, # Constructors of OpenMath objects OMA := function ( node ) local head, headfun; if node.content[1].name = "OMS" then head := OMsymLookup( [ node.content[1].attributes.cd, node.content[1].attributes.name ] ); else head := OMParseXmlObj( node.content[1] ); fi; # check if the head is not a function (e.f. when permutation1.endomap # (evaluated in GAP as Transformation) is be used a head if not IsFunction(head) then headfun := function(x) return x[1]^head; end; else headfun := head; fi; # extra check to achieve compatibility with SCSCP if IsBound(node.content[1].attributes.cd) and node.content[1].attributes.cd="scscp2" and node.content[1].attributes.name in [ "get_signature", "is_allowed_head" ] then return headfun( [ node.content[2].attributes.cd, node.content[2].attributes.name ] ); else return headfun( List( [ 2 .. Length( node.content ) ], x -> OMParseXmlObj( node.content[x] ) ) ); fi; end, OMATTR := function ( node ) node.content := Filtered( node.content, x -> x.name <> "OMATP" ); # the only thing we don't ignore - the unattributed object return OMParseXmlObj( node.content[1] ); end, OMBIND := function ( node ) local OMBVAR, string, i; # if not (node.content[1].attributes.cd = "fns1" and node.content[1].attributes.name = "lambda" and # node.content[1].name = "OMS" and node.content[2].name = "OMBVAR" ) then # Error( "this binding is unimplemented" ); # fi; node.content[2].content := Filtered( node.content[2].content, OMIsNotDummyLeaf ); if IsList( node.content[3].content ) then node.content[3].content := Filtered( node.content[3].content, OMIsNotDummyLeaf ); fi; OMBVAR := List( [ 1 .. Length( node.content[2].content ) ], x -> OMParseXmlObj( node.content[2].content[x] ) ); #Print( " OMBVAR = ", OMBVAR, "\n" ); #Print( " OMBVAR = ", OMBVAR, " node.content[3] = ", node.content[3], "\n" ); string := "function( "; for i in [ 1 .. Length( OMBVAR ) ] do Append( string, OMBVAR[i] ); if i < Length( OMBVAR ) then Append( string, ", " ); fi; od; Append( string, " )\n" ); for i in [ 1 .. Length( OMBVAR ) ] do Append( string, "OMTempVars.OMBIND." ); Append( string, OMBVAR[i] ); Append( string, " := " ); Append( string, OMBVAR[i] ); Append( string, ";\n" ); od; Append( string, "return OMParseXmlObj( " ); Append( string, String( node.content[3] ) ); Append( string, " );\n" ); Append( string, "end" ); return EvalString( string ); end, OME := function ( node ) if IsBound(node.content[1].attributes.cd) and node.content[1].attributes.cd="error" then Error( node.content[1].attributes.name, " : cd=", node.content[2].attributes.cd, ", name=", node.content[2].attributes.name, "\n" ); else Error( List( [ 2 .. Length( node.content ) ], x -> OMParseXmlObj( node.content[x] ) )[1], "\n", node.content[1].attributes ); fi; end, # Foreign OpenMath objects OMFOREIGN := function ( node ) return node; end, # References OMR := function ( node ) local ref; ref := node.attributes.href; return OMTempVars.OMREF.( ref{[ 2 .. Length( ref ) ]} ); end ) ); MakeReadWriteGlobal("OMObjects"); if CompareVersionNumbers( GAPInfo.Version, "4.5.0") then OMObjects.OMF := function ( node ) if not IsBound( node.attributes.dec ) then Error( "hexadecimal encoding of floats is not supported" ); fi; return Float( node.attributes.dec ); end; else OMObjects.OMF := function ( node ) if not IsBound( node.attributes.dec ) then Error( "hexadecimal encoding of floats is not supported" ); fi; return Float( node.attributes.dec ); end; fi; ############################################################################# #E