<?xml version="1.0" encoding="utf-8"?>
<iso:schema 
  xmlns="http://purl.oclc.org/dsdl/schematron"
  xmlns:iso="http://purl.oclc.org/dsdl/schematron" 
  xmlns:dp="http://www.pnml.org/version-2009/grammar/pnml"
  queryBinding='xslt2'
  schemaVersion='ISO19757-3'
  see='http://standards.iso.org/ittf/PubliclyAvailableStandards/index.html'
  defaultPhase='#ALL'>
  <iso:title>A Schematron mini-schema for PNML PT nets constraints specification</iso:title>
  <iso:ns prefix='dp' uri='http://www.pnml.org/version-2009/grammar/pnml'/>
  <p> 
    This schema provides Schematron rules you may use to further check 
    the validity of a PT Net Document, in addition to the original PNML Schema in RELAX NG.
    This schema reuses the rules designed to check PNML Core Model Documents,
    since PT Nets are built upon the Core Model.
    
    File name                      : PTNetconstraints.sch
    Version                        : 2010
    Copyright notice               : Copyright 2010 Lom Hillah (AFNOR)
    License                        : GNU GPL v3 (See http://www.gnu.org/licenses/)
    Revisions  					           -
    (Number/Date/Author/[Comment]) : 1/August 13, 2009/L.H./Inception
                                   : 2/March 3, 2010/L.H/Reuse CoreModel constraints with extends
  </p>
  
  <iso:phase 
    id="PTNet"
    see="http://www.pnml.org/version-2009/grammar/ptnet.pntd">
    <p>
      In this schema we provide a phase for PT nets.
      Since the Core Model schema is included, its phase 
      will be activated  as well during validation.
      
      If you extends this schema with another phase, you may set a default phase
      for the validation in the @defaultPhase attribute of the iso:schema element.
    </p>
 
    <iso:active pattern="CheckArcSourceTargetDifferent"/>
  </iso:phase>
  
  <!-- Pattern for PT nets-->
  <iso:pattern id="CheckArcSourceTargetDifferent">
    <iso:rule context="dp:arc[@source and @target]">
      <let name="placeSource" value="key('nodeId', current()/@source)/(self::dp:place|self::dp:referencePlace)[@id = current()/@source]"/>
      <let name="transitionTarget" value="key('nodeId', current()/@target)/(self::dp:transition|self::dp:referenceTransition)[@id = current()/@target]"/>
      <let name="transitionSource" value="key('nodeId', current()/@source)/(self::dp:transition|self::dp:referenceTransition)[@id = current()/@source]"/>
      <let name="placeTarget" value="key('nodeId', current()/@target)/(self::dp:place|self::dp:referencePlace)[@id = current()/@target]"/>
      <iso:assert test="(count($placeSource) = 1 and count($transitionTarget) = 1) or 
        (count($transitionSource) = 1 and count($placeTarget) = 1)" diagnostics="differentNodeKinds">
        The arc <value-of select="@id"/> must connect two different kinds of nodes.
      </iso:assert>
    </iso:rule>
  </iso:pattern>
  
  <!--
    Include all the children of the referenced schematron mini-schema for Core Model.
    See http://www.eccnet.com/pipermail/schematron/2009-April/000178.html
  -->
  <iso:extends href="CMconstraints.sch"/>
  
  
  <iso:diagnostics> 
    <iso:diagnostic id="differentNodeKinds"> 
      In a Place/Transition net, an arc may connect a place to a transition or vice versa.
      It may also connect a place to a referenceTransition (or vice versa) or a transition to 
      a referencePlace (or vice versa).
      It may also connect a referencePlace to a referenceTransition (or vice versa).
    </iso:diagnostic> 
  </iso:diagnostics> 
  
</iso:schema>

