<?xml version="1.0" encoding="utf-8"?>
<pml_schema
  xmlns="http://ufal.mff.cuni.cz/pdt/pml/schema/" version="1.2">
  <revision>0.0.8</revision>
  <description>A simple schema for query trees</description>

  <root name="tree_query" type="q-tree_query.type"/>

  <type name="q-user-relation-choice.type">
    <cdata format="token"/>
  </type>
  <type name="q-ref-user-relation-choice.type">
    <cdata format="token"/>
  </type>

  <type name="q-base-relation.type">
    <container/>
  </type>

  <derive name="q-subquery.type" type="q-node.type">
    <structure>    
      <member name="occurrences">
	<alt>
	  <structure>
	    <member name="min">
	      <cdata format="nonNegativeInteger"/>
	    </member>
	    <member name="max">
	      <cdata format="nonNegativeInteger"/>
	    </member>
	  </structure>
	</alt>
      </member>
      <delete>optional</delete>
      <delete>overlapping</delete>
    </structure>
  </derive>

  <derive name="q-descendant-relation.type" type="q-base-relation.type">
    <container>
      <attribute name="min_length">
	<cdata format="positiveInteger"/>
      </attribute>
      <attribute name="max_length">
	<cdata format="positiveInteger"/>
      </attribute>
      <attribute name="label">
	<constant>descendant</constant>
      </attribute>
    </container>
  </derive>
  <derive name="q-ancestor-relation.type" type="q-descendant-relation.type">
    <container>
      <attribute name="label">
	<constant>ancestor</constant>
      </attribute>
    </container>
  </derive>
  <derive name="q-child-relation.type" type="q-base-relation.type">
    <container>
      <attribute name="label">
	<constant>child</constant>
      </attribute>
    </container>
  </derive>
  <derive name="q-member-relation.type" type="q-base-relation.type">
    <container>
      <attribute name="label">
	<constant>member</constant>
      </attribute>
    </container>
  </derive>
  <derive name="q-parent-relation.type" type="q-base-relation.type">
    <container>
      <attribute name="label">
	<constant>parent</constant>
      </attribute>
    </container>
  </derive>
  <derive name="q-user-relation.type" type="q-base-relation.type">
    <container>
      <attribute required="1" name="label" type="q-user-relation-choice.type"/>
      <attribute required="0" name="category" type="q-user-relation-category.type"/>
      <attribute name="min_length">
	<cdata format="positiveInteger"/>
      </attribute>
      <attribute name="max_length">
	<cdata format="positiveInteger"/>
      </attribute>
    </container>
  </derive>
  <derive name="q-relation-with-int-minmax.type" type="q-base-relation.type">
    <container>
      <attribute name="min_length">
	<cdata format="integer"/>
      </attribute>
      <attribute name="max_length">
	<cdata format="integer"/>
      </attribute>
    </container>
  </derive>
  <derive name="q-sibling-relation.type" type="q-relation-with-int-minmax.type">
    <container>
      <attribute name="label">
	<constant>sibling</constant>
      </attribute>
    </container>
  </derive>
  <derive name="q-depth-first-precedes.type" type="q-base-relation.type">
    <container>
      <attribute name="label">
	<constant>depth-first-precedes</constant>
      </attribute>
    </container>
  </derive>
  <derive name="q-depth-first-follows.type" type="q-base-relation.type">
    <container>
      <attribute name="label">
	<constant>depth-first-follows</constant>
      </attribute>
    </container>
  </derive>
  <derive name="q-order-precedes.type" type="q-relation-with-int-minmax.type">
    <container>
      <attribute name="label">
	<constant>order-precedes</constant>
      </attribute>
    </container>
  </derive>
  <derive name="q-order-follows.type" type="q-base-relation.type">
    <container>
      <attribute name="label">
	<constant>order-follows</constant>
      </attribute>
    </container>
  </derive>
  <derive name="q-same-tree-as.type" type="q-base-relation.type">
    <container>
      <attribute name="label">
	<constant>same-tree-as</constant>
      </attribute>
    </container>
  </derive>
  <derive name="q-same-document-as.type" type="q-base-relation.type">
    <container>
      <attribute name="label">
	<constant>same-document-as</constant>
      </attribute>
    </container>
  </derive>

  <type name="q-user-relation-category.type">
    <choice>
      <value>pmlrf</value>
      <value>implementation</value>
    </choice>
  </type>

  <type name="q-relation.type">
    <sequence content_pattern="(member|child|parent|sibling|descendant|ancestor|depth-first-precedes|depth-first-follows|order-precedes|order-follows|user-defined|same-document-as|same-tree-as)?">
      <element name="same-document-as" type="q-same-document-as.type"/>
      <element name="same-tree-as" type="q-same-tree-as.type"/>
      <element name="depth-first-precedes" type="q-depth-first-precedes.type"/>
      <element name="depth-first-follows" type="q-depth-first-follows.type"/>
      <element name="order-precedes" type="q-order-precedes.type"/>
      <element name="order-follows" type="q-order-follows.type"/>
      <element name="ancestor" type="q-ancestor-relation.type"/>
      <element name="parent" type="q-parent-relation.type"/>
      <element name="sibling" type="q-sibling-relation.type"/>
      <element name="child" type="q-child-relation.type"/>
      <element name="descendant" type="q-descendant-relation.type"/>
      <element name="member" type="q-member-relation.type"/>
      <element name="user-defined" type="q-user-relation.type"/> 
    </sequence>
  </type>

  <type name="q-ref-relation.type">
    <sequence content_pattern="(descendant|ancestor|parent|sibling|child|depth-first-precedes|depth-first-follows|order-precedes|order-follows|user-defined|same-document-as|same-tree-as)?">
      <element name="same-document-as" type="q-same-document-as.type"/>
      <element name="same-tree-as" type="q-same-tree-as.type"/>
      <element name="depth-first-precedes" type="q-depth-first-precedes.type"/>
      <element name="depth-first-follows" type="q-depth-first-follows.type"/>
      <element name="order-precedes" type="q-order-precedes.type"/>
      <element name="order-follows" type="q-order-follows.type"/>
      <element name="ancestor" type="q-ancestor-relation.type"/>
      <element name="parent" type="q-parent-relation.type"/>
      <element name="sibling" type="q-sibling-relation.type"/>
      <element name="child" type="q-child-relation.type"/>
      <element name="descendant" type="q-descendant-relation.type"/>
      <element name="user-defined" type="q-user-relation.type"/> 
    </sequence>
  </type>

  <type name="q-tree_query.type">
    <structure>
      <member name="q-trees" role="#TREES" required="1">
	<list type="q-query.type" ordered="1"/>
      </member>
    </structure>
  </type>

  <type name="q-query.type">
    <structure role="#NODE" name="q-root">
      <member name="id" role="#ID" as_attribute="1">
	<cdata format="ID"/>
      </member>
      <member name="description"><cdata format="any"/></member>
      <member name="node-type"><cdata format="token"/></member>
      <member name="q-nodes" role="#CHILDNODES">
	<sequence>
	  <element name="node" type="q-node.type"/>
	</sequence>
      </member>
      <member name="output-filters"><list ordered="1" type="q-output.type"/></member>
      <member name="comments"><list ordered="1"><cdata format="any"/></list></member>
    </structure>
  </type>
  <type name="q-output.type">
    <structure>
      <member name="distinct"><cdata format="boolean"/></member>
      <member name="return" type="q-columns.type"/>
      <member name="where" type="q-col-group.type"/>
      <member name="group-by" type="q-columns.type"/>
      <member name="sort-by" type="q-columns.type"/>
    </structure>
  </type>
  <type name="q-columns.type">
    <list ordered="1"><cdata format="string"/></list>
  </type>
  <type name="q-node.type">
    <structure role="#NODE" name="q-node">
      <member name="name">
	<cdata format="NMTOKEN"/>
      </member>
      <member name="description"><cdata format="any"/></member>
      <member name="node-type"><cdata format="token"/></member>
      <member name="optional" type="bool"/>
      <member name="overlapping" type="bool"/>
      <member name="relation" type="q-relation.type"/>
