<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
  <start>
    <ref name="Simulation"/>
  </start>
  <define name="Simulation">
    <element name="simulation">
      <attribute name="xmds-version">
        <value>2</value>
      </attribute>
      <oneOrMore>
        <choice>
          <element name="name">
            <text/>
          </element>
          <element name="author">
            <text/>
          </element>
          <element name="description">
            <text/>
          </element>
          <ref name="Testing"/>
          <ref name="Features"/>
          <ref name="Geometry"/>
          <ref name="Driver"/>
          <ref name="Vector"/>
          <ref name="Filter"/>
          <ref name="ComputedVector"/>
          <ref name="NoiseVector"/>
          <ref name="Sequence"/>
          <ref name="Output"/>
        </choice>
      </oneOrMore>
    </element>
  </define>
  <define name="Testing">
    <element name="testing">
      <oneOrMore>
        <choice>
          <element name="command_line">
            <text/>
          </element>
          <ref name="Arguments"/>
          <ref name="XSILFile"/>
          <ref name="InputXSILFile"/>
        </choice>
      </oneOrMore>
    </element>
  </define>
  <define name="XSILFile">
    <element name="xsil_file">
      <attribute name="name"/>
      <attribute name="expected"/>
      <optional>
        <attribute name="absolute_tolerance"/>
      </optional>
      <optional>
        <attribute name="relative_tolerance"/>
      </optional>
      <zeroOrMore>
        <element name="moment_group">
          <attribute name="number"/>
          <optional>
            <attribute name="relative_tolerance"/>
          </optional>
          <optional>
            <attribute name="absolute_tolerance"/>
          </optional>
        </element>
      </zeroOrMore>
    </element>
  </define>
  <define name="InputXSILFile">
    <element name="input_xsil_file">
      <attribute name="name"/>
    </element>
  </define>
  <!-- Features -->
  <define name="Features">
    <element name="features">
      <oneOrMore>
        <choice>
          <element name="auto_vectorise">
            <choice>
              <ref name="Bool"/>
              <empty/>
            </choice>
          </element>
          <element name="benchmark">
            <choice>
              <ref name="Bool"/>
              <empty/>
            </choice>
          </element>
          <element name="bing">
            <choice>
              <ref name="Bool"/>
              <empty/>
            </choice>
          </element>
          <element name="cflags">
            <text/>
          </element>
          <element name="chunked_output">
            <attribute name="size"/>
          </element>
          <element name="diagnostics">
            <choice>
              <ref name="Bool"/>
              <empty/>
            </choice>
          </element>
          <element name="error_check">
            <choice>
              <ref name="Bool"/>
              <empty/>
            </choice>
          </element>
          <element name="halt_non_finite">
            <choice>
              <ref name="Bool"/>
              <empty/>
            </choice>
          </element>
          <element name="openmp">
            <optional>
              <attribute name="threads"/>
            </optional>
            <choice>
              <ref name="Bool"/>
              <empty/>
            </choice>
          </element>
          <ref name="Arguments"/>
          <element name="globals">
            <text/>
          </element>
          <element name="validation">
            <attribute name="kind"/>
            <empty/>
          </element>
          <ref name="FFTW"/>
          <element name="precision">
            <text/>
          </element>
        </choice>
      </oneOrMore>
    </element>
  </define>
  <define name="Bool">
    <choice>
      <value>yes</value>
      <value>no</value>
    </choice>
  </define>
  <define name="Arguments">
    <element name="arguments">
      <optional>
        <attribute name="append_args_to_output_filename">
          <ref name="Bool"/>
        </attribute>
      </optional>
      <zeroOrMore>
        <ref name="Argument"/>
      </zeroOrMore>
      <optional>
        <text/>
      </optional>
    </element>
  </define>
  <define name="Argument">
    <element name="argument">
      <attribute name="name"/>
      <attribute name="type"/>
      <attribute name="default_value"/>
      <empty/>
    </element>
  </define>
  <define name="FFTW">
    <element name="fftw">
      <optional>
        <attribute name="plan"/>
      </optional>
      <optional>
        <attribute name="threads"/>
      </optional>
      <empty/>
    </element>
  </define>
  <!-- Geometry -->
  <define name="Geometry">
    <element name="geometry">
      <element name="propagation_dimension">
        <text/>
      </element>
      <optional>
        <element name="transverse_dimensions">
          <oneOrMore>
            <ref name="Dimension"/>
          </oneOrMore>
        </element>
      </optional>
    </element>
  </define>
  <define name="Dimension">
    <element name="dimension">
      <attribute name="name"/>
      <optional>
        <attribute name="type"/>
      </optional>
      <optional>
        <attribute name="lattice"/>
      </optional>
      <optional>
        <attribute name="spectral_lattice"/>
      </optional>
      <choice>
        <attribute name="domain"/>
        <attribute name="length_scale"/>
      </choice>
      <optional>
        <attribute name="transform"/>
      </optional>
      <optional>
        <attribute name="order"/>
      </optional>
      <optional>
        <attribute name="aliases"/>
      </optional>
      <optional>
        <attribute name="volume_prefactor"/>
      </optional>
      <empty/>
    </element>
  </define>
  <!-- Driver -->
  <define name="Driver">
    <element name="driver">
      <attribute name="name"/>
      <optional>
        <attribute name="kind"/>
      </optional>
      <optional>
        <attribute name="paths"/>
      </optional>
      <empty/>
    </element>
  </define>
  <!-- Vector stuff -->
  <define name="VectorCommon">
    <attribute name="name"/>
    <optional>
      <attribute name="dimensions"/>
    </optional>
    <optional>
      <attribute name="initial_space"/>
    </optional>
    <optional>
      <attribute name="initial_basis"/>
    </optional>
    <optional>
      <attribute name="type"/>
    </optional>
    <element name="components">
      <text/>
    </element>
  </define>
  <define name="Dependencies">
    <element name="dependencies">
      <optional>
        <attribute name="basis"/>
      </optional>
      <text/>
    </element>
  </define>
  <define name="Vector">
    <element name="vector">
      <ref name="VectorCommon"/>
      <optional>
        <element name="initialisation">
          <optional>
            <attribute name="kind"/>
          </optional>
          <optional>
            <attribute name="geometry_matching_mode"/>
          </optional>
          <optional>
            <element name="filename">
              <optional>
                <attribute name="group"/>
              </optional>
              <text/>
            </element>
          </optional>
          <interleave>
            <text/>
            <optional>
              <ref name="Dependencies"/>
            </optional>
          </interleave>
        </element>
      </optional>
    </element>
  </define>
  <define name="ComputedVector">
    <element name="computed_vector">
      <ref name="VectorCommon"/>
      <element name="evaluation">
        <interleave>
          <optional>
            <ref name="Dependencies"/>
          </optional>
          <text/>
        </interleave>
      </element>
    </element>
  </define>
  <define name="NoiseVector">
    <element name="noise_vector">
      <ref name="VectorCommon"/>
      <attribute name="kind"/>
      <optional>
        <attribute name="mean"/>
      </optional>
      <optional>
        <attribute name="mean-rate"/>
      </optional>
      <optional>
        <attribute name="mean-density"/>
      </optional>
      <optional>
        <attribute name="method"/>
      </optional>
      <optional>
        <attribute name="seed"/>
      </optional>
    </element>
  </define>
  <!-- Sequence -->
  <define name="Sequence">
    <element name="sequence">
      <optional>
        <attribute name="cycles"/>
      </optional>
      <zeroOrMore>
        <choice>
          <ref name="Integrate"/>
          <ref name="Filter"/>
          <ref name="Breakpoint"/>
          <ref name="Sequence"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="Integrate">
    <element name="integrate">
      <attribute name="algorithm"/>
      <attribute name="interval"/>
      <optional>
        <attribute name="steps"/>
      </optional>
      <optional>
        <attribute name="tolerance"/>
      </optional>
      <optional>
        <attribute name="iterations"/>
      </optional>
      <optional>
        <attribute name="cutoff"/>
      </optional>
      <optional>
        <attribute name="home_space"/>
      </optional>
      <optional>
        <attribute name="extrapolations"/>
      </optional>
      <oneOrMore>
        <choice>
          <element name="samples">
            <text/>
          </element>
          <ref name="Filters"/>
          <ref name="ComputedVector"/>
          <ref name="Operators"/>
        </choice>
      </oneOrMore>
    </element>
  </define>
  <define name="Filters">
    <element name="filters">
      <optional>
        <attribute name="where"/>
      </optional>
      <oneOrMore>
        <ref name="Filter"/>
      </oneOrMore>
    </element>
  </define>
  <define name="Operators">
    <element name="operators">
      <optional>
        <attribute name="dimensions"/>
      </optional>
      <oneOrMore>
        <choice>
          <ref name="Operator"/>
          <element name="integration_vectors">
            <optional>
              <attribute name="basis"/>
            </optional>
            <text/>
          </element>
          <ref name="Dependencies"/>
          <text/>
        </choice>
      </oneOrMore>
    </element>
  </define>
  <define name="Operator">
    <element name="operator">
      <choice>
        <ref name="IPEXOperatorContents"/>
        <ref name="FunctionsOperatorContents"/>
        <ref name="CrossPropagationOperatorContents"/>
      </choice>
    </element>
  </define>
  <define name="IPEXOperatorContents">
    <attribute name="kind">
      <choice>
        <value>ip</value>
        <value>ex</value>
        <value>IP</value>
        <value>EX</value>
      </choice>
    </attribute>
    <optional>
      <attribute name="constant">
        <ref name="Bool"/>
      </attribute>
    </optional>
    <optional>
      <attribute name="basis"/>
    </optional>
    <optional>
      <attribute name="type"/>
    </optional>
    <optional>
      <attribute name="dimensions"/>
    </optional>
    <interleave>
      <element name="operator_names">
        <text/>
      </element>
      <optional>
        <ref name="Dependencies"/>
      </optional>
      <text/>
    </interleave>
  </define>
  <define name="FunctionsOperatorContents">
    <attribute name="kind">
      <value>functions</value>
    </attribute>
    <text/>
  </define>
  <define name="CrossPropagationOperatorContents">
    <attribute name="kind">
      <value>cross_propagation</value>
    </attribute>
    <attribute name="algorithm"/>
    <attribute name="propagation_dimension"/>
    <optional>
      <attribute name="iterations"/>
    </optional>
    <oneOrMore>
      <choice>
        <element name="integration_vectors">
          <text/>
        </element>
        <ref name="Dependencies"/>
        <element name="boundary_condition">
          <attribute name="kind"/>
          <optional>
            <ref name="Dependencies"/>
          </optional>
          <text/>
        </element>
        <ref name="Operator"/>
        <text/>
      </choice>
    </oneOrMore>
  </define>
  <define name="Filter">
    <element name="filter">
      <optional>
        <attribute name="name"/>
      </optional>
      <optional>
        <attribute name="only_when_called">
          <ref name="Bool"/>
        </attribute>
      </optional>
      <optional>
        <ref name="Dependencies"/>
      </optional>
      <text/>
    </element>
  </define>
  <define name="Breakpoint">
    <element name="breakpoint">
      <optional>
        <attribute name="filename"/>
      </optional>
      <optional>
        <attribute name="format"/>
      </optional>
      <ref name="Dependencies"/>
    </element>
  </define>
  <define name="SamplingContents">
    <optional>
      <attribute name="initial_sample">
        <ref name="Bool"/>
      </attribute>
    </optional>
    <optional>
      <attribute name="basis"/>
    </optional>
    <oneOrMore>
      <choice>
        <ref name="ComputedVector"/>
        <ref name="Operator"/>
        <element name="moments">
          <text/>
        </element>
        <ref name="Dependencies"/>
        <text/>
      </choice>
    </oneOrMore>
  </define>
  <define name="Output">
    <element name="output">
      <optional>
        <attribute name="format"/>
      </optional>
      <optional>
        <attribute name="filename"/>
      </optional>
      <zeroOrMore>
        <choice>
          <element name="group">
            <element name="sampling">
              <ref name="SamplingContents"/>
            </element>
          </element>
          <element name="sampling_group">
            <ref name="SamplingContents"/>
          </element>
        </choice>
      </zeroOrMore>
    </element>
  </define>
</grammar>
