<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:aodm="http://nesaraq.com/aodm/1.2"
           targetNamespace="http://nesaraq.com/aodm/1.2"
           elementFormDefault="qualified">

  <!--
    AODM 1.2 Core Schema
    Knowledge primitives: entity, relationship, fact, rule.
    Annotations:          source, confidence, value.
    Structural:           knowledge (root), condition/conclusion (inside rule).

    This is the stable core described in the AODM 1.2 Specification. Domain
    vocabularies extend AODM via separate, versioned namespaces layered on
    top of this core, never by adding elements here.

    Child elements may appear in any order (xs:choice). Cardinality limits
    that XSD 1.0 cannot express alongside free ordering (at most one
    confidence, at most one value per element) are stated in
    VALIDATION-RULES.md, rules C1/C2, and MUST be enforced by processors.
  -->

  <!-- ============ Shared simple types ============ -->

  <!-- A point in time, at date or dateTime precision -->
  <xs:simpleType name="temporalPoint">
    <xs:union memberTypes="xs:date xs:dateTime"/>
  </xs:simpleType>

  <!-- Self-describing content digest: "<algorithm>:<hex>", e.g. sha256:9f86d0... -->
  <xs:simpleType name="digest">
    <xs:restriction base="xs:string">
      <xs:pattern value="[a-z0-9\-]+:[0-9a-fA-F]{32,128}"/>
    </xs:restriction>
  </xs:simpleType>

  <!-- Whether an assertion is affirmed or explicitly denied -->
  <xs:simpleType name="polarity">
    <xs:restriction base="xs:string">
      <xs:enumeration value="positive"/>
      <xs:enumeration value="negative"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="confidenceValue">
    <xs:restriction base="xs:decimal">
      <xs:minInclusive value="0.0"/>
      <xs:maxInclusive value="1.0"/>
    </xs:restriction>
  </xs:simpleType>

  <!-- ============ Root container ============ -->

  <xs:element name="knowledge">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="aodm:entity"/>
        <xs:element ref="aodm:relationship"/>
        <xs:element ref="aodm:fact"/>
        <xs:element ref="aodm:rule"/>
        <xs:element ref="aodm:source"/>
      </xs:choice>
      <xs:attribute name="version" type="xs:string" default="1.2"/>
    </xs:complexType>
  </xs:element>

  <!-- ============ Annotations ============ -->

  <!-- Provenance: where a piece of knowledge came from -->
  <xs:element name="source">
    <xs:complexType mixed="true">
      <xs:attribute name="id" type="xs:ID"/>
      <xs:attribute name="uri" type="xs:anyURI"/>
      <xs:attribute name="title" type="xs:string"/>
      <xs:attribute name="retrieved" type="xs:date"/>
      <!-- When the source itself made the claim, vs. when we retrieved it -->
      <xs:attribute name="asserted" type="aodm:temporalPoint"/>
    </xs:complexType>
  </xs:element>

  <!-- How sure we are, 0.0-1.0 -->
  <xs:element name="confidence">
    <xs:complexType>
      <xs:attribute name="value" type="aodm:confidenceValue" use="required"/>
      <xs:attribute name="method" type="xs:string"/>
    </xs:complexType>
  </xs:element>

  <!--
    Structured measurement, so a quantity is machine-usable without
    regex-parsing prose. Either @number (optionally with @tolerance) for a
    point value, or @min and @max for a range. See VALIDATION-RULES.md M1-M3.
  -->
  <xs:element name="value">
    <xs:complexType>
      <xs:attribute name="number" type="xs:decimal"/>
      <xs:attribute name="min" type="xs:decimal"/>
      <xs:attribute name="max" type="xs:decimal"/>
      <xs:attribute name="tolerance" type="xs:decimal"/>
      <!-- SHOULD be a UCUM code (e.g. Cel, mm, kg, bar) -->
      <xs:attribute name="unit" type="xs:string"/>
    </xs:complexType>
  </xs:element>

  <!-- ============ Knowledge primitives ============ -->

  <!-- A thing: object, concept, component, actor, etc. -->
  <xs:element name="entity">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="aodm:source"/>
        <xs:element ref="aodm:confidence"/>
      </xs:choice>
      <xs:attribute name="id" type="xs:ID" use="required"/>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="label" type="xs:string"/>
      <xs:attribute name="hash" type="aodm:digest"/>
    </xs:complexType>
  </xs:element>

  <!-- A directed link between two entities: subject, predicate, object -->
  <xs:element name="relationship">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="aodm:source"/>
        <xs:element ref="aodm:confidence"/>
      </xs:choice>
      <xs:attribute name="id" type="xs:ID"/>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="subject" type="xs:IDREF" use="required"/>
      <xs:attribute name="predicate" type="xs:string" use="required"/>
      <xs:attribute name="object" type="xs:IDREF" use="required"/>
      <xs:attribute name="polarity" type="aodm:polarity" default="positive"/>
      <xs:attribute name="valid-from" type="aodm:temporalPoint"/>
      <xs:attribute name="valid-to" type="aodm:temporalPoint"/>
      <xs:attribute name="derived-from" type="xs:IDREFS"/>
    </xs:complexType>
  </xs:element>

  <!-- An assertion, optionally scoped to an entity/relationship via @about -->
  <xs:element name="fact">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="aodm:value"/>
        <xs:element ref="aodm:source"/>
        <xs:element ref="aodm:confidence"/>
      </xs:choice>
      <xs:attribute name="id" type="xs:ID"/>
      <xs:attribute name="about" type="xs:IDREF"/>
      <xs:attribute name="polarity" type="aodm:polarity" default="positive"/>
      <xs:attribute name="valid-from" type="aodm:temporalPoint"/>
      <xs:attribute name="valid-to" type="aodm:temporalPoint"/>
      <xs:attribute name="hash" type="aodm:digest"/>
      <!-- Ids of the rule and/or facts this fact was inferred from -->
      <xs:attribute name="derived-from" type="xs:IDREFS"/>
    </xs:complexType>
  </xs:element>

  <!--
    An inference rule: IF conditions THEN conclusion. Rule bodies are
    reference-only in 1.2 (pointers to fact/entity ids); an execution
    semantics is future work (see Specification, Section 10).
  -->
  <xs:element name="rule">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="condition" maxOccurs="unbounded">
          <xs:complexType>
            <xs:attribute name="ref" type="xs:IDREF" use="required"/>
            <xs:attribute name="polarity" type="aodm:polarity" default="positive"/>
          </xs:complexType>
        </xs:element>
        <xs:element name="conclusion">
          <xs:complexType>
            <xs:attribute name="ref" type="xs:IDREF" use="required"/>
          </xs:complexType>
        </xs:element>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element ref="aodm:source"/>
          <xs:element ref="aodm:confidence"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="id" type="xs:ID"/>
      <xs:attribute name="valid-from" type="aodm:temporalPoint"/>
      <xs:attribute name="valid-to" type="aodm:temporalPoint"/>
    </xs:complexType>
  </xs:element>

</xs:schema>