<!--      <member name="edge-transitive" type="bool"/> -->
      <member name="conditions" type="q-group.type"/>
      <member name="q-children" role="#CHILDNODES">
	<sequence>
	  <element name="node" type="q-node.type"/>
	  <element name="ref" type="q-ref.type"/>
	  <element name="subquery" type="q-subquery.type"/>
	  <element name="test" type="q-test.type"/>
	  <element name="or" type="q-group.type"/>
	  <element name="and" type="q-group.type"/>
	  <element name="not" type="q-group.type"/>
	</sequence>
      </member>
    </structure>
  </type>

  <type name="q-ref.type">
    <structure role="#NODE">
      <member name="relation" type="q-ref-relation.type"/>
      <member name="target">
	<cdata format="PMLREF"/>
      </member>
    </structure>
  </type>
  <type name="col-expr-seq.type">
    <sequence role="#CHILDNODES">
      <element name="test" type="q-test.type"/>
      <element name="not" type="q-col-group.type"/>
      <element name="or" type="q-col-group.type"/>
      <element name="and" type="q-col-group.type"/>
    </sequence>
  </type>
  <type name="q-col-group.type">
    <container type="col-expr-seq.type" role="#NODE">
    </container>
  </type>
  <type name="expr-seq.type">
    <sequence role="#CHILDNODES">
      <element name="subquery" type="q-subquery.type"/>
      <element name="ref" type="q-ref.type"/>
      <element name="test" type="q-test.type"/>
      <element name="not" type="q-group.type"/>
      <element name="or" type="q-group.type"/>
      <element name="and" type="q-group.type"/>
    </sequence>
  </type>
  <type name="q-test.type">
    <structure role="#NODE">
      <member name="a" required="1">
	<cdata format="string"/>
      </member>
      <member name="operator" required="1" as_attribute="1" type="operator.type"/>
      <member name="b" required="1">
	<cdata format="string"/>
      </member>
    </structure>
  </type>
  <type name="num.operator.type">
    <choice>
      <value>=</value>
      <value>!=</value>
      <value>&lt;</value>
      <value>&gt;</value>
      <value>&lt;=</value>
      <value>&gt;=</value>
    </choice>
  </type>
  <derive name="operator.type" type="num.operator.type">
    <choice>
      <value>in</value>
      <value>~</value>
      <value>~*</value>
      <value>!in</value>
      <value>!~</value>
      <value>!~*</value>
    </choice>
  </derive>

  <type name="q-group.type">
    <container type="expr-seq.type" role="#NODE">
    </container>
  </type>
  <type name="bool">
    <choice>
      <value>0</value>
      <value>1</value>
    </choice>    
  </type>
</pml_schema>
