{"id":10,"date":"2012-10-31T14:17:02","date_gmt":"2012-10-31T14:17:02","guid":{"rendered":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/?p=10"},"modified":"2025-08-12T16:11:01","modified_gmt":"2025-08-12T06:11:01","slug":"what-the-knights-tour-might-look-like-in-xslt-3-0","status":"publish","type":"post","link":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/archives\/10","title":{"rendered":"What the Knight&#8217;s Tour might look like in XSLT 3.0?"},"content":{"rendered":"\n<p>At the time of writing<a href=\"http:\/\/www.w3.org\/TR\/2012\/WD-xslt-30-20120710\/\"> XSL Transformations (XSLT) Version 3.0 (W3C Working Draft 10 July 2012)<\/a> is still a working draft. I can&#8217;t test this, but this is my estimate of what a solution for the Knight&#8217;s tour might look like in XSLT 3.0&nbsp; .d<\/p>\n\n\n\n<p>First we build a generic package for solving any kind of tour over the chess board. Here it is&#8230;<br \/><em>(Updated 31-Oct-2012)<\/em><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">&lt;br \/&gt;&amp;lt;xsl:package xsl:version=&quot;3.0&quot;&lt;br \/&gt;  xmlns:xsl=&amp;amp;amp;quot;http:\/\/www.w3.org\/1999\/XSL\/Transform&amp;amp;amp;quot;&lt;br \/&gt;  xmlns:xs=&amp;amp;amp;quot;http:\/\/www.w3.org\/2001\/XMLSchema&amp;amp;amp;quot;&lt;br \/&gt;  xmlns:fn=&amp;amp;amp;quot;http:\/\/www.w3.org\/2005\/xpath-functions&amp;amp;amp;quot;&lt;br \/&gt;  xmlns:tour=&amp;amp;amp;quot;http:\/\/www.seanbdurkin.id.au\/tour&amp;amp;amp;quot;&lt;br \/&gt;  name=&amp;amp;amp;quot;tour:tours&amp;amp;amp;quot;&amp;amp;amp;gt;&lt;br \/&gt;&amp;amp;amp;lt;xsl:stylesheet&amp;amp;amp;gt;&lt;br \/&gt;  &amp;amp;amp;lt;xsl:function name=&amp;amp;amp;quot;tour:manufacture-square&amp;amp;amp;quot;&lt;br \/&gt;       as=&amp;amp;amp;quot;element(square)&amp;amp;amp;quot; visibility=&amp;amp;amp;quot;public&amp;amp;amp;quot;&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;xsl:param name=&amp;amp;amp;quot;rank&amp;amp;amp;quot; as=&amp;amp;amp;quot;xs:integer&amp;amp;amp;quot; \/&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;xsl:param name=&amp;amp;amp;quot;file&amp;amp;amp;quot; as=&amp;amp;amp;quot;xs:integer&amp;amp;amp;quot; \/&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;square file=&amp;amp;amp;quot;$file&amp;amp;amp;quot; rank=&amp;amp;amp;quot;$rank&amp;amp;amp;quot; \/&amp;amp;amp;gt;&lt;br \/&gt;  &amp;amp;amp;lt;\/xsl:function&amp;amp;amp;gt;&lt;br \/&gt;&lt;br \/&gt;  &amp;amp;amp;lt;xsl:function name=&amp;amp;amp;quot;tour:on-board&amp;amp;amp;quot; as=&amp;amp;amp;quot;xs:boolean&amp;amp;amp;quot; visibility=&amp;amp;amp;quot;public&amp;amp;amp;quot;&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;xsl:param name=&amp;amp;amp;quot;rank&amp;amp;amp;quot; as=&amp;amp;amp;quot;xs:integer&amp;amp;amp;quot; \/&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;xsl:param name=&amp;amp;amp;quot;file&amp;amp;amp;quot; as=&amp;amp;amp;quot;xs:integer&amp;amp;amp;quot; \/&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;xsl:copy-of select=&amp;amp;amp;quot;($rank ge 1) and ($rank le 8) and&lt;br \/&gt;                         ($file ge 1) and ($file le 8)&amp;amp;amp;quot; \/&amp;amp;amp;gt;&lt;br \/&gt;  &amp;amp;amp;lt;\/xsl:function&amp;amp;amp;gt;&lt;br \/&gt;&lt;br \/&gt;  &amp;amp;amp;lt;xsl:function name=&amp;amp;amp;quot;tour:solve-tour&amp;amp;amp;quot; as=&amp;amp;amp;quot;item()*&amp;amp;amp;quot; visibility=&amp;amp;amp;quot;public&amp;amp;amp;quot;&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;!-- Solves the tour for any specified piece. --&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;!-- Outputs either a full solution of 64 squares, of if fail,&lt;br \/&gt;         a copy of the $state input. --&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;xsl:param name=&amp;amp;amp;quot;state&amp;amp;amp;quot; as=&amp;amp;amp;quot;item()+&amp;amp;amp;quot; \/&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;xsl:variable name=&amp;amp;amp;quot;compute-possible-moves&amp;amp;amp;quot;&lt;br \/&gt;      select=&amp;amp;amp;quot;$state&#x5B;. instance of function(*)]&amp;amp;amp;quot;&lt;br \/&gt;\t  as=&amp;amp;amp;quot;function(element(square)) as element(square)*&amp;amp;amp;quot;&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;xsl:variable name=&amp;amp;amp;quot;way-points&amp;amp;amp;quot; select=&amp;amp;amp;quot;$state\/self::square&amp;amp;amp;quot; \/&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;xsl:choose&amp;amp;amp;gt;&lt;br \/&gt;      &amp;amp;amp;lt;xsl:when test=&amp;amp;amp;quot;count($way-points) eq 64&amp;amp;amp;quot;&amp;amp;amp;gt;&lt;br \/&gt;        &amp;amp;amp;lt;xsl:sequence =&amp;amp;amp;quot;$state&amp;amp;amp;quot; \/&amp;amp;amp;gt;&lt;br \/&gt;      &amp;amp;amp;lt;\/xsl:when&amp;amp;amp;gt;&lt;br \/&gt;      &amp;amp;amp;lt;xsl:otherwise&amp;amp;amp;gt;&lt;br \/&gt;        &amp;amp;amp;lt;xsl:sequence select=&amp;amp;amp;quot;&lt;br \/&gt;\t  let $try-move := function( $state as item()*, $move as item()) as item()*)&lt;br \/&gt;\t        {&lt;br \/&gt;\t         if $state\/self::square&#x5B;@file=$move\/@file]&lt;br \/&gt;\t                               &#x5B;@rank=$move\/@rank]&lt;br \/&gt;\t           then $state&lt;br \/&gt;\t           else tour:solve-tour( ( $state, $move) )&lt;br \/&gt;                },&lt;br \/&gt;              $possible-moves := $compute-possible-moves( $way-points&#x5B;last()])&lt;br \/&gt;\t      return if empty( $possible-moves) then $state&lt;br \/&gt;                     else fn:fold-left( $try-move, $state, $possible-moves)&amp;amp;amp;quot; \/&amp;amp;amp;gt;&lt;br \/&gt;      &amp;amp;amp;lt;\/xsl:otherwise&amp;amp;amp;gt;&lt;br \/&gt;    &amp;amp;amp;lt;\/xsl:choose&amp;amp;amp;gt;&lt;br \/&gt;  &amp;amp;amp;lt;\/xsl:variable&amp;amp;amp;gt;&amp;amp;amp;lt;\/xsl:function&amp;amp;amp;gt;&lt;br \/&gt;&amp;amp;amp;lt;\/xsl:stylesheet&amp;amp;amp;gt;&lt;br \/&gt;&lt;br \/&gt;&amp;amp;amp;lt;xsl:expose component=&amp;amp;amp;quot;function&amp;amp;amp;quot;&lt;br \/&gt;  names=&amp;amp;amp;quot;tour:manufacture-square tour:on-board tour:solve-tour&amp;amp;amp;quot;&lt;br \/&gt;  visibility=&amp;amp;amp;quot;public&amp;amp;amp;quot; \/&amp;amp;amp;gt;&lt;br \/&gt;&lt;br \/&gt;&amp;amp;amp;lt;\/xsl:package&amp;amp;amp;gt;&lt;br \/&gt;<\/pre><\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignright\"><a href=\"https:\/\/i0.wp.com\/seanbdurkin.id.au\/pascaliburnus2\/wp-content\/uploads\/2012\/10\/knightstour1.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"224\" height=\"225\" data-attachment-id=\"19\" data-permalink=\"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/archives\/10\/knightstour1\" data-orig-file=\"https:\/\/i0.wp.com\/seanbdurkin.id.au\/pascaliburnus2\/wp-content\/uploads\/2012\/10\/knightstour1.jpg?fit=224%2C225\" data-orig-size=\"224,225\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"knight&amp;#8217;s Tour icon\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/seanbdurkin.id.au\/pascaliburnus2\/wp-content\/uploads\/2012\/10\/knightstour1.jpg?fit=224%2C225\" data-large-file=\"https:\/\/i0.wp.com\/seanbdurkin.id.au\/pascaliburnus2\/wp-content\/uploads\/2012\/10\/knightstour1.jpg?fit=224%2C225\" src=\"https:\/\/i0.wp.com\/seanbdurkin.id.au\/pascaliburnus2\/wp-content\/uploads\/2012\/10\/knightstour1.jpg?resize=224%2C225\" alt=\"The Knight's Tour\" class=\"wp-image-19\" title=\"knight's Tour icon\" srcset=\"https:\/\/i0.wp.com\/seanbdurkin.id.au\/pascaliburnus2\/wp-content\/uploads\/2012\/10\/knightstour1.jpg?w=224 224w, https:\/\/i0.wp.com\/seanbdurkin.id.au\/pascaliburnus2\/wp-content\/uploads\/2012\/10\/knightstour1.jpg?resize=150%2C150 150w\" sizes=\"auto, (max-width: 224px) 100vw, 224px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><strong>And now for the style-sheet to solve the Knight&#8217;s tour&#8230;<\/strong><br \/><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&amp;amp;lt;xsl:stylesheet version=&amp;amp;quot;3.0&amp;amp;quot;\n  xmlns:xsl=&amp;amp;quot;http:\/\/www.w3.org\/1999\/XSL\/Transform&amp;amp;quot;\n  xmlns:xs=&amp;amp;quot;http:\/\/www.w3.org\/2001\/XMLSchema&amp;amp;quot;\n  xmlns:fn=&amp;amp;quot;http:\/\/www.w3.org\/2005\/xpath-functions&amp;amp;quot;\n  xmlns:tour=&amp;amp;quot;http:\/\/www.seanbdurkin.id.au\/tour&amp;amp;quot;\n  exclude-result-prefixes=&amp;amp;quot;xsl fn xs tour&amp;amp;quot;&amp;amp;gt;\n&amp;amp;lt;xsl:use-package name=&amp;amp;quot;tour:tours&amp;amp;quot; \/&amp;amp;gt;\n&amp;amp;lt;xsl:output indent=&amp;amp;quot;yes&amp;amp;quot; encoding=&amp;amp;quot;UTF-8&amp;amp;quot; omit-xml-declaration=&amp;amp;quot;yes&amp;amp;quot; \/&amp;amp;gt;\n&amp;amp;lt;xsl:mode on-no-match=&amp;amp;quot;shallow-copy&amp;amp;quot; streamable=&amp;amp;quot;yes&amp;amp;quot;\/&amp;amp;gt;\n\n&amp;amp;lt;xsl:template match=&amp;amp;quot;knight&#x5B;square]&amp;amp;quot;&amp;amp;gt;\n  &amp;amp;lt;xsl:variable name=&amp;amp;quot;error&amp;amp;quot;&amp;amp;gt;\n    &amp;amp;lt;error&amp;amp;gt;Failed to find solution to Knight's Tour.&amp;amp;lt;\/error&amp;amp;gt;\n  &amp;amp;lt;\/xsl:variable&amp;amp;gt;\n  &amp;amp;lt;xsl:copy&amp;amp;gt;\n    &amp;amp;lt;xsl:copy-of select=&amp;amp;quot;\n    let $final-state := tour:solve-tour((\n    function( $piece-position as element(square)) as element(square)*\n      { (: This function defines a knight's move. :)\n\t    let $r0 := number( $piece-position\/@rank),\n\t    let $f0 := number( $piece-position\/@file),\n\t    for $r in -2..2, $f in -2..2 return\n\t\t  if (abs($r) + abs($f) eq 3) and\n\t\t     tour:on-board($r+$r0, $f+$f0) then\n\t\t    tour:manufacture-square($r+$r0, $f+$f0)\n\t      else ()\n\t  }\n      , current()\/square)),\n     $solution := $final-state\/self::square\n    return if count($solution) eq 64 then $solution\n           else $error\/*&amp;amp;quot; \/&amp;amp;gt;\n  &amp;amp;lt;\/xsl:copy&amp;amp;gt;\n&amp;amp;lt;\/xsl:template&amp;amp;gt;\n\n&amp;amp;lt;!-- Add templates for other piece types if you want to solve\n     their tours too. Solve by calling tour:solve-tour() .    --&amp;amp;gt;\n\n&amp;amp;lt;\/xsl:stylesheet&amp;amp;gt;\n<\/pre><\/pre>\n\n\n\n<p>So an input like this&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&amp;amp;lt;tt&amp;amp;gt;\n &amp;amp;lt;knight&amp;amp;gt;\n   &amp;amp;lt;square file=&amp;amp;quot;1&amp;amp;quot; rank=&amp;amp;quot;1&amp;amp;quot; \/&amp;amp;gt;\n &amp;amp;lt;\/knight&amp;amp;gt;\n&amp;amp;lt;\/tt&amp;amp;gt;\n<\/pre><\/pre>\n\n\n\n<p>&#8230;should be transformed in something like this&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&amp;amp;lt;tt&amp;amp;gt;\n &amp;amp;lt;knight&amp;amp;gt;\n   &amp;amp;lt;square file=&amp;amp;quot;1&amp;amp;quot; rank=&amp;amp;quot;1&amp;amp;quot; \/&amp;amp;gt;\n   &amp;amp;lt;square file=&amp;amp;quot;2&amp;amp;quot; rank=&amp;amp;quot;3&amp;amp;quot; \/&amp;amp;gt;\n   &amp;amp;lt;square file=&amp;amp;quot;1&amp;amp;quot; rank=&amp;amp;quot;5&amp;amp;quot; \/&amp;amp;gt;\n   ... etc for 64 squares.\n &amp;amp;lt;\/knight&amp;amp;gt;\n&amp;amp;lt;\/tt&amp;amp;gt;\n<\/pre><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>At the time of writing XSL Transformations (XSLT) Version 3.0 (W3C Working Draft 10 July 2012) is still a working draft. I can&#8217;t test this, but this is my estimate of what a solution for the Knight&#8217;s tour might look &hellip; <a href=\"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/archives\/10\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":19,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[3],"tags":[4,13],"class_list":["post-10","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-xslt-3-0","tag-knights-tour","tag-xslt-3-0"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/seanbdurkin.id.au\/pascaliburnus2\/wp-content\/uploads\/2012\/10\/knightstour1.jpg?fit=224%2C225","jetpack_shortlink":"https:\/\/wp.me\/p2QXbt-a","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/wp-json\/wp\/v2\/posts\/10","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/wp-json\/wp\/v2\/comments?post=10"}],"version-history":[{"count":29,"href":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/wp-json\/wp\/v2\/posts\/10\/revisions"}],"predecessor-version":[{"id":405,"href":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/wp-json\/wp\/v2\/posts\/10\/revisions\/405"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/wp-json\/wp\/v2\/media\/19"}],"wp:attachment":[{"href":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/wp-json\/wp\/v2\/media?parent=10"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/wp-json\/wp\/v2\/categories?post=10"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/seanbdurkin.id.au\/pascaliburnus2\/wp-json\/wp\/v2\/tags?post=10"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}