<Chapter Label="OpenMathFunctionality">
<Heading>&OpenMath; functionality in &GAP;</Heading>    


<Section Label="ViewOpenMath">
<Heading>Viewing &OpenMath; representation of an object</Heading>

<#Include Label="OMPrint">

Producing &OpenMath; representation of polynomials, one may get a warning:

<Log>
<![CDATA[
gap> x:=Indeterminate(Rationals,"x");; y:=Indeterminate(Rationals,"y");;
gap> OMPrint(x^2+y);
#I  Warning : polynomial will be printed using its default ring 
#I  because the default OpenMath polynomial ring is not specified 
#I  or it is not contained in the default OpenMath polynomial ring.
#I  You may ignore this or call SetOpenMathDefaultPolynomialRing to fix it.
<OMOBJ xmlns="http://www.openmath.org/OpenMath" version="2.0">
	<OMA>
		<OMS cd="polyd1" name="DMP"/>
		<OMA id="polyring9qiY2oOaiITWUORb" >
			<OMS cd="polyd1" name="poly_ring_d"/>
			<OMS cd="setname1" name="Q"/>
			<OMI>2</OMI>
		</OMA>
		<OMA>
			<OMS cd="polyd1" name="SDMP"/>
			<OMA>
				<OMS cd="polyd1" name="term"/>
				<OMI>1</OMI>
				<OMI>0</OMI>
				<OMI>1</OMI>
			</OMA>
			<OMA>
				<OMS cd="polyd1" name="term"/>
				<OMI>1</OMI>
				<OMI>2</OMI>
				<OMI>0</OMI>
			</OMA>
		</OMA>
	</OMA>
</OMOBJ>
]]>
</Log>
Indeed, now when another polynomial will be printed, it will belong to a
ring with a different identifier (despite &GAP; will be able to perform
arithmetical operations on these polynomials like when they belong to the
same ground ring):
<Log>
<![CDATA[
gap> OMPrint(x+1);
#I  Warning : polynomial will be printed using its default ring 
#I  because the default OpenMath polynomial ring is not specified 
#I  or it is not contained in the default OpenMath polynomial ring.
#I  You may ignore this or call SetOpenMathDefaultPolynomialRing to fix it.
<OMOBJ xmlns="http://www.openmath.org/OpenMath" version="2.0">
	<OMA>
		<OMS cd="polyd1" name="DMP"/>
		<OMA id="polyring0LqlkhnCyLldcoBl" >
			<OMS cd="polyd1" name="poly_ring_d_named"/>
			<OMS cd="setname1" name="Q"/>
			<OMV name="x"/>
		</OMA>
		<OMA>
			<OMS cd="polyd1" name="SDMP"/>
			<OMA>
				<OMS cd="polyd1" name="term"/>
				<OMI>1</OMI>
				<OMI>1</OMI>
			</OMA>
			<OMA>
				<OMS cd="polyd1" name="term"/>
				<OMI>1</OMI>
				<OMI>0</OMI>
			</OMA>
		</OMA>
	</OMA>
</OMOBJ>
]]>
</Log>
Thus, the warning means that it is not guaranteed that the polynomial ring
will have the same identifier <C>&lt;OMA id="polyring..." ></C> when
another or same polynomial from this ring will be printed next time.
If this may constitute a problem, for example, if a list of polynomial
is being exchanged with another system and it is crucial that all of
them will belong to the same ring, then such ring must be created
explicitly and then <C>SetOpenMathDefaultPolynomialRing</C> must be
called:
<Log>
<![CDATA[
gap> x:=Indeterminate(Rationals,"x");; y:=Indeterminate(Rationals,"y");;
gap> R:=PolynomialRing(Rationals,[x,y]);;
gap> SetOpenMathDefaultPolynomialRing(R);
gap> OMPrint(x^2+y);
<OMOBJ xmlns="http://www.openmath.org/OpenMath" version="2.0">
	<OMA>
		<OMS cd="polyd1" name="DMP"/>
		<OMA id="polyring9eNcBGFHXkjl2kWh" >
			<OMS cd="polyd1" name="poly_ring_d"/>
			<OMS cd="setname1" name="Q"/>
			<OMI>2</OMI>
		</OMA>
		<OMA>
			<OMS cd="polyd1" name="SDMP"/>
			<OMA>
				<OMS cd="polyd1" name="term"/>
				<OMI>1</OMI>
				<OMI>0</OMI>
				<OMI>0</OMI>
			</OMA>
			<OMA>
				<OMS cd="polyd1" name="term"/>
				<OMI>1</OMI>
				<OMI>0</OMI>
				<OMI>0</OMI>
			</OMA>
		</OMA>
	</OMA>
</OMOBJ>
]]>
</Log>
Now we can see that both polynomials belong to the ring with the same 
identifier, and the &OpenMath; representation of the 2nd polynomial 
properly reflects that it belongs to a polynomial ring with two variables.
<Log>
<![CDATA[
gap> OMPrint(x+1);  
<OMOBJ xmlns="http://www.openmath.org/OpenMath" version="2.0">
	<OMA>
		<OMS cd="polyd1" name="DMP"/>
		<OMR href="#polyring9eNcBGFHXkjl2kWh" />
		<OMA>
			<OMS cd="polyd1" name="SDMP"/>
			<OMA>
				<OMS cd="polyd1" name="term"/>
				<OMI>1</OMI>
				<OMI>0</OMI>
				<OMI>0</OMI>
			</OMA>
			<OMA>
				<OMS cd="polyd1" name="term"/>
				<OMI>1</OMI>
				<OMI>0</OMI>
				<OMI>0</OMI>
			</OMA>
		</OMA>
	</OMA>
</OMOBJ> 
]]>
</Log>

<#Include Label="OMString">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->

<Section Label="Reading OpenMath from streams">
<Heading>Reading &OpenMath; code from streams and strings</Heading>

<#Include Label="OMGetObject">
<#Include Label="EvalOMString">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->

<Section Label="Writing OpenMath to streams">
<Heading>Writing &OpenMath; code to streams</Heading>

While it is possible to read &OpenMath; code directly from a stream,
writing &OpenMath; to streams uses a different setup. It requires 
special objects called &OpenMath; <E>writers</E>, which encapsulate 
streams and may be viewed as transducers accepting &GAP; objects and 
writing them to a stream in the XML or binary &OpenMath;
<P/>
Such setup makes it possible to re-use the same stream for both binary 
and XML &OpenMath; communication, using different &OpenMath; writers 
in different calls. It also allows to re-use most of the high-level
code for &GAP; to &OpenMath; conversion, having separate methods for
generating binary and XML &OpenMath; only for low-level output 
(&OpenMath; tags and basic objects). This makes easier adding support 
to new mathematical objects and private content dictionaries as described 
in Chapter <Ref Chap="ExtendingOpenMath"/> since it does not require 
changing the low-level functionality.
<P/>

<#Include Label="IsOpenMathWriter">
<#Include Label="OpenMathXMLWriter">
<#Include Label="OpenMathBinaryWriter">
<#Include Label="OMPutObject">
<#Include Label="OMPlainString">

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->

<Section Label="Utilities">
<Heading>Utilities</Heading>

<#Include Label="OMTestXML">
<#Include Label="OMTestBinary">

</Section>

</Chapter>