2
votes

I have an assignment: Define the co-author graph G of the dblp-excerpt to be the undirected graph that has all authors as nodes, such that there is an edge between author a and author b in G if and only if a and b have written a publication together.

Define the distance between two authors a and b to be the length of the shortest path between a and b in G. Hence, authors that have published together have distance 1.

Moreover, if a and b have not published together but they have both published together with c, then the distance between a and b is two. Write an XQuery program that computes, for each pair of authors x and y 6= x the distance between x and y using the following output format.

I wrote a code, but it doesn't work. I'm sure, it is very simple mistake, but I can't find it.

I have an error: Error:

Stopped at C:/Users/Zhanna/Desktop/Test/test_3.xq, 28/44: [XPST0017] Unknown function 'local:getAvailablePathSizes'.

It underlines the beginning of the list of arguments in line 28, which is:

return
local:getAvailablePathSizes($graph,$current,$target,$visitedList,$count+1)

I validate the query with the Saxon as well and it also give a msg like this:

Error XPST0008: Unresolved reference to variable $count Static error(s) in query

Help me, please, to fix it.

<ee>
let $graph:=(
  <graph>{
    for $a in distinct-values(//author)
    let $publications:=/dblp/*[author=$a]
    order by $a
    return
    <node name="{$a}">
    {
      let $co:=$publications/author[(.)!=$a] return
      for $distinctCo in distinct-values($co) return
      <edge from="{$a}" to="{$distinctCo}"/>
    }
    </node>
  }</graph>
 ) return

declare function local:getAvailablePathSizes
 ($graph, $start, $target, $visitedList, $count)
{
  let $cos:=$graph/node[@name=$start]/edge/@to return
  let $listOfDistances:=(
    for $current in $cos
    return
    if($current=$target) then $count+1 else
      if (empty(visitedList[.=$current])) then(
        let $visitedList:=insert-before(data($current), 0, $visitedList)
        return local:getAvailablePathSizes($graph,$current,$target,$visitedList,$count+1)
      ) else()
  )
  return $listOfDistances
};

<distances>
{
  for $node in $graph/node return
  for $to in $graph/node[@name!=$node/@name]
    let $dist:=min(local:getAvailablePathSizes($graph, $node/@name, $to/@name, null, 0))
    return
    if($dist>0) then(
      <distance
        author1="{$node/@name}"
        author2="{$to/@name}"
        distance="{$dist}"/>)
        else()
}
</distances>
</ee>

This is the XML file http://www.filedropper.com/dblp

1
Please never retype error messages, but copy them. Are you really getting an error message with the singular of the function name? There is no respective function call leading to such an error message. Please provide the full error message, including any line/column indications and/or stacktrace (if available). Furthermore, you're aware there is no null value in XQuery? - Jens Erat
I use BaseX and it is impossible to copy there an error:( sorry:( You are right, I mistyped and the error is: Unknown function "local:getAvailablePathSizes". It underlines the beginning of the list of arguments in line 28, which is: return local:getAvailablePathSizes($graph,$current,$target,$visitedList,$count+1) - JeyKo
Open the Query Info pane (View->Query Info or <kbd>ctrl</kbd>+<kbd>i</kbd>). It shows a selectable error message. Please don't add information in the comments, edit your question instead (code is hardly readable in comments). - Jens Erat
Now that's what a question should look like. - Jens Erat

1 Answers

0
votes

The first problem is, that you did omit curly braces around the XQuery code inside the <ee> element, so large parts of your code haven't been evaluated (but interpreted as text instead). This resulted in a barely helpful error message indicating the second problem: you must define functions in the so-called prolog before the "normal" XQuery statements (in the query body).

declare function local:getAvailablePathSizes
 ($graph, $start, $target, $visitedList, $count)
{
  let $cos:=$graph/node[@name=$start]/edge/@to return
  let $listOfDistances:=(
    for $current in $cos
    return
    if($current=$target) then $count+1 else
      if (empty(visitedList[.=$current])) then(
        let $visitedList:=insert-before(data($current), 0, $visitedList)
        return local:getAvailablePathSizes($graph,$current,$target,$visitedList,$count+1)
      ) else()
  )
  return $listOfDistances
};

<ee>{
let $graph:=(
  <graph>{
    for $a in distinct-values(//author)
    let $publications:=/dblp/*[author=$a]
    order by $a
    return
    <node name="{$a}">
    {
      let $co:=$publications/author[(.)!=$a] return
      for $distinctCo in distinct-values($co) return
      <edge from="{$a}" to="{$distinctCo}"/>
    }
    </node>
  }</graph>
 ) return

<distances>
{
  for $node in $graph/node return
  for $to in $graph/node[@name!=$node/@name]
    let $dist:=min(local:getAvailablePathSizes($graph, $node/@name, $to/@name, null, 0))
    return
    if($dist>0) then(
      <distance
        author1="{$node/@name}"
        author2="{$to/@name}"
        distance="{$dist}"/>)
        else()
}
</distances>
}
</ee>