# baseURI: http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-generation-0.2
# imports: http://onto.fel.cvut.cz/ontologies/aviation
# imports: http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-0.2
# imports: http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-config-0.2
# imports: http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-generated-0.2
# imports: http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-lib
# imports: http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-mapping-0.2
# imports: http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-static-0.2
# imports: http://onto.fel.cvut.cz/ontologies/eccairs/aviation-3.4.0.2/operational-full
# imports: http://onto.fel.cvut.cz/ontologies/eccairs/mapping/model
# imports: http://onto.fel.cvut.cz/ontologies/eccairs/model
# imports: http://onto.fel.cvut.cz/ontologies/form-layout
# imports: http://onto.fel.cvut.cz/ontologies/lib/sm-module-adapter
# imports: http://onto.fel.cvut.cz/ontologies/lib/spin-function
# imports: http://onto.fel.cvut.cz/ontologies/reporting-tool/model
# imports: http://www.w3.org/2004/02/skos/core

@prefix : <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-generation-0.2/> .
@prefix aviation: <http://onto.fel.cvut.cz/ontologies/aviation/> .
@prefix aviation-safety: <http://onto.fel.cvut.cz/ontologies/aviation-safety/> .
@prefix doc: <http://onto.fel.cvut.cz/ontologies/documentation/> .
@prefix e-a-3.4.0.2: <http://onto.fel.cvut.cz/ontologies/eccairs/aviation-3.4.0.2/> .
@prefix e-m: <http://onto.fel.cvut.cz/ontologies/eccairs/model/> .
@prefix e-m-i: <http://onto.fel.cvut.cz/ontologies/eccairs/model/instance#> .
@prefix e-m-map: <http://onto.fel.cvut.cz/ontologies/eccairs/mapping/model/> .
@prefix e-m-v: <http://onto.fel.cvut.cz/ontologies/eccairs/model-view/> .
@prefix fn: <http://www.w3.org/2005/xpath-functions#> .
@prefix form: <http://onto.fel.cvut.cz/ontologies/form/> .
@prefix form-ecc: <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form/> .
@prefix form-ecc-cfg-0.2: <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-config-0.2/> .
@prefix form-ecc-gen-0.2: <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-generation-0.2/> .
@prefix form-ecc-lib: <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-lib/> .
@prefix form-ecc-map-0.2: <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-mapping-0.2/> .
@prefix form-layou: <http://onto.fel.cvut.cz/ontologies/form-layout> .
@prefix form-lt: <http://onto.fel.cvut.cz/ontologies/form-layout/> .
@prefix kbss-module: <http://onto.fel.cvut.cz/ontologies/lib/module/> .
@prefix kbss-spif: <http://onto.fel.cvut.cz/ontologies/lib/spin-function/> .
@prefix km-sesame: <http://onto.fel.cvut.cz/ontologies/lib/module/sesame/> .
@prefix model-vie: <http://onto.fel.cvut.cz/ontologies/eccairs/model-view> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix sm: <http://topbraid.org/sparqlmotion#> .
@prefix sml: <http://topbraid.org/sparqlmotionlib#> .
@prefix sp: <http://spinrdf.org/sp#> .
@prefix spif: <http://spinrdf.org/spif#> .
@prefix spin: <http://spinrdf.org/spin#> .
@prefix spl: <http://spinrdf.org/spl#> .
@prefix turtle: <http://www.semanticweb.org/owl/owlapi/turtle#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<http://inbas.cz/form-generation-test/event_type>
  rdf:type owl:DatatypeProperty ;
  rdfs:label "event type" ;
  rdfs:range xsd:string ;
.
form-ecc-cfg-0.2:bind-eccairs-mapping-service-uri
  sm:next form-ecc-gen-0.2:attach-event-filter ;
.
form-ecc-cfg-0.2:bind-eccairs-repository
  sm:next form-ecc-gen-0.2:bind-eccairs-model-service-uri ;
  sm:next form-ecc-gen-0.2:bind-operational-full-service-uri ;
.
form-ecc-cfg-0.2:bind-eccairs-schema-service-uri
  sm:next form-ecc-gen-0.2:attach-possible-values-hook ;
  sm:next form-ecc-gen-0.2:construct-answers ;
  sm:next form-ecc-gen-0.2:construct-question-templates ;
  sm:next form-ecc-gen-0.2:extract-eccairs-schema ;
  sm:next form-ecc-gen-0.2:populate-question-possible-values ;
.
form-ecc-cfg-0.2:bind-rdf4j-server
  sm:next form-ecc-gen-0.2:bind-imported-reports-repository-uri ;
  sm:next form-ecc-gen-0.2:bind-reports-repository ;
  sm:next form-ecc-gen-0.2:bind-sample-reports-repository ;
  sm:next form-ecc-gen-0.2:bind-schema-mapping-uri ;
.
form-ecc-cfg-0.2:isIdempotent
  rdf:type rdf:Property ;
  rdfs:subPropertyOf sp:arg ;
.
<http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-generation-0.2>
  rdf:type owl:Ontology ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/aviation> ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-0.2> ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-config-0.2> ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-generated-0.2> ;
  owl:imports aviation:eccairs-form-lib ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-mapping-0.2> ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-static-0.2> ;
  owl:imports e-a-3.4.0.2:operational-full ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/eccairs/mapping/model> ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/eccairs/model> ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/form-layout> ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/lib/sm-module-adapter> ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/lib/spin-function> ;
  owl:imports <http://onto.fel.cvut.cz/ontologies/reporting-tool/model> ;
  owl:imports <http://www.w3.org/2004/02/skos/core> ;
  owl:versionInfo "Created with TopBraid Composer" ;
.
form-ecc-gen-0.2:BindRootQuestion
  rdf:type sml:BindBySelect ;
  sm:next form-ecc-gen-0.2:layout-form ;
  sml:selectQuery [
      rdf:type sp:Select ;
      sp:resultVariables (
          [
            sp:varName "rootQuestion" ;
          ]
        ) ;
      sp:text """SELECT ?rootQuestion 
WHERE {
    ?rootQuestion a doc:question .
# TODO temporal fix remove !!!
   OPTIONAL {
      ?rootQuestion form:has-template ?rootQT .
   }
   FILTER( (?rootQT = e-a-3.4.0.2:e-24-qt) || (!bound(?rootQT))) 
    FILTER NOT EXISTS {
        ?superQuestion doc:has_related_question ?rootQuestion . 
        ?superQuestion a doc:question
   }
}""" ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "rootQuestion" ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "rootQT" ;
                    ] ;
                  sp:predicate form:has-template ;
                  sp:subject [
                      sp:varName "rootQuestion" ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:or ;
                sp:arg1 [
                    rdf:type sp:eq ;
                    sp:arg1 [
                        sp:varName "rootQT" ;
                      ] ;
                    sp:arg2 e-a-3.4.0.2:e-24-qt ;
                  ] ;
                sp:arg2 [
                    rdf:type sp:not ;
                    sp:arg1 [
                        rdf:type sp:bound ;
                        sp:arg1 [
                            sp:varName "rootQT" ;
                          ] ;
                      ] ;
                  ] ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "rootQuestion" ;
                        ] ;
                      sp:predicate doc:has_related_question ;
                      sp:subject [
                          sp:varName "superQuestion" ;
                        ] ;
                    ]
                    [
                      sp:object doc:question ;
                      sp:predicate rdf:type ;
                      sp:subject [
                          sp:varName "superQuestion" ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
    ] ;
  rdfs:label "Bind root question" ;
.
form-ecc-gen-0.2:BindSampleReportUri
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:bind-sample-report-service-uri ;
  sm:outputVariable "sampleReportUri" ;
  sml:value "http://onto.fel.cvut.cz/ontologies/documentation/report-i/246BAFD49E19E611B897002655546824.e5x/246BAFD49E19E611B897002655546824.xml" ;
  rdfs:comment """######################
###### NOT WORKING #####
######################

### \" BMS140 letící DCT PITOK se EC EPWW nepodařilo přeladit na kmitočet sektoru M. \"@en
http://onto.fel.cvut.cz/ontologies/documentation/report-i/246BAFD49E19E611B897002655546824.e5x/246BAFD49E19E611B897002655546824.xml


### PIC po DEP ohlasil střet s ptákem v bodě rotace.
http://onto.fel.cvut.cz/ontologies/documentation/report-i/36E482143035E611B897002655546824.e5x/36E482143035E611B897002655546824.xml

#####################
###### DEPRECATED #####
#####################

### RCOM LKPR - Rušení FREQ 132,890 
http://onto.fel.cvut.cz/ontologies/report-2FA6D6D1AE15E611B897002655546824.xml
""" ;
  rdfs:label "Bind sample report uri" ;
.
form-ecc-gen-0.2:ExportEccairs
  rdf:type sml:ExportToRDFFile ;
  sml:baseURI "http://onto.fel.cvut.cz/ontologies/eccairs/aviation-3.4.0.2" ;
  sml:targetFilePath "/inbas/forms/eccairs-0.2/output/aviation-eccairs-3.4.0.2.ttl" ;
  rdfs:label "Save eccairs schema" ;
.
form-ecc-gen-0.2:SaveExampleReport
  rdf:type sml:ExportToRDFFile ;
  sml:baseURI "http://onto.fel.cvut.cz/ontologies/report-2FA6D6D1AE15E611B897002655546824.xml/temp" ;
  sml:targetFilePath "/inbas/forms/eccairs-0.2/output/sample-report.ttl" ;
  rdfs:label "Save sample report" ;
.
form-ecc-gen-0.2:annotate-saved-questions
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:recover-question-template ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object "saved-questions" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
   ?q form:is-relevant-if \"saved-questions\" .
}
WHERE {
    ?q a doc:question .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "Annotate saved questions"^^xsd:string ;
.
form-ecc-gen-0.2:appRepositoryUrl
  rdf:type owl:DatatypeProperty ;
  rdfs:label "Application repository url" ;
  rdfs:range xsd:string ;
.
form-ecc-gen-0.2:attach-clones-values
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question that is both clone and cloned
ASK
WHERE {
    ?q form:is-clone-of-question ?clonedQ .
     ?cloneQ form:is-clone-of-question ?q .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "clonedQ"^^xsd:string ;
              ] ;
            sp:predicate form:is-clone-of-question ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q"^^xsd:string ;
              ] ;
            sp:predicate form:is-clone-of-question ;
            sp:subject [
                sp:varName "cloneQ"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question that is both clone and cloned"^^xsd:string ;
    ] ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question that is clone of multiple questions
ASK
WHERE {
    ?q form:is-clone-of-question ?clonedQ1 ;
         form:is-clone-of-question ?clonedQ2 .
    FILTER(?clonedQ1 != ?clonedQ2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "clonedQ1"^^xsd:string ;
              ] ;
            sp:predicate form:is-clone-of-question ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "clonedQ2"^^xsd:string ;
              ] ;
            sp:predicate form:is-clone-of-question ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "clonedQ1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "clonedQ2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question that is clone of multiple questions"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question clone without answer value 
ASK
WHERE {
    ?q a doc:question ;
         form:is-clone-of-question ?clonedQ .
    FILTER NOT EXISTS { 
             ?q doc:has_answer ?a .
             ?a  doc:has_data_value ?qPath .    
   }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "clonedQ"^^xsd:string ;
              ] ;
            sp:predicate form:is-clone-of-question ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "a"^^xsd:string ;
                        ] ;
                      sp:predicate doc:has_answer ;
                      sp:subject [
                          sp:varName "q"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object [
                          sp:varName "qPath"^^xsd:string ;
                        ] ;
                      sp:predicate doc:has_data_value ;
                      sp:subject [
                          sp:varName "a"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question clone without answer value"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:disable-question-clones ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "boundA"^^xsd:string ;
              ] ;
            sp:predicate doc:has_answer ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object doc:answer ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "boundA"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qPath"^^xsd:string ;
              ] ;
            sp:predicate doc:has_data_value ;
            sp:subject [
                sp:varName "boundA"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
      ?q doc:has_answer ?boundA .
      ?boundA   a doc:answer ;
                        doc:has_data_value ?qPath .    
}
WHERE {
    ?q form:is-clone-of-question ?clonedQ .
    ?clonedQ form-ecc-gen-0.2:has-question-path ?clonedQPath .
    OPTIONAL {
        ?q doc:has_answer ?a .
    }
    BIND(concat(\"links to \", ?clonedQPath, \"\")  as ?qPath)
    BIND(form-ecc-lib:create-a(?q) as ?newA)
    BIND(COALESCE(?a, ?newA) as ?boundA)    
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "clonedQ"^^xsd:string ;
              ] ;
            sp:predicate form:is-clone-of-question ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "clonedQPath"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:has-question-path ;
            sp:subject [
                sp:varName "clonedQ"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "a"^^xsd:string ;
                    ] ;
                  sp:predicate doc:has_answer ;
                  sp:subject [
                      sp:varName "q"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:concat ;
                sp:arg1 "links to " ;
                sp:arg2 [
                    sp:varName "clonedQPath"^^xsd:string ;
                  ] ;
                sp:arg3 "" ;
              ] ;
            sp:variable [
                sp:varName "qPath"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-a ;
                sp:arg1 [
                    sp:varName "q"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "newA"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:coalesce ;
                sp:arg1 [
                    sp:varName "a"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "newA"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "boundA"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "attach-clone-values"^^xsd:string ;
.
form-ecc-gen-0.2:attach-eccairs-views
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# each section defines subset of attributes of exactly one entity
ASK
WHERE {
#        SERVICE ?operationalFullServiceUri {          
#            ?topic e-mv:entityid ?ent .
#            ?topic  e-mv:has_child  ?section .
#            ?section  e-mv:allattributes   ?attr .
#            ?section rdfs:label ?sectionLabel . 
#        }
}"""^^xsd:string ;
      sp:where () ;
      rdfs:comment "each section defines subset of attributes of exactly one entity"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question template relation that does not have its reification constructed
ASK WHERE {
     ?parent_qt form:has-subtemplate ?child_qt .
     FILTER NOT EXISTS {
         ?r_qt_relation rdf:subject ?parent_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?child_qt .
    }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "parent_qt"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "parent_qt"^^xsd:string ;
                        ] ;
                      sp:predicate rdf:subject ;
                      sp:subject [
                          sp:varName "r_qt_relation"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object form:has-subtemplate ;
                      sp:predicate rdf:predicate ;
                      sp:subject [
                          sp:varName "r_qt_relation"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object [
                          sp:varName "child_qt"^^xsd:string ;
                        ] ;
                      sp:predicate rdf:object ;
                      sp:subject [
                          sp:varName "r_qt_relation"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question template relation that does not have its reification constructed"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a section with sub-template relation that does not have its reification
ASK WHERE {
     ?section_qt form:has-subtemplate ?child_qt ;
                         form:has-origin-type e-mv:section .
     FILTER NOT EXISTS {
         ?r_qt_relation rdf:subject ?section_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?child_qt .
    }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m-v:section ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "section_qt"^^xsd:string ;
                        ] ;
                      sp:predicate rdf:subject ;
                      sp:subject [
                          sp:varName "r_qt_relation"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object form:has-subtemplate ;
                      sp:predicate rdf:predicate ;
                      sp:subject [
                          sp:varName "r_qt_relation"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object [
                          sp:varName "child_qt"^^xsd:string ;
                        ] ;
                      sp:predicate rdf:object ;
                      sp:subject [
                          sp:varName "r_qt_relation"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a section with sub-template relation that does not have its reification"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:attach-template-relations-metadata ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "ent_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:question-template ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attr_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "sectionLabelFixed"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m-v:section ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_sec_attr_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_sec_attr_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attr_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_sec_attr_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "isLinkFlag"^^xsd:string ;
              ] ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "r_sec_attr_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "ent_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_ent_sec_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_ent_sec_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_ent_sec_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "ent_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attr_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "eccairs-data-schema" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# constuct eccairs views
CONSTRUCT {
# TODO -- not very readable .. should have been constructed incrementaly using construct-recursion 
     ?ent_qt form:has-subtemplate  ?section_qt .
     ?section_qt a form:question-template ;
               form:has-subtemplate ?attr_qt ;
               rdfs:label ?sectionLabelFixed ;    
               form:has-template-origin   ?section ;
               form:has-origin-type e-mv:section .
     ?r_sec_attr_qt_relation rdf:subject ?section_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?attr_qt ;
               form:is-relevant-if ?isLinkFlag .
    ?r_ent_sec_qt_relation rdf:subject ?ent_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?section_qt .
      
# filtering rule
     ?r_qt_relation 
               rdf:subject ?ent_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?attr_qt ;    
               form:is-relevant-if \"eccairs-data-schema\" .               
} WHERE {
# match question template entity -> attribute
    ?ent_qt form:has-subtemplate ?attr_qt .
    ?ent_qt form:has-template-origin ?ent .
    ?attr_qt form:has-template-origin ?attr .
    ?ent a e-m:entity .
    ?attr a e-m:attribute .
# match softlinks
     ?r_qt_relation rdf:subject ?ent_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?attr_qt .
    OPTIONAL {
             ?r_qt_relation form:is-relevant-if ?isLinkFlag .
    }
    SERVICE ?operationalFullServiceUri {          
         ?topic e-mv:entityid ?ent .
         ?topic  e-mv:has_child  ?section .
         ?section  e-mv:allattributes   ?attr .
         ?section rdfs:label ?sectionLabel . 
     }
# bind new reification of entity -> section relation
    BIND(md5(concat(str(?r_qt_relation), \"-\", str(?section))) as ?r_new_qt_relation_id)
    BIND(iri(concat(str(?ent), \"-\", ?r_new_qt_relation_id, \"-qts-relation\"))   as ?r_ent_sec_qt_relation)
# bind new reification of section -> attribute relation
    BIND(iri(concat(str(?section), \"-\", ?r_new_qt_relation_id, \"-qts-relation\"))   as ?r_sec_attr_qt_relation)

    BIND(form-ecc-lib:create-qt(?section) as ?section_qt) 
# BIND(spif:titleCase(fn:lower-case(replace(?sectionLabel, \"_\", \" \"))) as ?sectionLabelFixed)
    BIND(fn:lower-case(replace(?sectionLabel, \"_\", \" \")) as ?sectionLabelFixed)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "attr_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "ent_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "ent"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "ent_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attr"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "attr_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m:entity ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "ent"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m:attribute ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "attr"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "ent_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attr_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "isLinkFlag"^^xsd:string ;
                    ] ;
                  sp:predicate form:is-relevant-if ;
                  sp:subject [
                      sp:varName "r_qt_relation"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "ent"^^xsd:string ;
                    ] ;
                  sp:predicate e-m-v:entityid ;
                  sp:subject [
                      sp:varName "topic"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "section"^^xsd:string ;
                    ] ;
                  sp:predicate e-m-v:has_child ;
                  sp:subject [
                      sp:varName "topic"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "attr"^^xsd:string ;
                    ] ;
                  sp:predicate e-m-v:allattributes ;
                  sp:subject [
                      sp:varName "section"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "sectionLabel"^^xsd:string ;
                    ] ;
                  sp:predicate rdfs:label ;
                  sp:subject [
                      sp:varName "section"^^xsd:string ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "operationalFullServiceUri"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:md5 ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "r_qt_relation"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "-" ;
                    sp:arg3 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "section"^^xsd:string ;
                          ] ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "r_new_qt_relation_id"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:iri ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "ent"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "-" ;
                    sp:arg3 [
                        sp:varName "r_new_qt_relation_id"^^xsd:string ;
                      ] ;
                    sp:arg4 "-qts-relation" ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "r_ent_sec_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:iri ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "section"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "-" ;
                    sp:arg3 [
                        sp:varName "r_new_qt_relation_id"^^xsd:string ;
                      ] ;
                    sp:arg4 "-qts-relation" ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "r_sec_attr_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-qt ;
                sp:arg1 [
                    sp:varName "section"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type fn:lower-case ;
                sp:arg1 [
                    rdf:type sp:replace ;
                    sp:arg1 [
                        sp:varName "sectionLabel"^^xsd:string ;
                      ] ;
                    sp:arg2 "_" ;
                    sp:arg3 " " ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "sectionLabelFixed"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "constuct eccairs views"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "attach-eccairs-views" ;
.
form-ecc-gen-0.2:attach-event-filter
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:attach-transitive-event-type-filter-to-templates ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object "uniset-event-enhancement" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 1 - annotate uniset attributes 
CONSTRUCT {
   ?qt form:is-relevant-if \"uniset-event-enhancement\" .
}
WHERE {
    SERVICE ?eccairsMappingServiceUri {	
		?situation a e-m-map:organization-to-attribute-mapping ; 
          			e-m-map:has-if-present-organization-type ?organizationType ;
#          			e-m-map:has-if-present-attribute-value ?eccRelAttributeValue .
          			e-m-map:has-related-attribute-value ?eccAttributeValue .
    }
   ?qt form:has-template-origin ?eccAttributeValue . 
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object e-m-map:organization-to-attribute-mapping ;
                  sp:predicate rdf:type ;
                  sp:subject [
                      sp:varName "situation"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "organizationType"^^xsd:string ;
                    ] ;
                  sp:predicate e-m-map:has-if-present-organization-type ;
                  sp:subject [
                      sp:varName "situation"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "eccAttributeValue"^^xsd:string ;
                    ] ;
                  sp:predicate e-m-map:has-related-attribute-value ;
                  sp:subject [
                      sp:varName "situation"^^xsd:string ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "eccairsMappingServiceUri"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "eccAttributeValue"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - annotate uniset attributes"^^xsd:string ;
    ] ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "eccEventType"^^xsd:string ;
              ] ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m:value ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "eccEventType"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 0 - annotate event-type specific attributes 
CONSTRUCT {
   ?qt form:is-relevant-if ?eccEventType .
   ?eccEventType a e-m:value .
}
WHERE {
    SERVICE ?eccairsMappingServiceUri {	
		?situation a e-m-map:event-type-to-attribute-mapping ; 
					e-m-map:has-event-type-value ?eccEventType ;
          			e-m-map:has-if-present-organization-type ?organizationType ;
#          			e-m-map:has-if-present-attribute-value ?eccRelAttributeValue .
          			e-m-map:has-related-attribute-value ?eccAttributeValue .
    }
   ?qt form:has-template-origin ?eccAttributeValue . 
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object e-m-map:event-type-to-attribute-mapping ;
                  sp:predicate rdf:type ;
                  sp:subject [
                      sp:varName "situation"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "eccEventType"^^xsd:string ;
                    ] ;
                  sp:predicate e-m-map:has-event-type-value ;
                  sp:subject [
                      sp:varName "situation"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "organizationType"^^xsd:string ;
                    ] ;
                  sp:predicate e-m-map:has-if-present-organization-type ;
                  sp:subject [
                      sp:varName "situation"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "eccAttributeValue"^^xsd:string ;
                    ] ;
                  sp:predicate e-m-map:has-related-attribute-value ;
                  sp:subject [
                      sp:varName "situation"^^xsd:string ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "eccairsMappingServiceUri"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "eccAttributeValue"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - annotate event-type specific attributes"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "Attach attribute-based event-type filter to templates"^^xsd:string ;
.
form-ecc-gen-0.2:attach-event-type-question-links
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there exists question that relates to link but is not clone of any other question
ASK
WHERE {
    FILTER(true = false)
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:eq ;
                sp:arg1 "true"^^xsd:boolean ;
                sp:arg2 "false"^^xsd:boolean ;
              ] ;
          ]
        ) ;
      rdfs:comment "there exists question that relates to link but is not clone of any other question"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:form-generator-xxx ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "q2"^^xsd:string ;
              ] ;
            sp:predicate form:is-clone-of-question ;
            sp:subject [
                sp:varName "q1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "is-question-clone" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "q1"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# construct links between event-type questions
CONSTRUCT {
    ?q1 form:is-clone-of-question ?q2 ;
           form:is-relevant-if \"is-question-clone\" .
} 
WHERE {
# bind question 1 
     ?parentQ1 doc:has_related_question ?q1 ;
            form:has-template ?parentQT1 .
     ?q1 a doc:question ;
           form:has-template ?qt ;
### constructed by event-enhancement
           form:is-relevant-if \"event-enhancement\" .
     ?q1QTSRelation rdf:subject ?parentQT1 ;
                                 rdf:object ?qt.

# bind question 2
     ?parentQ2 doc:has_related_question ?q2 ;
            form:has-template ?parentQT2 .
     ?q2 a doc:question ;
           form:has-template ?qt ;
### constructed by event-enhancement
           form:is-relevant-if \"event-enhancement\" .
     ?q2QTSRelation rdf:subject ?parentQT2 ;
                                 rdf:object ?qt.
# check link template
     ?q1QTSRelation form:is-link-template-of ?q2QTSRelation .   
     FILTER(?q1 != ?q2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "q1"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parentQT1"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "parentQ1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "q1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "event-enhancement" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "q1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parentQT1"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "q1QTSRelation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "q1QTSRelation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q2"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ2"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parentQT2"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "parentQ2"^^xsd:string ;
              ] ;
          ]
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q2"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "q2"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "event-enhancement" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "q2"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parentQT2"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "q2QTSRelation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "q2QTSRelation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q2QTSRelation"^^xsd:string ;
              ] ;
            sp:predicate form:is-link-template-of ;
            sp:subject [
                sp:varName "q1QTSRelation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "q1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "q2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "construct links between event-type questions"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "attach-event-type-question-links"^^xsd:string ;
.
form-ecc-gen-0.2:attach-imported-answers
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:filter-populable-answers ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object doc:answer ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "a"^^xsd:string ;
              ] ;
            sp:predicate doc:has_answer ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
    ?a a doc:answer .
    ?q doc:has_answer ?a .
}
WHERE {
    ?q a doc:question .
    BIND(form-ecc-lib:create-a(?q) as ?a)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-a ;
                sp:arg1 [
                    sp:varName "q"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  rdfs:label "attach-imported-answers"^^xsd:string ;
.
form-ecc-gen-0.2:attach-imported-question-links
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:construct-questions-from-templates ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "q2"^^xsd:string ;
              ] ;
            sp:predicate form:is-clone-of-question ;
            sp:subject [
                sp:varName "q1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "is-question-clone" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "q1"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# construct links between imported questions
CONSTRUCT {
    ?q1 form:is-clone-of-question ?q2 ;
           form:is-relevant-if \"is-question-clone\" .
}
WHERE {
    ?q1 a doc:question ;
           form:has-question-origin ?q1Origin .
    ?q1Origin form-ecc-gen-0.2:is-origin-of-question-templates-reification ?q1QTSRelation  ;
                      rdf:object ?qObject .
    ?q2 a doc:question ;
           form:has-question-origin ?q2Origin .
    ?q2Origin form-ecc-gen-0.2:is-origin-of-question-templates-reification ?q2QTSRelation  ;
                      rdf:object ?qObject .
   ?q1QTSRelation form:is-link-template-of ?q2QTSRelation .
   FILTER(?q1 != ?q2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q1Origin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "q1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q1QTSRelation"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-templates-reification ;
            sp:subject [
                sp:varName "q1Origin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qObject"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "q1Origin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q2"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q2Origin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "q2"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q2QTSRelation"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-templates-reification ;
            sp:subject [
                sp:varName "q2Origin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qObject"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "q2Origin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q2QTSRelation"^^xsd:string ;
              ] ;
            sp:predicate form:is-link-template-of ;
            sp:subject [
                sp:varName "q1QTSRelation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "q1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "q2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "construct links between imported questions"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "attach-imported-question-links"^^xsd:string ;
.
form-ecc-gen-0.2:attach-imported-questions
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question template without label
ASK
WHERE {
    ?qt a form:question-template .
    FILTER NOT EXISTS {
        ?qt rdfs:label ?label .
    } .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:question-template ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "label"^^xsd:string ;
                        ] ;
                      sp:predicate rdfs:label ;
                      sp:subject [
                          sp:varName "qt"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question template without label"^^xsd:string ;
    ] ;
  kbss-module:has-max-iteration-count "15"^^xsd:string ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 0 - there is a question without specified question template
ASK WHERE {
    ?question a doc:question .
    FILTER NOT EXISTS {
        ?question form:has-template ?questionTemplate .
    } .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "question"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "questionTemplate"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-template ;
                      sp:subject [
                          sp:varName "question"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - there is a question without specified question template"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 1 - there is a question without specified question origin
ASK WHERE {
    ?question a doc:question .
    FILTER NOT EXISTS {
        ?question form:has-question-origin ?origin .
    } .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "question"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "origin"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-question-origin ;
                      sp:subject [
                          sp:varName "question"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - there is a question without specified question origin"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 3 - question for a question origin does not exist
ASK
WHERE {
    FILTER(! bound(?savedQAExists))    
    
    ?questionOrigin a form:question-origin .
    FILTER NOT EXISTS {
         ?q form:has-question-origin ?questionOrigin .
    }
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "savedQAExists"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "questionOrigin"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "questionOrigin"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-question-origin ;
                      sp:subject [
                          sp:varName "q"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "3 - question for a question origin does not exist"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 4 - there is a question with two parent questions w.r.t. has_related_question relation
ASK
WHERE {
    ?parentQ1 doc:has_related_question ?childQ .
    ?parentQ2 doc:has_related_question ?childQ .
    FILTER(?parentQ1 != ?parentQ2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "childQ"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childQ"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ2"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "parentQ1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "parentQ2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "4 - there is a question with two parent questions w.r.t. has_related_question relation"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:attach-imported-answers ;
  sm:next form-ecc-gen-0.2:attach-imported-question-links ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "childQ"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "imported-question" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childLabel"^^xsd:string ;
              ] ;
            sp:predicate skos:altLabel ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 0 - construct simple imported questions (without section)
CONSTRUCT {
    ?parentQ doc:has_related_question ?childQ .
    ?childQ  a doc:question ;
                  form:has-question-origin ?childOrigin ;
                  form:has-template ?childQT ;
                  form:is-relevant-if \"imported-question\" .
# for debugging only
     ?childQ skos:altLabel ?childLabel .
}
WHERE {
# precondition -- questions where not saved yet
    FILTER(! bound(?savedQAExists))

# bind parent Q 
    ?parentQ a doc:question ;
                     form:has-question-origin ?parentOrigin ;
                     form:has-template ?parentQT .

# parent must not be created from softlink
    ?parentOrigin form-ecc-gen-0.2:is-origin-of-question-templates-reification ?parentQTRelation .
    FILTER NOT EXISTS {
        ?parentQTRelation form:is-relevant-if \"is-link\" .
    }
                     
# bind childOrigin, childQT;  bound(?childOrigin) => not a section    
    ?childOrigin a form:question-origin ;
                         form-ecc-gen-0.2:is-origin-of-question-template ?childQT ;
                         rdf:subject ?parentObject .
    ?parentOrigin rdf:object ?parentObject .

# retrive from QT schema
    ?parentQT form:has-subtemplate ?childQT .
                          
# childQT is entity => childOrigin  is one per question
    BIND(form-ecc-lib:create-q(concat(str(?childOrigin), \"-\", ?executionId)) AS ?childQ)

# for debugging only
    ?childQT rdfs:label ?childLabel .
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "savedQAExists"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "parentQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parentOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "parentQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parentQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "parentQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parentQTRelation"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-templates-reification ;
            sp:subject [
                sp:varName "parentOrigin"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object "is-link" ;
                      sp:predicate form:is-relevant-if ;
                      sp:subject [
                          sp:varName "parentQTRelation"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "childOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childQT"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-template ;
            sp:subject [
                sp:varName "childOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parentObject"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "childOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parentObject"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "parentOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "parentQT"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-q ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "childOrigin"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "-" ;
                    sp:arg3 [
                        sp:varName "executionId"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "childQT"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - construct simple imported questions (without section)"^^xsd:string ;
    ] ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "secQ"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "entQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "secQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "secOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "secQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "secQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "secQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "imported-question" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "secQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "section-question" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "secQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attrQ"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "secQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "attrQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attrOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "attrQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attrQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "attrQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "imported-question" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "attrQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "part-of-view-question" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "attrQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "isLinkFlag"^^xsd:string ;
              ] ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "attrQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "secLabel"^^xsd:string ;
              ] ;
            sp:predicate skos:altLabel ;
            sp:subject [
                sp:varName "secQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attrLabel"^^xsd:string ;
              ] ;
            sp:predicate skos:altLabel ;
            sp:subject [
                sp:varName "attrQ"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 1 - construct imported questions within section
CONSTRUCT {
      ?entQ doc:has_related_question ?secQ .

      ?secQ a doc:question ;
                 form:has-question-origin ?secOrigin ;
                 form:has-template ?secQT ;
				 form:is-relevant-if \"imported-question\" ;
                 form:is-relevant-if \"section-question\" ;
                 doc:has_related_question ?attrQ .
      ?attrQ a doc:question ;
                 form:has-question-origin ?attrOrigin ;
                 form:has-template ?attrQT ;
				 form:is-relevant-if \"imported-question\" ;
                 form:is-relevant-if \"part-of-view-question\" ;
                 form:is-relevant-if ?isLinkFlag .

# for debugging only
     ?secQ skos:altLabel ?secLabel .
     ?attrQ skos:altLabel ?attrLabel .
}
WHERE {
# precondition -- questions where not saved yet
    FILTER(! bound(?savedQAExists))

# bind entQ
    ?entQ a doc:question ;
                 form:has-question-origin ?entOrigin ;
                 form:has-template ?entQT .

# entQ must not be created from softlink
    ?entOrigin form-ecc-gen-0.2:is-origin-of-question-templates-reification ?entQTRelation .
    FILTER NOT EXISTS {
        ?entQTRelation form:is-relevant-if \"is-link\" .
    }

#  bind attrOrigin, attrQT
    ?attrOrigin form-ecc-gen-0.2:is-origin-of-question-template ?attrQT ;
                         rdf:subject ?entObject .
    ?entOrigin rdf:object ?entObject .


# bind entQT -> secQT -> attrQT
    ?entQT form:has-subtemplate ?secQT .
    ?secQT form:has-subtemplate ?attrQT .

# ensure secQT is section       
    ?secQT form:has-template-origin ?section .
    ?secQT form:has-origin-type e-mv:section .
       
# bind section metadata
   BIND(md5(concat(str(?entOrigin), str(?section), ?executionId)) as ?secId)
   BIND(form-ecc-lib:create-qo(?secQT) AS ?secOrigin)
   BIND(form-ecc-lib:create-q(concat(str(?section),\"-\",?secId)) AS ?secQ)  
   
# bind attr metadata
   BIND(md5(concat(str(?section), str(?attrOrigin), ?executionId)) as ?attrId)
   BIND(form-ecc-lib:create-q(concat(str(?attrOrigin),\"-\",?attrId)) AS ?attrQ)  

# for debugging only
    ?secQT rdfs:label ?secLabel .
    ?attrQT rdfs:label ?attrLabel .
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "savedQAExists"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "entQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "entOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "entQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "entQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "entQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "entQTRelation"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-templates-reification ;
            sp:subject [
                sp:varName "entOrigin"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object "is-link" ;
                      sp:predicate form:is-relevant-if ;
                      sp:subject [
                          sp:varName "entQTRelation"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attrQT"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-template ;
            sp:subject [
                sp:varName "attrOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "entObject"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "attrOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "entObject"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "entOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "secQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "entQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attrQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "secQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "secQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m-v:section ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "secQT"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:md5 ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "entOrigin"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "section"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg3 [
                        sp:varName "executionId"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "secId"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-qo ;
                sp:arg1 [
                    sp:varName "secQT"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "secOrigin"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-q ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "section"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "-" ;
                    sp:arg3 [
                        sp:varName "secId"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "secQ"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:md5 ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "section"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "attrOrigin"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg3 [
                        sp:varName "executionId"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "attrId"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-q ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "attrOrigin"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "-" ;
                    sp:arg3 [
                        sp:varName "attrId"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "attrQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "secLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "secQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attrLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "attrQT"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - construct imported questions within section"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:comment "There is no need to pay special attention to hard-links as each question origin of imported data represents exactly 1 hard-link."^^xsd:string ;
  rdfs:label "attach imported questions"^^xsd:string ;
.
form-ecc-gen-0.2:attach-initial-question-path
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:attach-label-paths ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object "" ;
            sp:predicate form-ecc-gen-0.2:has-question-path ;
            sp:subject [
                sp:varName "rootQ"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
    ?rootQ form-ecc-gen-0.2:has-question-path \"\" .
}
WHERE {     
     ?rootQT form:has-template-origin  ?rootEntity .
     ?rootQ form:has-template ?rootQT .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "rootEntity"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "rootQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "rootQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "rootQ"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  rdfs:label "attach-initial-question-path"^^xsd:string ;
.
form-ecc-gen-0.2:attach-label-paths
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-max-iteration-count "10"^^xsd:string ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question without question path assigned
ASK
WHERE {
    ?q a doc:question .
    FILTER NOT EXISTS { 
          ?q form-ecc-gen-0.2:has-question-path ?path .
   }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "path"^^xsd:string ;
                        ] ;
                      sp:predicate form-ecc-gen-0.2:has-question-path ;
                      sp:subject [
                          sp:varName "q"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question without question path assigned"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:attach-clones-values ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "childPath"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:has-question-path ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
    ?childQ form-ecc-gen-0.2:has-question-path ?childPath .
}
WHERE {
     ?parentQ form-ecc-gen-0.2:has-question-path ?parentPath .
     ?parentQ doc:has_related_question ?childQ .
     ?childQ rdfs:label ?childLabel . 
     BIND(concat(?parentPath, \"/\", ?childLabel) as ?childPath)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "parentPath"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:has-question-path ;
            sp:subject [
                sp:varName "parentQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childQ"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:concat ;
                sp:arg1 [
                    sp:varName "parentPath"^^xsd:string ;
                  ] ;
                sp:arg2 "/" ;
                sp:arg3 [
                    sp:varName "childLabel"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "childPath"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "attach question paths"^^xsd:string ;
.
form-ecc-gen-0.2:attach-possible-values-hook
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:merge-form-data ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "downloadString" ;
              ] ;
            sp:predicate form:has-possible-values-query ;
            sp:subject [
                sp:varName "question" ;
              ] ;
          ]
          [
            sp:object "type-ahead" ;
            sp:predicate form-lt:has-layout-class ;
            sp:subject [
                sp:varName "question" ;
              ] ;
          ]
        ) ;
      sp:text """# TODO nemalo by byt potreba to viazat na eccairs schema URI
CONSTRUCT {
    ?question form:has-possible-values-query ?downloadString .
#  TODO  layout sem nepatri !!!!
   ?question form-lt:has-layout-class \"type-ahead\" .
}
WHERE {
# get all attributes with predefined value type
     SERVICE ?eccairsSchemaServiceUri {
          ?eccAttribute a e-m:attribute .      
          ?eccAttribute e-m:has-value-type \"PredefinedValueList\" .
     }
    ?question a doc:question .
    ?question form:has-template ?questionTemplate .
    ?questionTemplate form:has-template-origin ?eccAttribute .       
    BIND(CONCAT(str(?eccairsSchemaServiceUri), \"&query=\") as ?dowloadPrefix)    
    BIND(replace(?attributePossibleValuesQueryTemplate, \"XXXXX\", str(?eccAttribute)) as ?downloadSuffixRaw)
    BIND(ENCODE_FOR_URI(?downloadSuffixRaw) as ?downloadSuffix)
    BIND(concat(?dowloadPrefix, ?downloadSuffix) as ?downloadString)
}""" ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object e-m:attribute ;
                  sp:predicate rdf:type ;
                  sp:subject [
                      sp:varName "eccAttribute" ;
                    ] ;
                ]
                [
                  sp:object "PredefinedValueList" ;
                  sp:predicate e-m:has-value-type ;
                  sp:subject [
                      sp:varName "eccAttribute" ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "eccairsSchemaServiceUri" ;
              ] ;
          ]
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "question" ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "questionTemplate" ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "question" ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "eccAttribute" ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "questionTemplate" ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:concat ;
                sp:arg1 [
                    rdf:type sp:str ;
                    sp:arg1 [
                        sp:varName "eccairsSchemaServiceUri" ;
                      ] ;
                  ] ;
                sp:arg2 "&query=" ;
              ] ;
            sp:variable [
                sp:varName "dowloadPrefix" ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:replace ;
                sp:arg1 [
                    sp:varName "attributePossibleValuesQueryTemplate" ;
                  ] ;
                sp:arg2 "XXXXX" ;
                sp:arg3 [
                    rdf:type sp:str ;
                    sp:arg1 [
                        sp:varName "eccAttribute" ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "downloadSuffixRaw" ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:encode_for_uri ;
                sp:arg1 [
                    sp:varName "downloadSuffixRaw" ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "downloadSuffix" ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:concat ;
                sp:arg1 [
                    sp:varName "dowloadPrefix" ;
                  ] ;
                sp:arg2 [
                    sp:varName "downloadSuffix" ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "downloadString" ;
              ] ;
          ]
        ) ;
      rdfs:comment "TODO nemalo by byt potreba to viazat na eccairs schema URI" ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "Attach possible values hook" ;
.
form-ecc-gen-0.2:attach-template-relations-metadata
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a template without label
ASK
WHERE {
    ?qt a form:question-template .
    OPTIONAL {
        ?qt rdfs:label ?qtLabel .
    }
    FILTER(! bound(?qtLabel))
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:question-template ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "qtLabel"^^xsd:string ;
                    ] ;
                  sp:predicate rdfs:label ;
                  sp:subject [
                      sp:varName "qt"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "qtLabel"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a template without label"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a subtemplate relation without label
ASK
WHERE {
    ?qtsRelation  rdf:predicate form:has-subtemplate .              
    OPTIONAL {
        ?qtsRelation rdfs:label ?qtsRelationLabel .
    }
    FILTER(! bound(?qtsRelationLabel))
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "qtsRelation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "qtsRelationLabel"^^xsd:string ;
                    ] ;
                  sp:predicate rdfs:label ;
                  sp:subject [
                      sp:varName "qtsRelation"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "qtsRelationLabel"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a subtemplate relation without label"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:filter-irrelevant-templates ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "qtsRelationLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "qtsRelation"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
    ?qtsRelation rdfs:label ?qtsRelationLabel .
}
WHERE {
        ?qtsRelation 
               rdf:predicate form:has-subtemplate ;
               rdf:object ?objQT .
        ?objQT  rdfs:label ?objQTLabel .  
        OPTIONAL {
             ?qtsRelation rdf:subject ?subjQT .
             ?subjQT rdfs:label ?subjQTLabel .
        }
        BIND(COALESCE(?subjQTLabel, \"\") as ?subjQTBoundLabel)
        BIND(concat(?subjQTBoundLabel, \" -> \", ?objQTLabel) as ?qtsRelationLabel)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "qtsRelation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "objQT"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "qtsRelation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "objQTLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "objQT"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "subjQT"^^xsd:string ;
                    ] ;
                  sp:predicate rdf:subject ;
                  sp:subject [
                      sp:varName "qtsRelation"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "subjQTLabel"^^xsd:string ;
                    ] ;
                  sp:predicate rdfs:label ;
                  sp:subject [
                      sp:varName "subjQT"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:coalesce ;
                sp:arg1 [
                    sp:varName "subjQTLabel"^^xsd:string ;
                  ] ;
                sp:arg2 "" ;
              ] ;
            sp:variable [
                sp:varName "subjQTBoundLabel"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:concat ;
                sp:arg1 [
                    sp:varName "subjQTBoundLabel"^^xsd:string ;
                  ] ;
                sp:arg2 " -> " ;
                sp:arg3 [
                    sp:varName "objQTLabel"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "qtsRelationLabel"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "attach-subtemplate-relation-metadata"^^xsd:string ;
.
form-ecc-gen-0.2:attach-transitive-event-type-filter-to-templates
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-max-iteration-count "6"^^xsd:string ;
  sm:next form-ecc-gen-0.2:bind-event-type-matcher ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object "uniset-event-enhancement" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "parentQT"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 1 - propagates is-relevant-if uniset-flag from attributes to entities
CONSTRUCT {
    ?parentQT form:is-relevant-if \"uniset-event-enhancement\" .
}
WHERE {
    ?parentQT form:has-subtemplate ?childQT .
    ?childQT form:is-relevant-if \"uniset-event-enhancement\" .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "childQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "parentQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "uniset-event-enhancement" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "childQT"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - propagates is-relevant-if uniset-flag from attributes to entities"^^xsd:string ;
    ] ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "eccEventType"^^xsd:string ;
              ] ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "parentQT"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 0 - propagates is-relevant-if event from attributes to entities
CONSTRUCT {
    ?parentQT form:is-relevant-if  ?eccEventType .
}
WHERE {
    ?parentQT form:has-subtemplate ?childQT .
    ?childQT form:is-relevant-if ?eccEventType .
    ?eccEventType a e-m:value .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "childQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "parentQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "eccEventType"^^xsd:string ;
              ] ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "childQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m:value ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "eccEventType"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - propagates is-relevant-if event from attributes to entities"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "Attach entity-based event-type filter to templates"^^xsd:string ;
.
form-ecc-gen-0.2:bind-attribute-query
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:attach-possible-values-hook ;
  sm:outputVariable "attributePossibleValuesQueryTemplate" ;
  sml:value """prefix e-m: <http://onto.fel.cvut.cz/ontologies/eccairs/model/> 
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
CONSTRUCT {
     ?value rdfs:label ?label .
     ?value rdfs:comment ?explanation .
}
WHERE {
         ?eccAttribute a e-m:attribute .
         ?eccAttribute e-m:has-child+ ?value .  
         ?value rdfs:label ?label .
         ?value e-m:has-explanation ?explanation .
} 
VALUES (?eccAttribute) {
    (<XXXXX>)
}""" ;
  rdfs:label "bind-attribute-query" ;
.
form-ecc-gen-0.2:bind-concrete-report-service-uri
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:extract-concrete-report ;
  sm:outputVariable "concreteReportServiceUri" ;
  sml:value [
      rdf:type kbss-spif:create-sparql-service-url ;
      sp:arg1 [
          sp:varName "repositoryUrl" ;
        ] ;
      sp:arg2 [
          sp:varName "reportGraphId" ;
        ] ;
    ] ;
  rdfs:label "Bind concrete report service uri" ;
.
form-ecc-gen-0.2:bind-eccairs-model-service-uri
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:construct-question-templates ;
  sm:outputVariable "eccairsModelServiceUri" ;
  sml:value [
      rdf:type kbss-spif:create-sparql-service-url ;
      sp:arg1 [
          sp:varName "eccairsRepositoryUri" ;
        ] ;
      sp:arg2 "http://onto.fel.cvut.cz/ontologies/eccairs/model" ;
    ] ;
  rdfs:label "Bind eccairs model service uri" ;
.
form-ecc-gen-0.2:bind-event-type-matcher
  rdf:type sml:BindBySelect ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# event type matcher not bound
ASK 
WHERE {
    FILTER(! bound(?eventTypeMatcher))
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "eventTypeMatcher"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "event type matcher not bound"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:construct-questions-from-templates ;
  sml:selectQuery [
      rdf:type sp:Select ;
      sp:limit "1"^^xsd:long ;
      sp:resultVariables (
          [
            sp:varName "eventTypeMatcher"^^xsd:string ;
          ]
        ) ;
      sp:text """# bind matcher for event type enhancement
SELECT ?eventTypeMatcher
WHERE {
#      BIND(COALESCE(iri(?eventType), \"uniset-event-enhancement\") as ?eventTypeMatcher) 

         BIND(iri(?eventType) as  ?eventTypeIri) 
         OPTIONAL {
               ?qt form:is-relevant-if ?eventTypeIri . 
         }
         BIND((bound(?qt) && bound(?eventType)) as ?hasSpecificEventMapping)         
         BIND(IF(?hasSpecificEventMapping, ?eventTypeIri, \"uniset-event-enhancement\") as ?eventTypeMatcher) 
} LIMIT 1"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:iri ;
                sp:arg1 [
                    sp:varName "eventType"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "eventTypeIri"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "eventTypeIri"^^xsd:string ;
                    ] ;
                  sp:predicate form:is-relevant-if ;
                  sp:subject [
                      sp:varName "qt"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:and ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "qt"^^xsd:string ;
                      ] ;
                  ] ;
                sp:arg2 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "eventType"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "hasSpecificEventMapping"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:if ;
                sp:arg1 [
                    sp:varName "hasSpecificEventMapping"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "eventTypeIri"^^xsd:string ;
                  ] ;
                sp:arg3 "uniset-event-enhancement" ;
              ] ;
            sp:variable [
                sp:varName "eventTypeMatcher"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "bind matcher for event type enhancement"^^xsd:string ;
    ] ;
  rdfs:label "bind-event-type-matcher"^^xsd:string ;
.
form-ecc-gen-0.2:bind-execution-id
  rdf:type sml:BindBySelect ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# input parameter \"isIdempotent\" is invalid ({?isIdempotent})
ASK {
  FILTER (
       bound(?isIdempotent)  
       &&  (str(?isIdempotent) != \"true\") 
       && (str(?isIdempotent) != \"false\")
  )
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:and ;
                sp:arg1 [
                    rdf:type sp:and ;
                    sp:arg1 [
                        rdf:type sp:bound ;
                        sp:arg1 [
                            sp:varName "isIdempotent"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 [
                        rdf:type sp:ne ;
                        sp:arg1 [
                            rdf:type sp:str ;
                            sp:arg1 [
                                sp:varName "isIdempotent"^^xsd:string ;
                              ] ;
                          ] ;
                        sp:arg2 "true" ;
                      ] ;
                  ] ;
                sp:arg2 [
                    rdf:type sp:ne ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "isIdempotent"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "false" ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "input parameter \"isIdempotent\" is invalid ({?isIdempotent})"^^xsd:string ;
    ] ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# input parameter reportKey is not bound
ASK {
  FILTER (
       ! bound(?reportKey)  
  )
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "reportKey"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "input parameter reportKey is not bound"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# input parameter executionId is not bound
ASK {
  FILTER (
       ! bound(?executionId)  
  )
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "executionId"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "input parameter executionId is not bound"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:construct-data-questions ;
  sm:nodeX 4206 ;
  sm:nodeY 595 ;
  sml:selectQuery [
      rdf:type sp:Select ;
      sp:resultVariables (
          [
            sp:varName "executionId"^^xsd:string ;
          ]
        ) ;
      sp:text """SELECT ?executionId {
# default value
  BIND(str(COALESCE(?isIdempotent, true)) as ?isIdempotentStr) 
# bind event
  BIND(COALESCE(str(?event), \"\") as ?eventStr)
  BIND(IF( ?isIdempotentStr = \"false\", STRUUID(), md5(concat(str(?reportKey), ?eventStr))) as ?executionId)   
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:str ;
                sp:arg1 [
                    rdf:type sp:coalesce ;
                    sp:arg1 [
                        sp:varName "isIdempotent"^^xsd:string ;
                      ] ;
                    sp:arg2 "true"^^xsd:boolean ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "isIdempotentStr"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:coalesce ;
                sp:arg1 [
                    rdf:type sp:str ;
                    sp:arg1 [
                        sp:varName "event"^^xsd:string ;
                      ] ;
                  ] ;
                sp:arg2 "" ;
              ] ;
            sp:variable [
                sp:varName "eventStr"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:if ;
                sp:arg1 [
                    rdf:type sp:eq ;
                    sp:arg1 [
                        sp:varName "isIdempotentStr"^^xsd:string ;
                      ] ;
                    sp:arg2 "false" ;
                  ] ;
                sp:arg2 [
                    rdf:type sp:struuid ;
                  ] ;
                sp:arg3 [
                    rdf:type sp:md5 ;
                    sp:arg1 [
                        rdf:type sp:concat ;
                        sp:arg1 [
                            rdf:type sp:str ;
                            sp:arg1 [
                                sp:varName "reportKey"^^xsd:string ;
                              ] ;
                          ] ;
                        sp:arg2 [
                            sp:varName "eventStr"^^xsd:string ;
                          ] ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "executionId"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  rdfs:label "bind-execution-id"^^xsd:string ;
.
form-ecc-gen-0.2:bind-existence-of-imported-report
  rdf:type sml:BindBySelect ;
  sm:next form-ecc-gen-0.2:filter-for-qa-construction ;
  sm:nodeX 3418 ;
  sm:nodeY 442 ;
  sml:selectQuery [
      rdf:type sp:Select ;
      sp:limit "1"^^xsd:long ;
      sp:resultVariables (
          [
            sp:varName "importedReportExists"^^xsd:string ;
          ]
        ) ;
      sp:text """SELECT ?importedReportExists
WHERE {
   ?q a  e-m:instance  .
   BIND(\"true\"^^xsd:boolean as ?importedReportExists)
} LIMIT 1"""^^xsd:string ;
      sp:where (
          [
            sp:object e-m:instance ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression "true"^^xsd:boolean ;
            sp:variable [
                sp:varName "importedReportExists"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  rdfs:label "bind-existence-of-imported-report"^^xsd:string ;
.
form-ecc-gen-0.2:bind-existence-of-question-answer
  rdf:type sml:BindBySelect ;
  sm:next form-ecc-gen-0.2:annotate-saved-questions ;
  sm:next form-ecc-gen-0.2:filter-out-all ;
  sml:selectQuery [
      rdf:type sp:Select ;
      sp:limit "1"^^xsd:long ;
      sp:resultVariables (
          [
            sp:varName "savedQAExists"^^xsd:string ;
          ]
        ) ;
      sp:text """SELECT ?savedQAExists
WHERE {
   ?q a  doc:question .
   BIND(\"true\"^^xsd:boolean as ?savedQAExists)
} LIMIT 1"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression "true"^^xsd:boolean ;
            sp:variable [
                sp:varName "savedQAExists"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  rdfs:label "Bind if Q&A exists" ;
.
form-ecc-gen-0.2:bind-imported-report-service-uri
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:extract-imported-report ;
  sm:outputVariable "importedReportServiceUri" ;
  sml:value [
      rdf:type kbss-spif:create-sparql-service-url ;
      sp:arg1 [
          sp:varName "repositoryUrl" ;
        ] ;
      sp:arg2 [
          sp:varName "dataGraphId" ;
        ] ;
    ] ;
  rdfs:label "Bind imported report service uri" ;
.
form-ecc-gen-0.2:bind-imported-reports-repository-uri
  rdf:type sml:BindWithConstant ;
  sm:outputVariable "importedReportsRepositoryUri" ;
  sml:value [
      rdf:type sp:concat ;
      sp:arg1 [
          sp:varName "rdf4jServerUri" ;
        ] ;
      sp:arg2 "/repositories/" ;
      sp:arg3 "reports-refactoring" ;
    ] ;
  rdfs:label "Bind imported reports repository uri" ;
.
form-ecc-gen-0.2:bind-operational-full-service-uri
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:attach-eccairs-views ;
  sm:outputVariable "operationalFullServiceUri" ;
  sml:value [
      rdf:type kbss-spif:create-sparql-service-url ;
      sp:arg1 [
          sp:varName "eccairsRepositoryUri" ;
        ] ;
      sp:arg2 [
          sp:varName "operationalFullUri" ;
        ] ;
    ] ;
  rdfs:label "bind-operational-full-service-uri" ;
.
form-ecc-gen-0.2:bind-question-template-cache-uri
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:question-templates-cache-service-uri ;
  sm:outputVariable "questionTemplatesCacheUri" ;
  sml:value "http://onto.fel.cvut.cz/ontologies/forms/eccairs/question-templates" ;
  rdfs:label "Bind question templates cache uri" ;
.
form-ecc-gen-0.2:bind-record-context
  rdf:type sml:BindWithConstant ;
  sm:outputVariable "reportGraphUriStable" ;
  sml:value "http://www.inbas.cz/ontologies/reporting-tool/formGen" ;
  rdfs:label "Bind record graph" ;
.
form-ecc-gen-0.2:bind-report-key
  rdf:type sml:BindBySelect ;
  sm:next form-ecc-gen-0.2:bind-execution-id ;
  sm:nodeX 4206 ;
  sm:nodeY 456 ;
  sml:selectQuery [
      rdf:type sp:Select ;
      sp:resultVariables (
          [
            sp:varName "reportKey"^^xsd:string ;
          ]
        ) ;
      sp:text """SELECT ?reportKey
WHERE {
     ?report a doc:report .
    ?report doc:has_key ?reportKey .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:report ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "report"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "reportKey"^^xsd:string ;
              ] ;
            sp:predicate doc:has_key ;
            sp:subject [
                sp:varName "report"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  rdfs:label "bind-report-key"^^xsd:string ;
.
form-ecc-gen-0.2:bind-reports-repository
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:bind-record-context ;
  sm:outputVariable "reportsRepositoryUri" ;
  sml:value [
      rdf:type sp:concat ;
      sp:arg1 [
          sp:varName "rdf4jServerUri" ;
        ] ;
      sp:arg2 "/repositories/" ;
      sp:arg3 "form-generator" ;
    ] ;
  rdfs:label "Bind reports repository" ;
.
form-ecc-gen-0.2:bind-root-entity
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:construct-imported-questions-origins ;
  sm:outputVariable "rootEntity"^^xsd:string ;
  sml:value e-a-3.4.0.2:e-24 ;
  rdfs:label "bind-root-entity"^^xsd:string ;
.
form-ecc-gen-0.2:bind-sample-report-service-uri
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:extract-example-report ;
  sm:outputVariable "sampleReportServiceUri" ;
  sml:value [
      rdf:type kbss-spif:create-sparql-service-url ;
      sp:arg1 [
          sp:varName "sampleReportsRepositoryUri" ;
        ] ;
      sp:arg2 [
          sp:varName "sampleReportUri" ;
        ] ;
    ] ;
  rdfs:comment " " ;
  rdfs:label "Bind sample report service uri" ;
.
form-ecc-gen-0.2:bind-sample-reports-repository
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:bind-sample-report-service-uri ;
  sm:outputVariable "sampleReportsRepositoryUri" ;
  sml:value [
      rdf:type sp:concat ;
      sp:arg1 [
          sp:varName "rdf4jServerUri" ;
        ] ;
      sp:arg2 "/repositories/" ;
      sp:arg3 "reports-refactoring" ;
    ] ;
  rdfs:label "Bind sample reports repository" ;
.
form-ecc-gen-0.2:bind-schema-mapping-uri
  rdf:type sml:BindWithConstant ;
  sm:outputVariable "schemaMappingUri" ;
  sml:value "http://onto.fel.cvut.cz/ontologies/eccairs/mapping/aerodrome" ;
  rdfs:label "Bind schema mapping uri" ;
.
form-ecc-gen-0.2:construct-answer-origins
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:construct-answers ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object form:answer-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "valueObject"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
    ?valueObject a form:answer-origin .
}
WHERE {
# precondition -- questions where not saved yet
    FILTER(! bound(?savedQAExists))

    ?qOrigin a form:question-origin .

# find concrete data
     ?qOrigin rdf:object ?i .

# retrieve answer value
    ?i a e-m:instance .
    ?i e-m:has-value ?valueObject .
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "savedQAExists"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "qOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "i"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "qOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m:instance ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "i"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "valueObject"^^xsd:string ;
              ] ;
            sp:predicate e-m:has-value ;
            sp:subject [
                sp:varName "i"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "construct-answer-origins"^^xsd:string ;
.
form-ecc-gen-0.2:construct-answers
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is an answer origin not connected to any question
ASK 
WHERE {
    ?ao a form:answer-origin .
    FILTER NOT EXISTS {
        ?q doc:has_answer ?a .
        ?a form:has-answer-origin ?ao .
    }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:answer-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "ao"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "a"^^xsd:string ;
                        ] ;
                      sp:predicate doc:has_answer ;
                      sp:subject [
                          sp:varName "q"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object [
                          sp:varName "ao"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-answer-origin ;
                      sp:subject [
                          sp:varName "a"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is an answer origin not connected to any question"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is an answer to a question that has two data value
ASK 
WHERE {
    ?a a doc:answer .
    ?a doc:has_data_value ?dataValue1 .
    ?a doc:has_data_value ?dataValue2 .
    FILTER(?dataValue1 != ?dataValue2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:answer ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "dataValue1"^^xsd:string ;
              ] ;
            sp:predicate doc:has_data_value ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "dataValue2"^^xsd:string ;
              ] ;
            sp:predicate doc:has_data_value ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "dataValue1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "dataValue2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is an answer to a question that has two data value"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is an answer to a question that has two data value
ASK 
WHERE {
    ?a a doc:answer .
    ?a doc:has_object_value ?objectValue1 .
    ?a doc:has_object_value ?objectValue2 .
    FILTER(?objectValue1 != ?objectValue2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:answer ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "objectValue1"^^xsd:string ;
              ] ;
            sp:predicate doc:has_object_value ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "objectValue2"^^xsd:string ;
              ] ;
            sp:predicate doc:has_object_value ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "objectValue1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "objectValue2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is an answer to a question that has two data value"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:form-generator-xxx ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "codeValue"^^xsd:string ;
              ] ;
            sp:predicate doc:has_object_value ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "codeObject"^^xsd:string ;
              ] ;
            sp:predicate form:has-answer-origin ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 0 -  populate code value answers
CONSTRUCT {
   ?a doc:has_object_value ?codeValue .
   ?a form:has-answer-origin ?codeObject .
}
WHERE {
# precondition -- questions where not saved yet
    FILTER(! bound(?savedQAExists))

# match question, answer instance
    ?a a doc:answer .
    ?q doc:has_answer ?a ;
         form:has-question-origin ?qOrigin .

# find concrete data
     ?qOrigin rdf:object ?i .

# retrieve answer value
    ?i a e-m:instance .
    ?i e-m:has-value ?codeObject .
    ?codeObject e-m:has-code-value ?codeValue .

# attach metadata # TODO maybe elsewhere
    SERVICE ?eccairsSchemaServiceUri {    
          ?codeValue rdfs:label ?codeLabel .
          OPTIONAL {  
              ?codeValue e-m:has-explanation ?codeComment .
         }  
    }
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "savedQAExists"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
          [
            sp:object doc:answer ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "a"^^xsd:string ;
              ] ;
            sp:predicate doc:has_answer ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "i"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "qOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m:instance ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "i"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "codeObject"^^xsd:string ;
              ] ;
            sp:predicate e-m:has-value ;
            sp:subject [
                sp:varName "i"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "codeValue"^^xsd:string ;
              ] ;
            sp:predicate e-m:has-code-value ;
            sp:subject [
                sp:varName "codeObject"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "codeLabel"^^xsd:string ;
                    ] ;
                  sp:predicate rdfs:label ;
                  sp:subject [
                      sp:varName "codeValue"^^xsd:string ;
                    ] ;
                ]
                [
                  rdf:type sp:Optional ;
                  sp:elements (
                      [
                        sp:object [
                            sp:varName "codeComment"^^xsd:string ;
                          ] ;
                        sp:predicate e-m:has-explanation ;
                        sp:subject [
                            sp:varName "codeValue"^^xsd:string ;
                          ] ;
                      ]
                    ) ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "eccairsSchemaServiceUri"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 -  populate code value answers"^^xsd:string ;
    ] ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "textValue"^^xsd:string ;
              ] ;
            sp:predicate doc:has_data_value ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "textObject"^^xsd:string ;
              ] ;
            sp:predicate form:has-answer-origin ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 1 -  populate text value answers 
CONSTRUCT {
   ?a doc:has_data_value ?textValue .  
   ?a form:has-answer-origin ?textObject . 
}
WHERE {
# precondition -- questions where not saved yet
    FILTER(! bound(?savedQAExists))

# match question, answer instance
    ?a a doc:answer .
    ?q doc:has_answer ?a ;
         form:has-question-origin ?qOrigin .

# find concrete data
     ?qOrigin rdf:object ?i .

# retrieve answer value
    ?i a e-m:instance .
    ?i e-m:has-value ?textObject .
    ?textObject  e-m:has-text-value ?textValue .
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "savedQAExists"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
          [
            sp:object doc:answer ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "a"^^xsd:string ;
              ] ;
            sp:predicate doc:has_answer ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "i"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "qOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m:instance ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "i"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "textObject"^^xsd:string ;
              ] ;
            sp:predicate e-m:has-value ;
            sp:subject [
                sp:varName "i"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "textValue"^^xsd:string ;
              ] ;
            sp:predicate e-m:has-text-value ;
            sp:subject [
                sp:varName "textObject"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 -  populate text value answers"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "populate answers"^^xsd:string ;
.
form-ecc-gen-0.2:construct-data-questions
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:recover-question-template ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "imported-questions" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
     ?q a doc:question ;
          form:has-question-origin ?qOrigin ;    
          form:is-relevant-if \"imported-questions\" .   
}
WHERE {
# apply only if there are no saved questions
    FILTER(?savedQAExists = false)    
    
    ?qOrigin a form:question-origin .
    BIND(form-ecc-lib:create-q(concat(str(?qOrigin), \"-\", ?executionId)) as ?q)
# TODO ---- execution ID ?
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:eq ;
                sp:arg1 [
                    sp:varName "savedQAExists"^^xsd:string ;
                  ] ;
                sp:arg2 "false"^^xsd:boolean ;
              ] ;
          ]
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "qOrigin"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-q ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "qOrigin"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "-" ;
                    sp:arg3 [
                        sp:varName "executionId"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  rdfs:label "Construct imported questions"^^xsd:string ;
.
form-ecc-gen-0.2:construct-imported-questions-origins
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 0 - ?rootEntity is not bound
ASK
WHERE {
    FILTER(! bound(?rootEntity))    
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "rootEntity"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - ?rootEntity is not bound"^^xsd:string ;
    ] ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 1 - there is no root e-m:instance of type ?rootEntity
ASK
WHERE {
    ?i a e-m:instance .
    FILTER NOT EXISTS {
          ?root_i a e-m:instance .
          ?root_i a ?rootEntity .            
   }   
}"""^^xsd:string ;
      sp:where (
          [
            sp:object e-m:instance ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "i"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object e-m:instance ;
                      sp:predicate rdf:type ;
                      sp:subject [
                          sp:varName "root_i"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object [
                          sp:varName "rootEntity"^^xsd:string ;
                        ] ;
                      sp:predicate rdf:type ;
                      sp:subject [
                          sp:varName "root_i"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - there is no root e-m:instance of type ?rootEntity"^^xsd:string ;
    ] ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 2 - there is more than one root e-m:instance of type ?rootEntity
ASK
WHERE {
    ?root_i1 a ?rootEntity ;
                a e-m:instance .
    ?root_i1 a ?rootEntity ;
                a e-m:instance .
     FILTER(?root_i1 != ?root_i2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "rootEntity"^^xsd:string ;
              ] ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "root_i1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m:instance ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "root_i1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "rootEntity"^^xsd:string ;
              ] ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "root_i1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m:instance ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "root_i1"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "root_i1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "root_i2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "2 - there is more than one root e-m:instance of type ?rootEntity"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 0 - there is some eccairs attribute or entity not associated with question origin
ASK
WHERE {
    ?o e-m:has-child-instance|^e-m:has-child-instance ?connectedObject .
    FILTER NOT EXISTS {
          ?questionOrigin a form:question-origin ;
                rdf:object ?o .
    }
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:TriplePath ;
            sp:object [
                sp:varName "connectedObject"^^xsd:string ;
              ] ;
            sp:path [
                rdf:type sp:AltPath ;
                sp:path1 e-m:has-child-instance ;
                sp:path2 [
                    rdf:type sp:ReversePath ;
                    sp:subPath e-m:has-child-instance ;
                  ] ;
              ] ;
            sp:subject [
                sp:varName "o"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object form:question-origin ;
                      sp:predicate rdf:type ;
                      sp:subject [
                          sp:varName "questionOrigin"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object [
                          sp:varName "o"^^xsd:string ;
                        ] ;
                      sp:predicate rdf:object ;
                      sp:subject [
                          sp:varName "questionOrigin"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - there is some eccairs attribute or entity not associated with question origin"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 1 - there is a question origin refering to multiple subjects of a relation
ASK
WHERE {
    ?questionOrigin a form:question-origin ;
                                 rdf:subject ?s1 ;
                                 rdf:subject ?s2 .
    FILTER(?s1 != ?s2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "questionOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "s1"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "questionOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "s2"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "questionOrigin"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "s1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "s2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - there is a question origin refering to multiple subjects of a relation"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """#2 - there is a question origin refering to multiple objects of a relation
ASK
WHERE {
    ?questionOrigin a form:question-origin ;
                                 rdf:object ?o1 ;
                                 rdf:object ?o2 .
    FILTER(?o1 != ?o2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "questionOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "o1"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "questionOrigin"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "o2"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "questionOrigin"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "o1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "o2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "2 - there is a question origin refering to multiple objects of a relation"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:construct-answer-origins ;
  sm:next form-ecc-gen-0.2:relate-question-origin-to-template ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "r_so"^^xsd:string ;
              ] ;
          ]
          [
            sp:object rdf:Statement ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "r_so"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "s"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_so"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m:has-child-instance ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_so"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_so"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "o_type"^^xsd:string ;
              ] ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "o"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 0 - create imported question origins
CONSTRUCT {
    ?r_so a form:question-origin ;
              a rdf:Statement ;
              rdf:subject ?s ;
              rdf:predicate e-m:has-child-instance ;
              rdf:object ?o .
    ?o a ?o_type .
}
WHERE {
# origins are accessible from form root
    ?rootO a ?rootEntity ;
                e-m:has-child-instance* ?o .

    ?o a e-m:instance .   
    OPTIONAL { 
       ?s e-m:has-child-instance ?o .
    }
# add type
    ?o a ?o_type .
    FILTER(?o_type != e-m:instance)

    BIND(COALESCE(concat(\"-\", md5(str(?s))),\"\")  as ?subjectHash)
    BIND(form-ecc-lib:create-qo(concat(str(?o), ?subjectHash)) as ?r_so) .

# label for debugging
    BIND(?s as ?boundS)
    OPTIONAL {           
           ?boundS rdfs:label ?sLabel  .
     }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "rootEntity"^^xsd:string ;
              ] ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "rootO"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:TriplePath ;
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:path [
                rdf:type sp:ModPath ;
                sp:modMax -2 ;
                sp:modMin 0 ;
                sp:subPath e-m:has-child-instance ;
              ] ;
            sp:subject [
                sp:varName "rootO"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m:instance ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "o"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "o"^^xsd:string ;
                    ] ;
                  sp:predicate e-m:has-child-instance ;
                  sp:subject [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            sp:object [
                sp:varName "o_type"^^xsd:string ;
              ] ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "o"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "o_type"^^xsd:string ;
                  ] ;
                sp:arg2 e-m:instance ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:coalesce ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 "-" ;
                    sp:arg2 [
                        rdf:type sp:md5 ;
                        sp:arg1 [
                            rdf:type sp:str ;
                            sp:arg1 [
                                sp:varName "s"^^xsd:string ;
                              ] ;
                          ] ;
                      ] ;
                  ] ;
                sp:arg2 "" ;
              ] ;
            sp:variable [
                sp:varName "subjectHash"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-qo ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "o"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 [
                        sp:varName "subjectHash"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "r_so"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                sp:varName "s"^^xsd:string ;
              ] ;
            sp:variable [
                sp:varName "boundS"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "sLabel"^^xsd:string ;
                    ] ;
                  sp:predicate rdfs:label ;
                  sp:subject [
                      sp:varName "boundS"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
        ) ;
      rdfs:comment "0 - create imported question origins"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "Construct question origins"^^xsd:string ;
.
form-ecc-gen-0.2:construct-initial-question-from-templates
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# ?rootEntity is not bound
ASK
WHERE {
    FILTER(! bound(?rootEntity))    
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "rootEntity"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "?rootEntity is not bound"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question without specified question origin
ASK WHERE {
    ?question a doc:question .
    FILTER NOT EXISTS {
        ?question form:has-question-origin ?origin .
    } .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "question"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "origin"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-question-origin ;
                      sp:subject [
                          sp:varName "question"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question without specified question origin"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question without specified question template
ASK WHERE {
    ?question a doc:question .
    FILTER NOT EXISTS {
        ?question form:has-template ?questionTemplate .
    } .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "question"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "questionTemplate"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-template ;
                      sp:subject [
                          sp:varName "question"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question without specified question template"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:attach-imported-questions ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "rootQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "rootEntity"^^xsd:string ;
              ] ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "rootQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "rootOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "rootQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "rootQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "rootQ"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 0 - construct ROOT question if not present 
CONSTRUCT {
    ?rootQ a doc:question ;
          form:has-origin-type ?rootEntity ;
          form:has-question-origin ?rootOrigin ;
          form:has-template ?rootQT .            
} WHERE {    
    ?rootQT form:has-template-origin  ?rootEntity .
# do nothing if having root question
    FILTER NOT EXISTS {
            ?rootQNotBound form:has-template ?rootQT .
     }    
# assign new root question based on imported data
    OPTIONAL {
          ?importedOrigin form-ecc-gen-0.2:is-origin-of-question-template ?rootQT .   
    }
   BIND(form-ecc-lib:create-q(concat(str(?importedOrigin))) as ?importedRootQ)

#assign new root question based on root template
  BIND(form-ecc-lib:create-q(concat(str(?rootQT),\"-\", ?executionId)) as ?newRootQ)

# bind new variables   
    BIND(COALESCE(?importedRootQ, ?newRootQ) as ?rootQ)
    BIND(COALESCE(?importedOrigin, ?rootQT) as ?rootOrigin)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "rootEntity"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "rootQT"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "rootQT"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-template ;
                      sp:subject [
                          sp:varName "rootQNotBound"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "rootQT"^^xsd:string ;
                    ] ;
                  sp:predicate form-ecc-gen-0.2:is-origin-of-question-template ;
                  sp:subject [
                      sp:varName "importedOrigin"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-q ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "importedOrigin"^^xsd:string ;
                          ] ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "importedRootQ"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-q ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "rootQT"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "-" ;
                    sp:arg3 [
                        sp:varName "executionId"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "newRootQ"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:coalesce ;
                sp:arg1 [
                    sp:varName "importedRootQ"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "newRootQ"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "rootQ"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:coalesce ;
                sp:arg1 [
                    sp:varName "importedOrigin"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "rootQT"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "rootOrigin"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - construct ROOT question if not present"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "attach initial question"^^xsd:string ;
.
form-ecc-gen-0.2:construct-question-templates
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there exists eccairs entity that does not have reification of its has-child relationship
ASK WHERE {
     SERVICE ?eccairsSchemaServiceUri {      
         ?s a e-m:entity .   
         ?s e-m:has-child ?o .
         OPTIONAL {
             ?reification rdf:subject ?s ;
                  rdf:predicate e-m:has-child ;
                  rdf:object ?o .
         } 
         FILTER(!bound(?reification))                             
     }
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object e-m:entity ;
                  sp:predicate rdf:type ;
                  sp:subject [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "o"^^xsd:string ;
                    ] ;
                  sp:predicate e-m:has-child ;
                  sp:subject [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                ]
                [
                  rdf:type sp:Optional ;
                  sp:elements (
                      [
                        sp:object [
                            sp:varName "s"^^xsd:string ;
                          ] ;
                        sp:predicate rdf:subject ;
                        sp:subject [
                            sp:varName "reification"^^xsd:string ;
                          ] ;
                      ]
                      [
                        sp:object e-m:has-child ;
                        sp:predicate rdf:predicate ;
                        sp:subject [
                            sp:varName "reification"^^xsd:string ;
                          ] ;
                      ]
                      [
                        sp:object [
                            sp:varName "o"^^xsd:string ;
                          ] ;
                        sp:predicate rdf:object ;
                        sp:subject [
                            sp:varName "reification"^^xsd:string ;
                          ] ;
                      ]
                    ) ;
                ]
                [
                  rdf:type sp:Filter ;
                  sp:expression [
                      rdf:type sp:not ;
                      sp:arg1 [
                          rdf:type sp:bound ;
                          sp:arg1 [
                              sp:varName "reification"^^xsd:string ;
                            ] ;
                        ] ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "eccairsSchemaServiceUri"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "there exists eccairs entity that does not have reification of its has-child relationship"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:attach-eccairs-views ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "o_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 0 - create root question templates
CONSTRUCT {
    ?r_qt_relation 
               rdf:predicate form:has-subtemplate ;
               rdf:object ?o_qt ;
}
WHERE {
    SERVICE ?eccairsSchemaServiceUri {      
         ?o a e-m:entity .   
         FILTER NOT EXISTS {
             ?notBoundParent e-m:has-child ?o .
         }
    }
    BIND(iri(concat(str(?o), \"-qts-relation\")) as  ?r_qt_relation)
    BIND(form-ecc-lib:create-qt(?o) as ?o_qt) 
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object e-m:entity ;
                  sp:predicate rdf:type ;
                  sp:subject [
                      sp:varName "o"^^xsd:string ;
                    ] ;
                ]
                [
                  rdf:type sp:Filter ;
                  sp:expression [
                      rdf:type sp:notExists ;
                      sp:elements (
                          [
                            sp:object [
                                sp:varName "o"^^xsd:string ;
                              ] ;
                            sp:predicate e-m:has-child ;
                            sp:subject [
                                sp:varName "notBoundParent"^^xsd:string ;
                              ] ;
                          ]
                        ) ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "eccairsSchemaServiceUri"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:iri ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "o"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "-qts-relation" ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-qt ;
                sp:arg1 [
                    sp:varName "o"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "o_qt"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - create root question templates"^^xsd:string ;
    ] ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "s_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "s_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "o_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "isLinkStr"^^xsd:string ;
              ] ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 1 - create structure of question templates
CONSTRUCT {
    ?s_qt form:has-subtemplate ?o_qt .
    ?r_qt_relation rdf:subject ?s_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?o_qt ;
               form:is-relevant-if  ?isLinkStr .
}
WHERE {
    SERVICE ?eccairsSchemaServiceUri {      
         ?s a e-m:entity .   
         ?s e-m:has-child ?o .
         ?reification rdf:subject ?s ;
                  rdf:predicate e-m:has-child ;
                  rdf:object ?o .
         OPTIONAL {
                  ?reification e-m:is-link ?isLinkFlag .
         }                                  
    }
    BIND(IF(?isLinkFlag = \"1\", \"is-link\", ?notBoundVariable) as ?isLinkStr)
    BIND(iri(concat(str(?reification), \"-qts-relation\")) as  ?r_qt_relation)
    BIND(form-ecc-lib:create-qt(?s) as ?s_qt)
    BIND(form-ecc-lib:create-qt(?o) as ?o_qt) 
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object e-m:entity ;
                  sp:predicate rdf:type ;
                  sp:subject [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "o"^^xsd:string ;
                    ] ;
                  sp:predicate e-m:has-child ;
                  sp:subject [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                  sp:predicate rdf:subject ;
                  sp:subject [
                      sp:varName "reification"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object e-m:has-child ;
                  sp:predicate rdf:predicate ;
                  sp:subject [
                      sp:varName "reification"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "o"^^xsd:string ;
                    ] ;
                  sp:predicate rdf:object ;
                  sp:subject [
                      sp:varName "reification"^^xsd:string ;
                    ] ;
                ]
                [
                  rdf:type sp:Optional ;
                  sp:elements (
                      [
                        sp:object [
                            sp:varName "isLinkFlag"^^xsd:string ;
                          ] ;
                        sp:predicate e-m:is-link ;
                        sp:subject [
                            sp:varName "reification"^^xsd:string ;
                          ] ;
                      ]
                    ) ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "eccairsSchemaServiceUri"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:if ;
                sp:arg1 [
                    rdf:type sp:eq ;
                    sp:arg1 [
                        sp:varName "isLinkFlag"^^xsd:string ;
                      ] ;
                    sp:arg2 "1" ;
                  ] ;
                sp:arg2 "is-link" ;
                sp:arg3 [
                    sp:varName "notBoundVariable"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "isLinkStr"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:iri ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "reification"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "-qts-relation" ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "r_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-qt ;
                sp:arg1 [
                    sp:varName "s"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "s_qt"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-qt ;
                sp:arg1 [
                    sp:varName "o"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "o_qt"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - create structure of question templates"^^xsd:string ;
    ] ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "type"^^xsd:string ;
              ] ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "s"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "s"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "s_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "type"^^xsd:string ;
              ] ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "s_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:question-template ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "s_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "sLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "s_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "sDescription"^^xsd:string ;
              ] ;
            sp:predicate rdfs:comment ;
            sp:subject [
                sp:varName "s_qt"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 2 -  attach info to each question template
CONSTRUCT {
    ?s a ?type .
    ?s_qt form:has-template-origin ?s .
    ?s_qt form:has-origin-type ?type .
    ?s_qt a form:question-template .
    ?s_qt rdfs:label ?sLabel .
    ?s_qt rdfs:comment ?sDescription .
}
WHERE {
      SERVICE  ?eccairsSchemaServiceUri {     
          ?s a ?type .
          ?s rdfs:label ?sLabel .
          ?s e-m:has-explanation ?sDescription .
          FILTER(?type in (e-m:entity, e-m:attribute))
      }
      BIND(form-ecc-lib:create-qt(?s) as ?s_qt)
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "type"^^xsd:string ;
                    ] ;
                  sp:predicate rdf:type ;
                  sp:subject [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "sLabel"^^xsd:string ;
                    ] ;
                  sp:predicate rdfs:label ;
                  sp:subject [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "sDescription"^^xsd:string ;
                    ] ;
                  sp:predicate e-m:has-explanation ;
                  sp:subject [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                ]
                [
                  rdf:type sp:Filter ;
                  sp:expression [
                      rdf:type sp:in ;
                      sp:arg1 [
                          sp:varName "type"^^xsd:string ;
                        ] ;
                      sp:arg2 e-m:entity ;
                      sp:arg3 e-m:attribute ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "eccairsSchemaServiceUri"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-qt ;
                sp:arg1 [
                    sp:varName "s"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "s_qt"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "2 -  attach info to each question template"^^xsd:string ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "Construct simple question templates" ;
.
form-ecc-gen-0.2:construct-questions-from-templates
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-max-iteration-count "10"^^xsd:string ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# question for a question template matched by eventTypeMatcher not found 
ASK
WHERE {
    ?childQT form:is-relevant-if ?eventTypeMatcher .
    FILTER NOT EXISTS {
         ?q form:has-template ?childQT .
    }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "eventTypeMatcher"^^xsd:string ;
              ] ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "childQT"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "childQT"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-template ;
                      sp:subject [
                          sp:varName "q"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "question for a question template matched by eventTypeMatcher not found"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question with two parent questions w.r.t. has_related_question relation
ASK
WHERE {
    ?parentQ1 doc:has_related_question ?childQ .
    ?parentQ2 doc:has_related_question ?childQ .
    FILTER(?parentQ1 != ?parentQ2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "childQ"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childQ"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ2"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "parentQ1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "parentQ2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question with two parent questions w.r.t. has_related_question relation"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:attach-event-type-question-links ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childEntity"^^xsd:string ;
              ] ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "event-enhancement" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "eventTypeMatcher"^^xsd:string ;
              ] ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childQ"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childLabel"^^xsd:string ;
              ] ;
            sp:predicate skos:altLabel ;
            sp:subject [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 0 - construct next level of questions based on event type
CONSTRUCT {
# TODO (management issues) -- caching should be rather automatic and thus input must be \"filter irrelevant questions\"  instead
       ?childQ a doc:question ;
           form:has-origin-type ?childEntity ;
           form:has-question-origin ?childOrigin ;
           form:has-template ?childQT ;   
           form:is-relevant-if \"event-enhancement\" ;
           form:is-relevant-if ?eventTypeMatcher .
       ?parentQ doc:has_related_question ?childQ .
# only for debugging
       ?childQ skos:altLabel ?childLabel .        
}
WHERE {
# bind templates that are relevant to eventType
    ?childQT form:is-relevant-if ?eventTypeMatcher .

# find parent question to attach to 
    ?parentQ a doc:question ;
          form:has-template ?parentQT .  
    ?parentQT  form:has-subtemplate ?childQT .
    ?childQT form:has-template-origin ?childEntity .

# attach only if parentQ is not link
    ?parentQTRelation rdf:object ?parentQT .
    { 
         ?grantParentQ doc:has_related_question ?parentQ ;
                                   form:has-template ?grandParentQT . 
         ?parentQTRelation rdf:subject ?grandParentQT . 
         FILTER NOT EXISTS {
            ?parentQTRelation form:is-relevant-if \"is-link\" . 
         }
    } UNION {
         FILTER NOT EXISTS {
            ?grantParentQ doc:has_related_question ?parentQ . 
         }
    }

# bind new question
    BIND(md5(concat(str(?parentQ), str(?childQT), ?executionId)) as ?childId)
    BIND(form-ecc-lib:create-q(concat(str(?childQT),\"-\", ?childId)) as ?childQ)

# bind child origin
   BIND(form-ecc-lib:create-qo(?childQT) as ?childOrigin)   

# create only if question does not exist already
    FILTER NOT EXISTS {
         ?parentQ doc:has_related_question ?childQNotBound .
         ?childQNotBound form:has-template ?childQT .
    }  

# only for debugging
     ?childQT rdfs:label ?childLabel .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "eventTypeMatcher"^^xsd:string ;
              ] ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "childQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "parentQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parentQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "parentQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "parentQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childEntity"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "childQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parentQT"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "parentQTRelation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Union ;
            sp:elements (
                (
                  [
                    sp:object [
                        sp:varName "parentQ"^^xsd:string ;
                      ] ;
                    sp:predicate doc:has_related_question ;
                    sp:subject [
                        sp:varName "grantParentQ"^^xsd:string ;
                      ] ;
                  ]
                  [
                    sp:object [
                        sp:varName "grandParentQT"^^xsd:string ;
                      ] ;
                    sp:predicate form:has-template ;
                    sp:subject [
                        sp:varName "grantParentQ"^^xsd:string ;
                      ] ;
                  ]
                  [
                    sp:object [
                        sp:varName "grandParentQT"^^xsd:string ;
                      ] ;
                    sp:predicate rdf:subject ;
                    sp:subject [
                        sp:varName "parentQTRelation"^^xsd:string ;
                      ] ;
                  ]
                  [
                    rdf:type sp:Filter ;
                    sp:expression [
                        rdf:type sp:notExists ;
                        sp:elements (
                            [
                              sp:object "is-link" ;
                              sp:predicate form:is-relevant-if ;
                              sp:subject [
                                  sp:varName "parentQTRelation"^^xsd:string ;
                                ] ;
                            ]
                          ) ;
                      ] ;
                  ]
                )
                (
                  [
                    rdf:type sp:Filter ;
                    sp:expression [
                        rdf:type sp:notExists ;
                        sp:elements (
                            [
                              sp:object [
                                  sp:varName "parentQ"^^xsd:string ;
                                ] ;
                              sp:predicate doc:has_related_question ;
                              sp:subject [
                                  sp:varName "grantParentQ"^^xsd:string ;
                                ] ;
                            ]
                          ) ;
                      ] ;
                  ]
                )
              ) ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:md5 ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "parentQ"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "childQT"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg3 [
                        sp:varName "executionId"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "childId"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-q ;
                sp:arg1 [
                    rdf:type sp:concat ;
                    sp:arg1 [
                        rdf:type sp:str ;
                        sp:arg1 [
                            sp:varName "childQT"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 "-" ;
                    sp:arg3 [
                        sp:varName "childId"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "childQ"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-qo ;
                sp:arg1 [
                    sp:varName "childQT"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "childOrigin"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "childQNotBound"^^xsd:string ;
                        ] ;
                      sp:predicate doc:has_related_question ;
                      sp:subject [
                          sp:varName "parentQ"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object [
                          sp:varName "childQT"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-template ;
                      sp:subject [
                          sp:varName "childQNotBound"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "childLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "childQT"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - construct next level of questions based on event type"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "Attach event-type questions from templates"^^xsd:string ;
.
form-ecc-gen-0.2:construct-template-symlinks
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 0 -  there is a question-template without a label
ASK WHERE {
     ?qt a form:question-template .
     OPTIONAL {
          ?qt rdfs:label ?label .
      }
      FILTER( !bound(?label))
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:question-template ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "label"^^xsd:string ;
                    ] ;
                  sp:predicate rdfs:label ;
                  sp:subject [
                      sp:varName "qt"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "label"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 -  there is a question-template without a label"^^xsd:string ;
    ] ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there are multiple levels of sections (NOT IMPLEMENTED)
ASK WHERE {
     ?parent_section_qt form:has-subtemplate ?section_qt ;
                           form:has-origin-type e-mv:section .
     ?section_qt form:has-subtemplate ?child_qt ;
                           form:has-origin-type e-mv:section .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "parent_section_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m-v:section ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "parent_section_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m-v:section ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "section_qt"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "there are multiple levels of sections (NOT IMPLEMENTED)"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 0 - there are two sections sharing same attribute but are not implementing symlinks
ASK
# TODO -- make it not eccairs specific, make it more generic w.r.t. multiple levels of sections
WHERE {
    ?root_qt form:has-subtemplate ?section1_qt ;
                   form:has-subtemplate ?section2_qt .
    FILTER(?section1_qt != ?section2_qt)
    ?section1_qt form:has-subtemplate ?child_qt ;
                          form:has-origin-type e-mv:section .
    ?section2_qt form:has-subtemplate ?child_qt ;
                          form:has-origin-type e-mv:section .   
    ?r_1_qt_relation rdf:subject ?section1_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?child_qt .
    ?r_2_qt_relation rdf:subject ?section1_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?child_qt .
    OPTIONAL {
        ?r_1_qt_relation form:is-relevant-if ?isLink1 .
    }
    OPTIONAL {
        ?r_2_qt_relation form:is-relevant-if ?isLink2 .
    }
    FILTER(! ((?isLink1 = \"is-link\") || (?isLink2 = \"is-link\")) )
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "section1_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "root_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section2_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "root_qt"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "section1_qt"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "section2_qt"^^xsd:string ;
                  ] ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "section1_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m-v:section ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "section1_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "section2_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m-v:section ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "section2_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section1_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_1_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_1_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_1_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section1_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_2_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_2_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_2_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "isLink1"^^xsd:string ;
                    ] ;
                  sp:predicate form:is-relevant-if ;
                  sp:subject [
                      sp:varName "r_1_qt_relation"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "isLink2"^^xsd:string ;
                    ] ;
                  sp:predicate form:is-relevant-if ;
                  sp:subject [
                      sp:varName "r_2_qt_relation"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:or ;
                    sp:arg1 [
                        rdf:type sp:eq ;
                        sp:arg1 [
                            sp:varName "isLink1"^^xsd:string ;
                          ] ;
                        sp:arg2 "is-link" ;
                      ] ;
                    sp:arg2 [
                        rdf:type sp:eq ;
                        sp:arg1 [
                            sp:varName "isLink2"^^xsd:string ;
                          ] ;
                        sp:arg2 "is-link" ;
                      ] ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - there are two sections sharing same attribute but are not implementing symlinks"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 1 - there is symlink that does not have hardlink associated
ASK
WHERE {
     ?parent_qt form:has-subtemplate ?child_qt .
     ?r_symlink_qt_relation rdf:subject ?parent_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?child_qt ;
               form:is-relevant-if \"is-link\" .
      FILTER NOT EXISTS {
            ?r_symlink_qt_relation form:is-link-template-of ?r_hardlink_qt_relation .
       }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "parent_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parent_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "is-link" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "r_hardlink_qt_relation"^^xsd:string ;
                        ] ;
                      sp:predicate form:is-link-template-of ;
                      sp:subject [
                          sp:varName "r_symlink_qt_relation"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - there is symlink that does not have hardlink associated"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 2 - there is more than one hardlink for some eccairs template question relation (eccairs specific constraint)
ASK
WHERE {
    ?r_symlink_qt_relation form:is-link-template-of ?r_hardlink_qt_relation1 ;
                                           form:is-link-template-of ?r_hardlink_qt_relation2 .
    FILTER(?r_hardlink_qt_relation1 != ?r_hardlink_qt_relation2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "r_hardlink_qt_relation1"^^xsd:string ;
              ] ;
            sp:predicate form:is-link-template-of ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "r_hardlink_qt_relation2"^^xsd:string ;
              ] ;
            sp:predicate form:is-link-template-of ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "r_hardlink_qt_relation1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "r_hardlink_qt_relation2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "2 - there is more than one hardlink for some eccairs template question relation (eccairs specific constraint)"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# 3 - there is a question tempate relation that act as hardlink and symlink at the same time
ASK
WHERE {
    ?r_symlink_qt_relation form:is-link-template-of ?r_bad_qt_relation .
    ?r_bad_qt_relation form:is-link-template-of  ?r_hardlink_qt_relation.
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "r_bad_qt_relation"^^xsd:string ;
              ] ;
            sp:predicate form:is-link-template-of ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "r_hardlink_qt_relation"^^xsd:string ;
              ] ;
            sp:predicate form:is-link-template-of ;
            sp:subject [
                sp:varName "r_bad_qt_relation"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "3 - there is a question tempate relation that act as hardlink and symlink at the same time"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:extract-shape ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "r_hardlink_qt_relation"^^xsd:string ;
              ] ;
            sp:predicate form:is-link-template-of ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 0 - construct symlinks if explicitely stated
CONSTRUCT {
	?r_symlink_qt_relation form:is-link-template-of ?r_hardlink_qt_relation .
} WHERE {
     ?parent1_qt form:has-subtemplate ?child_qt .
     ?parent2_qt form:has-subtemplate ?child_qt .
     ?r_symlink_qt_relation rdf:subject ?parent1_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?child_qt ;
               form:is-relevant-if \"is-link\" .
     ?r_hardlink_qt_relation rdf:subject ?parent2_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?child_qt . 
     FILTER(?r_hardlink_qt_relation != ?r_symlink_qt_relation)
     FILTER NOT EXISTS {
              	?r_hardlink_qt_relation	  form:is-relevant-if \"is-link\" .
     }     
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "parent1_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "parent2_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parent1_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "is-link" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "parent2_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_hardlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_hardlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_hardlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "r_hardlink_qt_relation"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "r_symlink_qt_relation"^^xsd:string ;
                  ] ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object "is-link" ;
                      sp:predicate form:is-relevant-if ;
                      sp:subject [
                          sp:varName "r_hardlink_qt_relation"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - construct symlinks if explicitely stated"^^xsd:string ;
    ] ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "r_hardlink_qt_relation"^^xsd:string ;
              ] ;
            sp:predicate form:is-link-template-of ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "is-link" ;
            sp:predicate form:is-relevant-if ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 1 - construct symlinks if sections are based on same eccairs entity and its attribute
CONSTRUCT {
# TODO -- make it not eccairs specific, make it work with more than one level of sections, make it work if more than two sections share same attribute
	?r_symlink_qt_relation form:is-link-template-of ?r_hardlink_qt_relation ;
                   form:is-relevant-if \"is-link\" .
} WHERE {
# pick relation that is minimal w.r.t. ordering of labels
     ?parent_qt form:has-subtemplate ?section1_qt .
     ?section1_qt form:has-subtemplate ?child_qt ;
                           form:has-origin-type e-mv:section ;
                           rdfs:label ?section1_label .                                
     ?r_hardlink_qt_relation rdf:subject ?section1_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?child_qt . 
## section1_label must be minimal w.r.t. ordering of question template labels
     FILTER NOT EXISTS {
          ?parent_qt form:has-subtemplate ?sectionNotBound_qt ;
                             form:has-origin-type e-mv:section ;
                             rdfs:label ?sectionNotBound_label .
          ?sectionNotBound_qt form:has-subtemplate ?child_qt .
          FILTER(?sectionNotBound_qt != ?section1_qt)
          FILTER(?sectionNotBound_label < ?section1_label)
     }     

# pick any other relation 
     ?parent_qt form:has-subtemplate ?section2_qt .
     ?section2_qt form:has-subtemplate ?child_qt ;
                           form:has-origin-type e-mv:section ;
                           rdfs:label ?section2_label .    
     ?r_symlink_qt_relation rdf:subject ?section2_qt ;
               rdf:predicate form:has-subtemplate ;
               rdf:object ?child_qt .
     FILTER(?section1_qt != ?section2_qt)
     FILTER(str(?section1_label) < str(?section2_label))
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "section1_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "parent_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "section1_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m-v:section ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "section1_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section1_label"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "section1_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section1_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_hardlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_hardlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_hardlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "sectionNotBound_qt"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-subtemplate ;
                      sp:subject [
                          sp:varName "parent_qt"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object e-m-v:section ;
                      sp:predicate form:has-origin-type ;
                      sp:subject [
                          sp:varName "parent_qt"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object [
                          sp:varName "sectionNotBound_label"^^xsd:string ;
                        ] ;
                      sp:predicate rdfs:label ;
                      sp:subject [
                          sp:varName "parent_qt"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object [
                          sp:varName "child_qt"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-subtemplate ;
                      sp:subject [
                          sp:varName "sectionNotBound_qt"^^xsd:string ;
                        ] ;
                    ]
                    [
                      rdf:type sp:Filter ;
                      sp:expression [
                          rdf:type sp:ne ;
                          sp:arg1 [
                              sp:varName "sectionNotBound_qt"^^xsd:string ;
                            ] ;
                          sp:arg2 [
                              sp:varName "section1_qt"^^xsd:string ;
                            ] ;
                        ] ;
                    ]
                    [
                      rdf:type sp:Filter ;
                      sp:expression [
                          rdf:type sp:lt ;
                          sp:arg1 [
                              sp:varName "sectionNotBound_label"^^xsd:string ;
                            ] ;
                          sp:arg2 [
                              sp:varName "section1_label"^^xsd:string ;
                            ] ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section2_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "parent_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "section2_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m-v:section ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "section2_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section2_label"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "section2_qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "section2_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:subject ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:has-subtemplate ;
            sp:predicate rdf:predicate ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "child_qt"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "r_symlink_qt_relation"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "section1_qt"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "section2_qt"^^xsd:string ;
                  ] ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:lt ;
                sp:arg1 [
                    rdf:type sp:str ;
                    sp:arg1 [
                        sp:varName "section1_label"^^xsd:string ;
                      ] ;
                  ] ;
                sp:arg2 [
                    rdf:type sp:str ;
                    sp:arg1 [
                        sp:varName "section2_label"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - construct symlinks if sections are based on same eccairs entity and its attribute"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "construct-template-symlinks"^^xsd:string ;
.
form-ecc-gen-0.2:dataGraphId
  rdf:type owl:DatatypeProperty ;
  rdfs:comment "Context that contains original data from email importer that contains 2 types of data -- eccairs schema compliant and aviation ontology compliant data. Aviation ontology compliant data might be possibly reduced (moved to default graph of RT)." ;
  rdfs:label "Named graph id imported data" ;
  rdfs:range xsd:string ;
.
form-ecc-gen-0.2:deploy-question-templates
  rdf:type kbss-module:deploy ;
  km-sesame:p-is-replace "true"^^xsd:boolean ;
  km-sesame:p-sesame-context-iri "http://onto.fel.cvut.cz/ontologies/forms/eccairs/question-templates" ;
  km-sesame:p-sesame-repository-name "form-generator" ;
  km-sesame:p-sesame-server-url "http://dev.inbas.cz/rdf4j-server" ;
  rdfs:label "deploy-question-templates" ;
.
form-ecc-gen-0.2:disable-question-clones
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:filter-irrelevant ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object "true"^^xsd:boolean ;
            sp:predicate form-lt:is-disabled ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
   ?q form-lt:is-disabled true .
}
WHERE {
    ?q form:is-clone-of-question ?clonedQ .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "clonedQ"^^xsd:string ;
              ] ;
            sp:predicate form:is-clone-of-question ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "disable-question-clones"^^xsd:string ;
.
form-ecc-gen-0.2:event
  rdf:type owl:DatatypeProperty ;
  rdfs:label "Event" ;
  rdfs:range xsd:string ;
.
form-ecc-gen-0.2:eventType
  rdf:type owl:DatatypeProperty ;
  rdfs:label "Event type" ;
  rdfs:range xsd:string ;
.
form-ecc-gen-0.2:extract-concrete-report
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question with two parents
ASK
WHERE {
   ?parentQ1 doc:has_related_question ?q .
   ?parentQ2 doc:has_related_question ?q .
   FILTER(?parentQ1 != ?parentQ2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "q"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ2"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "parentQ1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "parentQ2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question with two parents"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:bind-report-key ;
  sm:next form-ecc-gen-0.2:filter-relevant-form ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o" ;
              ] ;
            sp:predicate [
                sp:varName "p" ;
              ] ;
            sp:subject [
                sp:varName "s" ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
    ?s ?p ?o .
}
WHERE {
   SERVICE ?concreteReportServiceUri {
         ?s ?p ?o .
    }
}""" ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "o" ;
                    ] ;
                  sp:predicate [
                      sp:varName "p" ;
                    ] ;
                  sp:subject [
                      sp:varName "s" ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "concreteReportServiceUri" ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "Extract concrete report" ;
.
form-ecc-gen-0.2:extract-eccairs-schema
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:ExportEccairs ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o" ;
              ] ;
            sp:predicate [
                sp:varName "p" ;
              ] ;
            sp:subject [
                sp:varName "s" ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
    ?s ?p ?o .
}
WHERE {
    SERVICE ?eccairsSchemaServiceUri {
         ?s ?p ?o .
    }
}""" ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "o" ;
                    ] ;
                  sp:predicate [
                      sp:varName "p" ;
                    ] ;
                  sp:subject [
                      sp:varName "s" ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "eccairsSchemaServiceUri" ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "Extract eccairs schema" ;
.
form-ecc-gen-0.2:extract-example-report
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:SaveExampleReport ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o" ;
              ] ;
            sp:predicate [
                sp:varName "p" ;
              ] ;
            sp:subject [
                sp:varName "s" ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
    ?s ?p ?o .
}
WHERE {
    SERVICE ?sampleReportServiceUri {
         ?s ?p ?o .
    }
}""" ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "o" ;
                    ] ;
                  sp:predicate [
                      sp:varName "p" ;
                    ] ;
                  sp:subject [
                      sp:varName "s" ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "sampleReportServiceUri" ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "Extract sample report" ;
.
form-ecc-gen-0.2:extract-imported-report
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:bind-existence-of-imported-report ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o" ;
              ] ;
            sp:predicate [
                sp:varName "p" ;
              ] ;
            sp:subject [
                sp:varName "s" ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
    ?s ?p ?o .
}
WHERE {
   SERVICE ?importedReportServiceUri {
         ?s ?p ?o .
    }
}""" ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "o" ;
                    ] ;
                  sp:predicate [
                      sp:varName "p" ;
                    ] ;
                  sp:subject [
                      sp:varName "s" ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "importedReportServiceUri" ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "Extract imported report" ;
.
form-ecc-gen-0.2:extract-shape
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:deploy-question-templates ;
  sm:next form-ecc-gen-0.2:question-template-merge ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:predicate [
                sp:varName "p"^^xsd:string ;
              ] ;
            sp:subject [
                sp:varName "s"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# TODO -- include shape
CONSTRUCT {
    ?s ?p ?o . 
}
WHERE {
    ?s ?p ?o .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:predicate [
                sp:varName "p"^^xsd:string ;
              ] ;
            sp:subject [
                sp:varName "s"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "TODO -- include shape"^^xsd:string ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "Filter template-set shape"^^xsd:string ;
.
form-ecc-gen-0.2:filter-for-qa-construction
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:construct-imported-questions-origins ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:predicate [
                sp:varName "p"^^xsd:string ;
              ] ;
            sp:subject [
                sp:varName "s"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# filter only necessary data for q&a reconstruction
CONSTRUCT {
    ?s ?p ?o .
}
WHERE {
    ?s ?p ?o .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:predicate [
                sp:varName "p"^^xsd:string ;
              ] ;
            sp:subject [
                sp:varName "s"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "filter only necessary data for q&a reconstruction"^^xsd:string ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "filter-for-qa-construction" ;
.
form-ecc-gen-0.2:filter-irrelevant
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:merge-form-data ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:predicate [
                sp:varName "p"^^xsd:string ;
              ] ;
            sp:subject [
                sp:varName "s"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
    ?s ?p ?o .
}
WHERE {
    ?s ?p ?o .
    FILTER(?p != form:has-subtemplate)  
    FILTER(?p != rdf:object)  
    FILTER(?p != rdf:subject)
    FILTER(?p != rdf:predicate)
    FILTER(?p != form:is-relevant-if)      
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:predicate [
                sp:varName "p"^^xsd:string ;
              ] ;
            sp:subject [
                sp:varName "s"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "p"^^xsd:string ;
                  ] ;
                sp:arg2 form:has-subtemplate ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "p"^^xsd:string ;
                  ] ;
                sp:arg2 rdf:object ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "p"^^xsd:string ;
                  ] ;
                sp:arg2 rdf:subject ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "p"^^xsd:string ;
                  ] ;
                sp:arg2 rdf:predicate ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "p"^^xsd:string ;
                  ] ;
                sp:arg2 form:is-relevant-if ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "Filter irrelevant" ;
.
form-ecc-gen-0.2:filter-irrelevant-templates
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a template for an attribute that is both in section and outside of it
ASK 
# TODO make it not eccairs specific
WHERE {
    ?entQT form:has-subtemplate ?attrQT ;
                 form:has-subtemplate ?secQT .
    ?secQT form:has-subtemplate ?attrQT ;
                 form:has-origin-type e-m-v:section .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "attrQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "entQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "secQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "entQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "attrQT"^^xsd:string ;
              ] ;
            sp:predicate form:has-subtemplate ;
            sp:subject [
                sp:varName "secQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object e-m-v:section ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "secQT"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a template for an attribute that is both in section and outside of it"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:construct-template-symlinks ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o" ;
              ] ;
            sp:predicate [
                sp:varName "p" ;
              ] ;
            sp:subject [
                sp:varName "s" ;
              ] ;
          ]
        ) ;
      sp:text """# TODO put ?disabledContext -> VALUES
CONSTRUCT {
   ?s ?p ?o .
} WHERE {
      ?s ?p ?o . 
      OPTIONAL {
           ?reification 
               rdf:subject ?s ;
               rdf:predicate ?p ;
               rdf:object ?o ;    
               form:is-relevant-if \"eccairs-data-schema\" .   
     }
     FILTER(! bound(?reification))
}""" ;
      sp:where (
          [
            sp:object [
                sp:varName "o" ;
              ] ;
            sp:predicate [
                sp:varName "p" ;
              ] ;
            sp:subject [
                sp:varName "s" ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "s" ;
                    ] ;
                  sp:predicate rdf:subject ;
                  sp:subject [
                      sp:varName "reification" ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "p" ;
                    ] ;
                  sp:predicate rdf:predicate ;
                  sp:subject [
                      sp:varName "reification" ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "o" ;
                    ] ;
                  sp:predicate rdf:object ;
                  sp:subject [
                      sp:varName "reification" ;
                    ] ;
                ]
                [
                  sp:object "eccairs-data-schema" ;
                  sp:predicate form:is-relevant-if ;
                  sp:subject [
                      sp:varName "reification" ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "reification" ;
                      ] ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "TODO put ?disabledContext -> VALUES" ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "Filter out irrelevant templates"^^xsd:string ;
.
form-ecc-gen-0.2:filter-out-all
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:filter-for-qa-construction ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates () ;
      sp:text """# only path to propagate variables
CONSTRUCT {
    
}
WHERE {
    
}"""^^xsd:string ;
      sp:where () ;
      rdfs:comment "only path to propagate variables"^^xsd:string ;
    ] ;
  rdfs:label "filter-out-all"^^xsd:string ;
.
form-ecc-gen-0.2:filter-populable-answers
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:construct-answers ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object doc:answer ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "a"^^xsd:string ;
              ] ;
            sp:predicate doc:has_answer ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# filter only answers that should be populated from imported questions
CONSTRUCT {    
    ?a a doc:answer .
    ?q doc:has_answer ?a ;
         form:has-question-origin ?qOrigin .
}
WHERE {
# precondition -- questions where not saved yet
    FILTER(! bound(?savedQAExists))

    ?a a doc:answer .
    ?q doc:has_answer ?a ;
         form:has-question-origin ?qOrigin .

# question is leaf node question
    FILTER NOT EXISTS {
         ?q doc:has_related_question ?childQ .
    }

# question is not a clone
    FILTER NOT EXISTS {
         ?qOrigin form-ecc-gen-0.2:is-origin-of-question-templates-reification ?qTRelation .
         ?qTRelation form:is-relevant-if \"is-link\" .
    }
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:not ;
                sp:arg1 [
                    rdf:type sp:bound ;
                    sp:arg1 [
                        sp:varName "savedQAExists"^^xsd:string ;
                      ] ;
                  ] ;
              ] ;
          ]
          [
            sp:object doc:answer ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "a"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "a"^^xsd:string ;
              ] ;
            sp:predicate doc:has_answer ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "childQ"^^xsd:string ;
                        ] ;
                      sp:predicate doc:has_related_question ;
                      sp:subject [
                          sp:varName "q"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "qTRelation"^^xsd:string ;
                        ] ;
                      sp:predicate form-ecc-gen-0.2:is-origin-of-question-templates-reification ;
                      sp:subject [
                          sp:varName "qOrigin"^^xsd:string ;
                        ] ;
                    ]
                    [
                      sp:object "is-link" ;
                      sp:predicate form:is-relevant-if ;
                      sp:subject [
                          sp:varName "qTRelation"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "filter only answers that should be populated from imported questions"^^xsd:string ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "filter-populable-answers"^^xsd:string ;
.
form-ecc-gen-0.2:filter-relevant-form
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there are two root questions
ASK
WHERE {
    ?root_q1 a doc:question .
    ?root_q2 a doc:question .
    FILTER(?root_q1 != ?root_q2)
    FILTER NOT EXISTS {
             ?notBoundq1 doc:has_related_question ?root_q1 .
    }
    FILTER NOT EXISTS {
             ?notBoundq2 doc:has_related_question ?root_q2 .
    }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "root_q1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "root_q2"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "root_q1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "root_q2"^^xsd:string ;
                  ] ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "root_q1"^^xsd:string ;
                        ] ;
                      sp:predicate doc:has_related_question ;
                      sp:subject [
                          sp:varName "notBoundq1"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "root_q2"^^xsd:string ;
                        ] ;
                      sp:predicate doc:has_related_question ;
                      sp:subject [
                          sp:varName "notBoundq2"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there are two root questions"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question with two parents
ASK
WHERE {
    ?q a doc:question .
    ?parentQ1 doc:has_related_question ?q .
    ?parentQ2 doc:has_related_question ?q .
    FILTER(?parentQ1 != ?parentQ2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ2"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "parentQ1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "parentQ2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question with two parents"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:bind-existence-of-question-answer ;
  sm:nodeX 4533 ;
  sm:nodeY 448 ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:predicate [
                sp:varName "p"^^xsd:string ;
              ] ;
            sp:subject [
                sp:varName "s"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# return only questions rooted by input eccairs event
CONSTRUCT {
    ?s ?p ?o .
}
WHERE {
    ?event doc:has_related_question ?rootQ .
    ?rootQ (doc:has_related_question*|doc:has_answer*)* ?s .
    ?s ?p ?o .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "rootQ"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "event"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:TriplePath ;
            sp:object [
                sp:varName "s"^^xsd:string ;
              ] ;
            sp:path [
                rdf:type sp:ModPath ;
                sp:modMax -2 ;
                sp:modMin 0 ;
                sp:subPath [
                    rdf:type sp:AltPath ;
                    sp:path1 [
                        rdf:type sp:ModPath ;
                        sp:modMax -2 ;
                        sp:modMin 0 ;
                        sp:subPath doc:has_related_question ;
                      ] ;
                    sp:path2 [
                        rdf:type sp:ModPath ;
                        sp:modMax -2 ;
                        sp:modMin 0 ;
                        sp:subPath doc:has_answer ;
                      ] ;
                  ] ;
              ] ;
            sp:subject [
                sp:varName "rootQ"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:predicate [
                sp:varName "p"^^xsd:string ;
              ] ;
            sp:subject [
                sp:varName "s"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "return only questions rooted by input eccairs event"^^xsd:string ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "filter relevant form [rt]"^^xsd:string ;
.
form-ecc-gen-0.2:form-generator-xxx
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there exists generated question but only loaded ones should be present
ASK 
WHERE {
     FILTER NOT EXISTS {
         ?s a doc:question .
         FILTER(contains(str(?s), \"http://onto.fel.cvut.cz/ontologies/eccairs/model/instance\"))
     }
     FILTER(bound(?qaExists))
}""" ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object doc:question ;
                      sp:predicate rdf:type ;
                      sp:subject [
                          sp:varName "s" ;
                        ] ;
                    ]
                    [
                      rdf:type sp:Filter ;
                      sp:expression [
                          rdf:type sp:contains ;
                          sp:arg1 [
                              rdf:type sp:str ;
                              sp:arg1 [
                                  sp:varName "s" ;
                                ] ;
                            ] ;
                          sp:arg2 "http://onto.fel.cvut.cz/ontologies/eccairs/model/instance" ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:bound ;
                sp:arg1 [
                    sp:varName "qaExists" ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there exists generated question but only loaded ones should be present" ;
    ] ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question with two parents
ASK
WHERE {
    ?q a doc:question .
    ?parentQ1 doc:has_related_question ?q .
    ?parentQ2 doc:has_related_question ?q .
    FILTER(?parentQ1 != ?parentQ2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ1"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "q"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "parentQ2"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "parentQ1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "parentQ2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question with two parents"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:BindRootQuestion ;
  sm:next form-ecc-gen-0.2:attach-initial-question-path ;
  sm:next form-ecc-gen-0.2:attach-possible-values-hook ;
  sm:next form-ecc-gen-0.2:filter-irrelevant ;
  sm:next form-ecc-gen-0.2:populate-question-from-template ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o" ;
              ] ;
            sp:predicate [
                sp:varName "p" ;
              ] ;
            sp:subject [
                sp:varName "s" ;
              ] ;
          ]
        ) ;
      sp:text """CONSTRUCT {
    ?s ?p ?o .    
}
WHERE {
    ?s ?p ?o .
}""" ;
      sp:where (
          [
            sp:object [
                sp:varName "o" ;
              ] ;
            sp:predicate [
                sp:varName "p" ;
              ] ;
            sp:subject [
                sp:varName "s" ;
              ] ;
          ]
        ) ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "form generator sink"^^xsd:string ;
.
form-ecc-gen-0.2:generateEccairsForms
  rdf:type sm:Function ;
  spin:constraint [
      rdf:type spl:Argument ;
      spl:defaultValue "http://dev.inbas.cz/rdf4j-server/repositories/form-generator" ;
      spl:optional "false"^^xsd:boolean ;
      spl:predicate form-ecc-gen-0.2:repositoryUrl ;
      sm:next form-ecc-gen-0.2:bind-concrete-report-service-uri ;
      sm:next form-ecc-gen-0.2:bind-imported-report-service-uri ;
      sm:next form-ecc-gen-0.2:question-templates-cache-service-uri ;
      rdfs:comment "Repository url parameter" ;
    ] ;
  spin:constraint [
      rdf:type spl:Argument ;
      spl:defaultValue "http://onto.fel.cvut.cz/ontologies/eccairs/aviation-3.4.0.2/vl-a-390/v-2180107" ;
      spl:optional "true"^^xsd:boolean ;
      spl:predicate form-ecc-gen-0.2:eventType ;
      sm:next form-ecc-gen-0.2:bind-event-type-matcher ;
      rdfs:comment "Event type." ;
    ] ;
  spin:constraint [
      rdf:type spl:Argument ;
      spl:defaultValue "http://onto.fel.cvut.cz/ontologies/ufo/Event#instance-351263038" ;
      spl:optional "true"^^xsd:boolean ;
      spl:predicate form-ecc-gen-0.2:event ;
      spl:valueType xsd:string ;
      sm:next form-ecc-gen-0.2:bind-execution-id ;
      sm:next form-ecc-gen-0.2:filter-relevant-form ;
      sm:nodeX 4477 ;
      sm:nodeY 269 ;
      rdfs:comment "Event parameter" ;
    ] ;
  spin:constraint [
      rdf:type spl:Argument ;
      spl:defaultValue "http://www.inbas.cz/ontologies/reporting-tool/formGen1471849823485" ;
      spl:optional "false"^^xsd:boolean ;
      spl:predicate form-ecc-gen-0.2:reportGraphId ;
      sm:next form-ecc-gen-0.2:bind-concrete-report-service-uri ;
      rdfs:comment "Named graph id of report parameter" ;
    ] ;
  spin:constraint [
      rdf:type spl:Argument ;
      spl:defaultValue "http://www.inbas.cz/ontologies/reporting-tool/formGen1471849823487" ;
      spl:optional "false"^^xsd:boolean ;
      spl:predicate form-ecc-gen-0.2:dataGraphId ;
      sm:next form-ecc-gen-0.2:bind-imported-report-service-uri ;
      rdfs:comment "Named graph id of imported email parameter" ;
    ] ;
  spin:constraint [
      rdf:type spl:Argument ;
      spl:predicate form-ecc-cfg-0.2:isIdempotent ;
      sm:next form-ecc-gen-0.2:bind-execution-id ;
      sm:nodeX 3774 ;
      sm:nodeY 460 ;
      rdfs:comment "If true, generation of form should be  idempotent i.e. 2 runs of the generator on the same data should results in same result."^^xsd:string ;
    ] ;
  sm:returnModule form-ecc-gen-0.2:generateEccairsForms_Return ;
  rdfs:comment "Generate forms from occurrence category." ;
  rdfs:subClassOf sm:Functions ;
.
form-ecc-gen-0.2:generateEccairsForms_Return
  rdf:type sml:ReturnRDF ;
  sml:baseURI "http://miro.example.org" ;
  sml:serialization sml:JSONLD ;
.
form-ecc-gen-0.2:has-context
  rdf:type rdf:Property ;
  rdfs:label "has-context" ;
.
form-ecc-gen-0.2:has-question-path
  rdf:type rdf:Property ;
  rdfs:label "has question path"^^xsd:string ;
.
form-ecc-gen-0.2:has-sub-question-origin
  rdf:type rdf:Property ;
  rdfs:label "has subquestion origin"^^xsd:string ;
.
form-ecc-gen-0.2:is-origin-of-question-template
  rdf:type rdf:Property ;
  rdfs:label "is-origin-of-question-template"^^xsd:string ;
.
form-ecc-gen-0.2:is-origin-of-question-templates-reification
  rdf:type rdf:Property ;
  rdfs:label "is-origin-of-question-templates-reification"^^xsd:string ;
.
form-ecc-gen-0.2:layout-form
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:merge-form-data ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object "form" ;
            sp:predicate form-lt:has-layout-class ;
            sp:subject [
                sp:varName "rootQuestion" ;
              ] ;
          ]
        ) ;
      sp:text """# 0 - create form layout question
CONSTRUCT {
    ?rootQuestion    form-lt:has-layout-class \"form\" .
}
WHERE {    

}""" ;
      sp:where () ;
      rdfs:comment "0 - create form layout question" ;
    ] ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object "section" ;
            sp:predicate form-lt:has-layout-class ;
            sp:subject [
                sp:varName "sectionQuestion" ;
              ] ;
          ]
        ) ;
      sp:text """# 1 - create section layout classes
CONSTRUCT {
    ?sectionQuestion    form-lt:has-layout-class \"section\" .
}
WHERE {    
    ?sectionQuestion doc:has_related_question ?subQuestion .
    FILTER(?rootQuestion != ?sectionQuestion)
}""" ;
      sp:where (
          [
            sp:object [
                sp:varName "subQuestion" ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "sectionQuestion" ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "rootQuestion" ;
                  ] ;
                sp:arg2 [
                    sp:varName "sectionQuestion" ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - create section layout classes" ;
    ] ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object "wizard-step" ;
            sp:predicate form-lt:has-layout-class ;
            sp:subject [
                sp:varName "topSectionQuestion"^^xsd:string ;
              ] ;
          ]
          [
            sp:object "section" ;
            sp:predicate form-lt:has-layout-class ;
            sp:subject [
                sp:varName "topSectionQuestion"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 2 - create wizard step layout for top level sections
CONSTRUCT {
    ?topSectionQuestion    form-lt:has-layout-class \"wizard-step\" .
# TODO !!! remove asi ??
    ?topSectionQuestion    form-lt:has-layout-class \"section\" .
}
WHERE {    
    ?rootQuestion doc:has_related_question ?topSectionQuestion .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "topSectionQuestion"^^xsd:string ;
              ] ;
            sp:predicate doc:has_related_question ;
            sp:subject [
                sp:varName "rootQuestion"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "2 - create wizard step layout for top level sections"^^xsd:string ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "Layout form" ;
.
form-ecc-gen-0.2:merge-form-data
  rdf:type sml:Merge ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# root question does not have any subquestions
ASK 
WHERE {
     ?rootQuestion form-lt:has-layout-class \"form\" .
     FILTER NOT EXISTS {
           ?rootQuestion doc:has_related_question ?subQuestion .
     }
}""" ;
      sp:where (
          [
            sp:object "form" ;
            sp:predicate form-lt:has-layout-class ;
            sp:subject [
                sp:varName "rootQuestion" ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "subQuestion" ;
                        ] ;
                      sp:predicate doc:has_related_question ;
                      sp:subject [
                          sp:varName "rootQuestion" ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "root question does not have any subquestions" ;
    ] ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question with more than one answer
ASK
WHERE {
    ?q a doc:question ;
            doc:has_answer ?a1 ; 
            doc:has_answer ?a2 .
   FILTER(?a1 != ?a2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "a1"^^xsd:string ;
              ] ;
            sp:predicate doc:has_answer ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "a2"^^xsd:string ;
              ] ;
            sp:predicate doc:has_answer ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "a1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "a2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question with more than one answer"^^xsd:string ;
    ] ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question without a label
ASK
WHERE {
    ?question a doc:question .
    FILTER  NOT  EXISTS {
            ?question rdfs:label ?label .
    }
}""" ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "question" ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "label" ;
                        ] ;
                      sp:predicate rdfs:label ;
                      sp:subject [
                          sp:varName "question" ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question without a label" ;
    ] ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question without specified question origin
ASK
WHERE {
    ?question a doc:question .
     FILTER NOT EXISTS {
           ?question form:has-question-origin ?origin . 
    }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "question"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "origin"^^xsd:string ;
                        ] ;
                      sp:predicate form:has-question-origin ;
                      sp:subject [
                          sp:varName "question"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question without specified question origin"^^xsd:string ;
    ] ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is an empty section within the form
ASK
WHERE {    
    ?sectionQ form-lt:has-layout-class \"section\" .
    FILTER NOT EXISTS {
        ?sectionQ doc:has_related_question ?subQ .
    }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object "section" ;
            sp:predicate form-lt:has-layout-class ;
            sp:subject [
                sp:varName "sectionQ"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "subQ"^^xsd:string ;
                        ] ;
                      sp:predicate doc:has_related_question ;
                      sp:subject [
                          sp:varName "sectionQ"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is an empty section within the form"^^xsd:string ;
    ] ;
  kbss-module:has-input-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is no \"form\" element
ASK
WHERE {
        FILTER  NOT  EXISTS {
            ?s form-lt:has-layout-class \"form\" .
        }
}""" ;
      sp:where (
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object "form" ;
                      sp:predicate form-lt:has-layout-class ;
                      sp:subject [
                          sp:varName "s" ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is no \"form\" element" ;
    ] ;
  sm:next form-ecc-gen-0.2:generateEccairsForms_Return ;
  rdfs:label "merge-form-data" ;
.
form-ecc-gen-0.2:operational-full-uri
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:bind-operational-full-service-uri ;
  sm:outputVariable "operationalFullUri" ;
  sml:value "http://onto.fel.cvut.cz/ontologies/eccairs/aviation-3.4.0.2/views/operational-full" ;
  rdfs:label "operational-full-uri" ;
.
form-ecc-gen-0.2:populate-question-from-template
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:attach-label-paths ;
  sm:next form-ecc-gen-0.2:merge-form-data ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "qLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtComment"^^xsd:string ;
              ] ;
            sp:predicate rdfs:comment ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 1 - construct question info for links
CONSTRUCT {
    ?q rdfs:label ?qLabel .
    ?q rdfs:comment ?qtComment .
    ?q form:has-origin-type ?qtOrigin .
}
WHERE {
# bind link questions
    ?q form:has-template ?qt ;
         form:is-clone-of-question ?qCloned .
    ?qt rdfs:label ?qtLabel .    
    ?qt form:has-template-origin ?qtOrigin .
# TODO comment should be part of templates as well -> remove optional
    OPTIONAL {
        ?qt rdfs:comment ?qtComment .
    }
# TODO !!!!!!!
#  BIND(concat(\"Link to '\", ?qtLabel, \"'\") as ?qLabel)
    BIND(?qtLabel as ?qLabel)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qCloned"^^xsd:string ;
              ] ;
            sp:predicate form:is-clone-of-question ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "qtComment"^^xsd:string ;
                    ] ;
                  sp:predicate rdfs:comment ;
                  sp:subject [
                      sp:varName "qt"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                sp:varName "qtLabel"^^xsd:string ;
              ] ;
            sp:variable [
                sp:varName "qLabel"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - construct question info for links"^^xsd:string ;
    ] ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "qtLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtComment"^^xsd:string ;
              ] ;
            sp:predicate rdfs:comment ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-origin-type ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 0 - construct question info for normal questions
CONSTRUCT {
    ?q rdfs:label ?qtLabel .
    ?q rdfs:comment ?qtComment .
    ?q form:has-origin-type ?qtOrigin .
}
WHERE {
# bind qt template
    ?q form:has-template ?qt .
    ?qt rdfs:label ?qtLabel .    
    ?qt form:has-template-origin ?qtOrigin .
# TODO comment should be part of templates as well -> remove optional
    OPTIONAL {
        ?qt rdfs:comment ?qtComment .
    }
    FILTER NOT EXISTS {
         ?q form:is-clone-of-question ?qCloned .
    }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "qtComment"^^xsd:string ;
                    ] ;
                  sp:predicate rdfs:comment ;
                  sp:subject [
                      sp:varName "qt"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "qCloned"^^xsd:string ;
                        ] ;
                      sp:predicate form:is-clone-of-question ;
                      sp:subject [
                          sp:varName "q"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "0 - construct question info for normal questions"^^xsd:string ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "Construct questions info from templates" ;
.
form-ecc-gen-0.2:populate-question-possible-values
  rdf:type sml:ApplyConstruct ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "value" ;
              ] ;
            sp:predicate form:has-possible-value ;
            sp:subject [
                sp:varName "question" ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "label" ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "value" ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "explanation" ;
              ] ;
            sp:predicate rdfs:comment ;
            sp:subject [
                sp:varName "value" ;
              ] ;
          ]
        ) ;
      sp:text """# TODO attach form generator to it
CONSTRUCT {
     ?question form:has-possible-value ?value .
     ?value rdfs:label ?label .
     ?value rdfs:comment ?explanation .
}
WHERE {
    ?question a doc:question .
    ?question form:has-template ?questionTemplate .
    ?questionTemplate form:has-template-origin ?eccAttribute .
    SERVICE ?eccairsSchemaServiceUri {    
         ?eccAttribute a e-m:attribute .
         ?eccAttribute e-m:has-child+ ?value .  
         ?value rdfs:label ?label .
         ?value e-m:has-explanation ?explanation .
# TODO remove !!!!!!!!!!!
#        FILTER(?eccAttribute = <http://onto.fel.cvut.cz/ontologies/eccairs/aviation-3.4.0.2/a-454>)
    }
}""" ;
      sp:where (
          [
            sp:object doc:question ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "question" ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "questionTemplate" ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "question" ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "eccAttribute" ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "questionTemplate" ;
              ] ;
          ]
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object e-m:attribute ;
                  sp:predicate rdf:type ;
                  sp:subject [
                      sp:varName "eccAttribute" ;
                    ] ;
                ]
                [
                  rdf:type sp:TriplePath ;
                  sp:object [
                      sp:varName "value" ;
                    ] ;
                  sp:path [
                      rdf:type sp:ModPath ;
                      sp:modMax -2 ;
                      sp:modMin 1 ;
                      sp:subPath e-m:has-child ;
                    ] ;
                  sp:subject [
                      sp:varName "eccAttribute" ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "label" ;
                    ] ;
                  sp:predicate rdfs:label ;
                  sp:subject [
                      sp:varName "value" ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "explanation" ;
                    ] ;
                  sp:predicate e-m:has-explanation ;
                  sp:subject [
                      sp:varName "value" ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "eccairsSchemaServiceUri" ;
              ] ;
          ]
        ) ;
      rdfs:comment "TODO attach form generator to it" ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "!!TMP  Assign question possible values" ;
.
form-ecc-gen-0.2:question-template-merge
  rdf:type sml:Merge ;
  rdfs:label "!!! TMP question-template-merge" ;
.
form-ecc-gen-0.2:question-templates-cache-service-uri
  rdf:type sml:BindWithConstant ;
  sm:next form-ecc-gen-0.2:retrieve-generated-question-templates ;
  sm:nodeX 3135 ;
  sm:nodeY 195 ;
  sm:outputVariable "questionTemplatesCacheServiceUri" ;
  sml:value [
      rdf:type kbss-spif:create-sparql-service-url ;
      sp:arg1 [
          sp:varName "repositoryUrl"^^xsd:string ;
        ] ;
      sp:arg2 [
          sp:varName "questionTemplatesCacheUri"^^xsd:string ;
        ] ;
    ] ;
  rdfs:label "question-templates-cache-service-uri" ;
.
form-ecc-gen-0.2:recover-question-template
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:construct-initial-question-from-templates ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 1 - recover templates for questions created from input data
CONSTRUCT {
    ?q form:has-template ?qt .
}
WHERE {
    ?q form:has-question-origin ?dataOrigin . 
    ?dataOrigin form-ecc-gen-0.2:is-origin-of-question-template ?qt .
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "dataOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qt"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-template ;
            sp:subject [
                sp:varName "dataOrigin"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "1 - recover templates for questions created from input data"^^xsd:string ;
    ] ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "qt"^^xsd:string ;
              ] ;
            sp:predicate form:has-template ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# 2 - recover templates for questions created from directly templates (not input data)
CONSTRUCT {
    ?q form:has-template ?qt .
}
WHERE {
    ?q form:has-question-origin ?templateOrigin . 
    ?qt a form:question-template .
# TODO not nice, not effective -- this should be rather pre-computed
    BIND(form-ecc-lib:create-qo(?qt) as ?qo)
    FILTER(?templateOrigin = ?qo)    
}"""^^xsd:string ;
      sp:where (
          [
            sp:object [
                sp:varName "templateOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-question-origin ;
            sp:subject [
                sp:varName "q"^^xsd:string ;
              ] ;
          ]
          [
            sp:object form:question-template ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "qt"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type form-ecc-lib:create-qo ;
                sp:arg1 [
                    sp:varName "qt"^^xsd:string ;
                  ] ;
              ] ;
            sp:variable [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:eq ;
                sp:arg1 [
                    sp:varName "templateOrigin"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "qo"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "2 - recover templates for questions created from directly templates (not input data)"^^xsd:string ;
    ] ;
  sml:replace "false"^^xsd:boolean ;
  rdfs:label "Recover question template from origin"^^xsd:string ;
.
form-ecc-gen-0.2:relate-question-origin-to-template
  rdf:type sml:ApplyConstruct ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question origin bound to two question template relations 
ASK
WHERE {
    ?qo a form:question-origin ;
        form-ecc-gen-0.2:is-origin-of-question-templates-reification ?qtsReification1 ;
        form-ecc-gen-0.2:is-origin-of-question-templates-reification ?qtsReification2 .
   FILTER(?qtsReification1 != ?qtsReification2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtsReification1"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-templates-reification ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtsReification2"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-templates-reification ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "qtsReification1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "qtsReification2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question origin bound to two question template relations"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question origin bound to two question templates
ASK
WHERE {
    ?qo a form:question-origin ;
        form-ecc-gen-0.2:is-origin-of-question-template ?oQT1 ;
        form-ecc-gen-0.2:is-origin-of-question-template ?oQT2 .
   FILTER(?oQT1 != ?oQT2)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "oQT1"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-template ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "oQT2"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-template ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:ne ;
                sp:arg1 [
                    sp:varName "oQT1"^^xsd:string ;
                  ] ;
                sp:arg2 [
                    sp:varName "oQT2"^^xsd:string ;
                  ] ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question origin bound to two question templates"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question origin that is not bound to question template
ASK
WHERE {
    ?qo a form:question-origin .
    FILTER NOT EXISTS {
       ?qo form-ecc-gen-0.2:is-origin-of-question-template ?oQT .
    }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "oQT"^^xsd:string ;
                        ] ;
                      sp:predicate form-ecc-gen-0.2:is-origin-of-question-template ;
                      sp:subject [
                          sp:varName "qo"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question origin that is not bound to question template"^^xsd:string ;
    ] ;
  kbss-module:has-output-graph-constraint [
      rdf:type sp:Ask ;
      sp:text """# there is a question origin that is not bound to question template reification
ASK
WHERE {
    ?qo a form:question-origin .
    FILTER NOT EXISTS {
       ?qo form-ecc-gen-0.2:is-origin-of-question-templates-reification ?qtsReification .
    }
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:notExists ;
                sp:elements (
                    [
                      sp:object [
                          sp:varName "qtsReification"^^xsd:string ;
                        ] ;
                      sp:predicate form-ecc-gen-0.2:is-origin-of-question-templates-reification ;
                      sp:subject [
                          sp:varName "qo"^^xsd:string ;
                        ] ;
                    ]
                  ) ;
              ] ;
          ]
        ) ;
      rdfs:comment "there is a question origin that is not bound to question template reification"^^xsd:string ;
    ] ;
  sm:next form-ecc-gen-0.2:construct-data-questions ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "oQT"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-template ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtsReification"^^xsd:string ;
              ] ;
            sp:predicate form-ecc-gen-0.2:is-origin-of-question-templates-reification ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qoLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# construct question templates and its reifications relevant to origins
CONSTRUCT {
    ?qo form-ecc-gen-0.2:is-origin-of-question-template ?oQT ;
           form-ecc-gen-0.2:is-origin-of-question-templates-reification ?qtsReification ;
           rdfs:label ?qoLabel .
}
WHERE {
# bind question origin
      ?qo a form:question-origin ;
              rdf:object ?o .
      ?o a ?o_type .
# bind template
      ?oQT form:has-template-origin ?oTOrigin .
      ?o a ?oTOrigin .
# bind template reification
     ?qtsReification rdf:object ?oQT .
     OPTIONAL {
           ?qo rdf:subject ?s .
     }
     OPTIONAL {          
           ?qtsReification rdf:subject ?sQT .
           ?sQT form:has-template-origin ?sTOrigin .
      	   ?s a ?sTOrigin .                        
     }
     FILTER( (bound(?s) && bound(?sQT)) || (!bound(?s) && !bound(?sQT)))
# bind label for origin
    ?qtsReification rdfs:label ?qtsReificationLabel .
    BIND(concat(\"Origin of '\", ?qtsReificationLabel, \"'\") as ?qoLabel)
}"""^^xsd:string ;
      sp:where (
          [
            sp:object form:question-origin ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "qo"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "o_type"^^xsd:string ;
              ] ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "o"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "oTOrigin"^^xsd:string ;
              ] ;
            sp:predicate form:has-template-origin ;
            sp:subject [
                sp:varName "oQT"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "oTOrigin"^^xsd:string ;
              ] ;
            sp:predicate rdf:type ;
            sp:subject [
                sp:varName "o"^^xsd:string ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "oQT"^^xsd:string ;
              ] ;
            sp:predicate rdf:object ;
            sp:subject [
                sp:varName "qtsReification"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                  sp:predicate rdf:subject ;
                  sp:subject [
                      sp:varName "qo"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Optional ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "sQT"^^xsd:string ;
                    ] ;
                  sp:predicate rdf:subject ;
                  sp:subject [
                      sp:varName "qtsReification"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "sTOrigin"^^xsd:string ;
                    ] ;
                  sp:predicate form:has-template-origin ;
                  sp:subject [
                      sp:varName "sQT"^^xsd:string ;
                    ] ;
                ]
                [
                  sp:object [
                      sp:varName "sTOrigin"^^xsd:string ;
                    ] ;
                  sp:predicate rdf:type ;
                  sp:subject [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                ]
              ) ;
          ]
          [
            rdf:type sp:Filter ;
            sp:expression [
                rdf:type sp:or ;
                sp:arg1 [
                    rdf:type sp:and ;
                    sp:arg1 [
                        rdf:type sp:bound ;
                        sp:arg1 [
                            sp:varName "s"^^xsd:string ;
                          ] ;
                      ] ;
                    sp:arg2 [
                        rdf:type sp:bound ;
                        sp:arg1 [
                            sp:varName "sQT"^^xsd:string ;
                          ] ;
                      ] ;
                  ] ;
                sp:arg2 [
                    rdf:type sp:and ;
                    sp:arg1 [
                        rdf:type sp:not ;
                        sp:arg1 [
                            rdf:type sp:bound ;
                            sp:arg1 [
                                sp:varName "s"^^xsd:string ;
                              ] ;
                          ] ;
                      ] ;
                    sp:arg2 [
                        rdf:type sp:not ;
                        sp:arg1 [
                            rdf:type sp:bound ;
                            sp:arg1 [
                                sp:varName "sQT"^^xsd:string ;
                              ] ;
                          ] ;
                      ] ;
                  ] ;
              ] ;
          ]
          [
            sp:object [
                sp:varName "qtsReificationLabel"^^xsd:string ;
              ] ;
            sp:predicate rdfs:label ;
            sp:subject [
                sp:varName "qtsReification"^^xsd:string ;
              ] ;
          ]
          [
            rdf:type sp:Bind ;
            sp:expression [
                rdf:type sp:concat ;
                sp:arg1 "Origin of '" ;
                sp:arg2 [
                    sp:varName "qtsReificationLabel"^^xsd:string ;
                  ] ;
                sp:arg3 "'" ;
              ] ;
            sp:variable [
                sp:varName "qoLabel"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "construct question templates and its reifications relevant to origins"^^xsd:string ;
    ] ;
  rdfs:label "assign-question-origins-to-templates"^^xsd:string ;
.
form-ecc-gen-0.2:reportGraphId
  rdf:type owl:DatatypeProperty ;
  rdfs:comment "Context with actual state of report that is saved by RT thus including saved Q&A model. Q&A data are empty here in case when report is opened for the first time in RT." ;
  rdfs:label "Named graph id of a report" ;
  rdfs:range xsd:string ;
.
form-ecc-gen-0.2:repositoryUrl
  rdf:type owl:DatatypeProperty ;
  rdfs:label "Repository url" ;
  rdfs:range xsd:string ;
.
form-ecc-gen-0.2:retrieve-generated-question-templates
  rdf:type sml:ApplyConstruct ;
  sm:next form-ecc-gen-0.2:attach-event-filter ;
  sm:next form-ecc-gen-0.2:recover-question-template ;
  sm:next form-ecc-gen-0.2:relate-question-origin-to-template ;
  sml:constructQuery [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o"^^xsd:string ;
              ] ;
            sp:predicate [
                sp:varName "p"^^xsd:string ;
              ] ;
            sp:subject [
                sp:varName "s"^^xsd:string ;
              ] ;
          ]
        ) ;
      sp:text """# CACHE -- instead of \"filter irrelevant templates\"
CONSTRUCT {
    ?s ?p ?o .
}
WHERE {
    SERVICE ?questionTemplatesCacheServiceUri {
          ?s ?p ?o .
    }
}"""^^xsd:string ;
      sp:where (
          [
            rdf:type sp:Service ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "o"^^xsd:string ;
                    ] ;
                  sp:predicate [
                      sp:varName "p"^^xsd:string ;
                    ] ;
                  sp:subject [
                      sp:varName "s"^^xsd:string ;
                    ] ;
                ]
              ) ;
            sp:serviceURI [
                sp:varName "questionTemplatesCacheServiceUri"^^xsd:string ;
              ] ;
          ]
        ) ;
      rdfs:comment "CACHE -- instead of \"filter irrelevant templates\""^^xsd:string ;
    ] ;
  sml:replace "true"^^xsd:boolean ;
  rdfs:label "Retrieve cached generated question templates" ;
.
rdfs:Resource
  spin:query [
      rdf:type sp:Construct ;
      sp:templates (
          [
            sp:object [
                sp:varName "o" ;
              ] ;
            sp:predicate [
                sp:varName "p" ;
              ] ;
            sp:subject [
                sp:varName "s" ;
              ] ;
          ]
        ) ;
      sp:text """#http://dev.inbas.cz/rdf4j-server/repositories/eccairs-aviation-3.4.0.2?query=
CONSTRUCT {
    ?s ?p ?o .
}
WHERE {
    GRAPH <http://onto.fel.cvut.cz/ontologies/eccairs/aviation-3.4.0.2> {
        ?s ?p ?o .
    } .
}""" ;
      sp:where (
          [
            rdf:type sp:NamedGraph ;
            sp:elements (
                [
                  sp:object [
                      sp:varName "o" ;
                    ] ;
                  sp:predicate [
                      sp:varName "p" ;
                    ] ;
                  sp:subject [
                      sp:varName "s" ;
                    ] ;
                ]
              ) ;
            sp:graphNameNode <http://onto.fel.cvut.cz/ontologies/eccairs/aviation-3.4.0.2> ;
          ]
        ) ;
      rdfs:comment "http://dev.inbas.cz/rdf4j-server/repositories/eccairs-aviation-3.4.0.2?query=" ;
    ] ;
  rdfs:comment """#SELECT ?eccTerm
INSERT  {
    graph <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-generated> {   
		?formItem rdfs:label ?label ;        
		rdfs:comment ?comment ;
    }
} 
WHERE {
GRAPH <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-generated> {
   {	?formItem a form:section .
		?formItem <http://onto.fel.cvut.cz/ontologies/form/origin> ?eccTerm .
    } UNION  {
       ?formItem a form:question .
       	?formItem <http://onto.fel.cvut.cz/ontologies/form/origin> ?eccTerm . 
    } 
 }
 GRAPH <http://onto.fel.cvut.cz/ontologies/eccairs-3.4.0.2-v-2016-02-23> {
	?eccTerm <http://onto.fel.cvut.cz/ontologies/eccairs/model/has-description> ?label.
	?eccTerm <http://onto.fel.cvut.cz/ontologies/eccairs/model/has-explanation> ?comment.
    }
} 
""" ;
  rdfs:comment """INSERT {
      GRAPH <http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form-generated> {
          ?section form:has-question ?question .
          ?section a owl:NamedIndividual .
          ?question a owl:NamedIndividual .
          ?section a form:section .
          ?question a form:question .
          ?question <http://onto.fel.cvut.cz/ontologies/form/origin> ?attribute .
          ?section <http://onto.fel.cvut.cz/ontologies/form/origin> ?entity .
       }
} WHERE {
   GRAPH <http://onto.fel.cvut.cz/ontologies/eccairs-3.4.0.2> {
	    ?entity <http://onto.fel.cvut.cz/ontologies/eccairs/model/has-child> ?attribute .
        BIND(\"http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form/\" AS ?eccairsFormIRI) 
        BIND( afn:localname(?entity) AS ?entityName)
 		BIND(iri(concat(?eccairsFormIRI, ?entityName)) AS ?section)
   }
   GRAPH <http://onto.fel.cvut.cz/ontologies/aviation/mapping-ans-eccairs-events-and-attributes> {
	     ?event <http://onto.fel.cvut.cz/ontologies/documentation/has_question> ?attribute .
        BIND(\"http://onto.fel.cvut.cz/ontologies/aviation/eccairs-form/\" AS ?eccairsFormIRI)     
        BIND( afn:localname(?attribute) AS ?attributeName)
        BIND(iri(concat(?eccairsFormIRI, ?attributeName)) AS ?question)
   }
}""" ;
.
