<o:param name="servlet:req"/>
-<!-- This example implements a solution to the Eight Queens Problem,
how to place eight queens on a chess board in such a way that
no one queen threatens (is on the diagonal or straight line of)
any other -->
-<!-- define our types: Queen and QueenSolver
-->
-<o:type name="ex:Queen">
<o:variable name="row" select="1"/>
<o:variable name="column"/>
<o:variable name="neighbour"/>
-<o:function name="ex:Queen">
-<!-- type constructor
-->
<o:param name="column" type="Number"/>
<o:param name="neighbour"/>
-<!-- column and neighbour are automatically set from their parameter
-->
-<!-- values, row is set from default value
-->
</o:function>
-<o:function name="findSolution">
-<o:while test="$neighbour and $neighbour.canAttach($row, $column)">
-<o:if test="not($this.advance())">
<o:return select="false()"/>
</o:if>
</o:while>
<o:return select="true()"/>
</o:do>
</o:function>
-<o:function name="advance">
-<o:when test="$row < 8">
<o:return select="$this.findSolution()"/>
</o:when>
-<o:when test="$neighbour">
-<o:if test="not($neighbour.advance())">
<o:return select="false()"/>
</o:if>
-<o:if test="not($neighbour.findSolution())">
<o:return select="false()"/>
</o:if>
</o:when>
<o:return select="false()"/>
</o:otherwise>
</o:choose>
<o:return select="$this.findSolution()"/>
</o:do>
</o:function>
-<o:function name="canAttach">
<o:param name="testRow"/>
<o:param name="testColumn"/>
<o:variable name="columnDifference" select="$testColumn - $column"/>
-<o:when test="$row = $testRow or ($row + $columnDifference = $testRow) or ($row - $columnDifference = $testRow)">
<o:return select="true()"/>
</o:when>
-<o:when test="$neighbour">
<o:return select="$neighbour.canAttach($testRow, $testColumn)"/>
</o:when>
</o:choose>
<o:return select="false()"/>
</o:do>
</o:function>
-<o:function name="paint">
-<o:if test="$neighbour">
<o:eval select="$neighbour.paint()"/>
</o:if>
<o:eval select="$column"/>
</column>
</queen>
</o:do>
</o:function>
</o:type>
-<o:type name="ex:QueenSolver">
<o:variable name="lastQueen"/>
-<!-- type constructor
-->
-<o:function name="ex:QueenSolver">
<o:variable name="i" select="1"/>
-<o:while test="$i <= 8">
<o:set lastQueen="ex:Queen($i, $lastQueen)"/>
<o:do select="$lastQueen.findSolution()"/>
</o:while>
</o:do>
</o:function>
-<o:function name="paint">
<o:eval select="$lastQueen.paint()"/>
</o:do>
</o:function>
-<o:function name="advance">
<o:return select="$lastQueen.advance()"/>
</o:do>
</o:function>
</o:type>
-<!-- end type definitions
-->
-<!-- get the eight queens solver from the session
-->
<o:variable name="session" select="$servlet:req.getSession()"/>
<o:variable name="solver" select="$session.getAttribute('eight-queens')"/>
-<o:when test="not($solver)">
-<!-- not there, create a new one
-->
<o:set solver="ex:QueenSolver()"/>
</o:when>
-<!-- advance to next solution
-->
-<o:if test="not($solver.advance())">
-<!-- no more solutions, create new queen solver
-->
<o:set solver="ex:QueenSolver()"/>
</o:if>
</o:otherwise>
</o:choose>
<o:eval select="$solver.paint()"/>
</solution>
-<!-- save the solver for next time
-->
<o:do select="$session.setAttribute('eight-queens', $solver)"/>
</o:program>