Last active
August 29, 2015 14:02
-
-
Save LeoWoerteler/ae998db0b3b1f08ef72f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(: list of all persons and their neighbors :) | |
declare variable $persons := | |
for $scene in doc('http://www.ibiblio.org/xml/examples/shakespeare/r_and_j.xml')//SCENE | |
let $speakers := distinct-values($scene/SPEECH/SPEAKER) | |
for $p1 in $speakers, $p2 in $speakers | |
where $p1 ne $p2 | |
group by $p1 | |
return <person name="{$p1}">{ | |
for $other in distinct-values($p2) | |
return <neighbor name="{$other}"/> | |
}</person>; | |
declare function local:BFS($start) { | |
(: just starts the first round with the start node :) | |
local:round( | |
1, | |
<speaker name="{$start}"><distance>0</distance></speaker>, | |
() | |
) | |
}; | |
declare function local:round($n, $last-round, $out) { | |
if(empty($last-round)) then ( | |
(: last round found no new persons, we are finished :) | |
$out | |
) else ( | |
let $current-round := | |
(: iterate over all persons found in the last round :) | |
fold-left($last-round, (), function($current, $speaker) { | |
(: iterate over their neighbors :) | |
fold-left( | |
(: ignore persons found in previous rounds :) | |
$persons[@name=$speaker/@name]/neighbor/@name[not(. = $out/@name)], | |
$current, | |
function($current2, $neighbor) { | |
if($current2/speaker[@name = $neighbor]) then ( | |
(: person was already found this round, ignore :) | |
$current2 | |
) else ( | |
(: append newly found person to this round's output :) | |
$current2, | |
<speaker name="{$neighbor}"><distance>{$n}</distance></speaker> | |
) | |
}) | |
}) | |
return local:round($n + 1, $current-round, ($out, $last-round)) | |
) | |
}; | |
local:BFS("JULIET") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment