@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix usdm: <https://w3id.org/cdisc/usdm/v4/> .
@prefix uo: <https://kerfors.github.io/usdm-overlay/> .
@prefix uof: <https://kerfors.github.io/usdm-overlay/id/finding/> .
@prefix ct: <https://github.com/cdisc-org/DDF-RA/blob/v4.0.0/Deliverables/CT/> .
@prefix uml: <https://github.com/cdisc-org/DDF-RA/blob/v4.0.0/Deliverables/UML/> .
@prefix rdfrepo: <https://github.com/kerfors/usdm-rdf/blob/v0.7.1/> .

# Findings about the USDM v4 model and its published examples. Hand-maintained.
# Each finding has one test: a SPARQL ASK query over usdm_v4.ttl (uo:testQuery with
# uo:expectedResult), or a named function in scripts/check_findings.py (uo:checkFunction).
# Statements are qualitative; counts are written by the check script to
# derived/finding_results.ttl and reports/findings.md.

# ---------------------------------------------------------------- missing links

uof:endpoint-activity-gap a uo:Finding ;
    dcterms:title "No link between Endpoint and what it requires" ;
    uo:statement "No property connects Endpoint, or its superclass SyntaxTemplate, to Activity, Procedure, ScheduledActivityInstance or the biomedical concept classes, in either direction. The model does not carry which activities or biomedical concepts an endpoint depends on." ;
    dcterms:subject usdm:Endpoint, usdm:Activity, usdm:BiomedicalConcept, usdm:Procedure ;
    uo:evidenceTier uo:ModelStated ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "The model may leave endpoint dependencies out of scope on purpose." ;
    uo:testQuery """PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX usdm: <https://w3id.org/cdisc/usdm/v4/>
ASK {
    {
        VALUES ?d { usdm:Endpoint usdm:SyntaxTemplate }
        VALUES ?r { usdm:Activity usdm:Procedure usdm:ScheduledActivityInstance usdm:ScheduledInstance
                    usdm:BiomedicalConcept usdm:BiomedicalConceptCategory usdm:BiomedicalConceptSurrogate }
        ?p rdfs:domain ?d ; rdfs:range/(owl:unionOf/rdf:rest*/rdf:first)? ?r .
    } UNION {
        VALUES ?d { usdm:Activity usdm:Procedure usdm:ScheduledActivityInstance usdm:ScheduledInstance
                    usdm:BiomedicalConcept usdm:BiomedicalConceptCategory usdm:BiomedicalConceptSurrogate }
        VALUES ?r { usdm:Endpoint usdm:SyntaxTemplate }
        ?p rdfs:domain ?d ; rdfs:range/(owl:unionOf/rdf:rest*/rdf:first)? ?r .
    }
}""" ;
    uo:expectedResult false ;
    dcterms:source rdfrepo:usdm_v4.ttl .

uof:design-elements-not-linked-to-document a uo:Finding ;
    dcterms:title "Objectives, endpoints and criteria have no link to document sections" ;
    uo:statement "No property connects Objective, Endpoint, EligibilityCriterion or EligibilityCriterionItem to the document structure (StudyDefinitionDocument, StudyDefinitionDocumentVersion, NarrativeContent, NarrativeContentItem, DocumentContentReference), in either direction." ;
    dcterms:subject usdm:Objective, usdm:Endpoint, usdm:EligibilityCriterion, usdm:EligibilityCriterionItem, usdm:NarrativeContent ;
    uo:evidenceTier uo:ModelStated ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "The model may leave the link between design elements and document sections out of scope on purpose." ;
    uo:testQuery """PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX usdm: <https://w3id.org/cdisc/usdm/v4/>
ASK {
    {
        VALUES ?d { usdm:Objective usdm:Endpoint usdm:SyntaxTemplate usdm:EligibilityCriterion usdm:EligibilityCriterionItem }
        VALUES ?r { usdm:StudyDefinitionDocument usdm:StudyDefinitionDocumentVersion usdm:NarrativeContent
                    usdm:NarrativeContentItem usdm:DocumentContentReference }
        ?p rdfs:domain ?d ; rdfs:range/(owl:unionOf/rdf:rest*/rdf:first)? ?r .
    } UNION {
        VALUES ?d { usdm:StudyDefinitionDocument usdm:StudyDefinitionDocumentVersion usdm:NarrativeContent
                    usdm:NarrativeContentItem usdm:DocumentContentReference }
        VALUES ?r { usdm:Objective usdm:Endpoint usdm:SyntaxTemplate usdm:EligibilityCriterion usdm:EligibilityCriterionItem }
        ?p rdfs:domain ?d ; rdfs:range/(owl:unionOf/rdf:rest*/rdf:first)? ?r .
    }
}""" ;
    uo:expectedResult false ;
    dcterms:source rdfrepo:usdm_v4.ttl .

uof:document-content-reference-amendments-only a uo:Finding ;
    dcterms:title "Section references are used only for amendment changes" ;
    uo:statement "DocumentContentReference, the class that points at a document section by number and title, is the range of one property only: StudyChange.changedSections." ;
    dcterms:subject usdm:DocumentContentReference, usdm:StudyChange ;
    uo:evidenceTier uo:ModelStated ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Limiting section references to amendment changes may be deliberate." ;
    uo:testQuery """PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX usdm: <https://w3id.org/cdisc/usdm/v4/>
ASK {
    ?p rdfs:range/(owl:unionOf/rdf:rest*/rdf:first)? usdm:DocumentContentReference .
    FILTER (?p != usdm:StudyChange-changedSections)
}""" ;
    uo:expectedResult false ;
    dcterms:source rdfrepo:usdm_v4.ttl .

uof:condition-not-referenced a uo:Finding ;
    dcterms:title "Schedule conditions are strings, not Condition instances" ;
    uo:statement "ConditionAssignment.condition and ScheduleTimeline.entryCondition have range xsd:string. The model has a Condition class, but neither attribute references it." ;
    dcterms:subject usdm:ConditionAssignment, usdm:ScheduleTimeline, usdm:Condition ;
    uo:evidenceTier uo:ModelStated ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Holding schedule conditions as strings may be a deliberate choice; the ask would be a modelling change." ;
    uo:testQuery """PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX usdm: <https://w3id.org/cdisc/usdm/v4/>
ASK {
    usdm:Condition a owl:Class .
    usdm:ConditionAssignment-condition rdfs:range xsd:string .
    usdm:ScheduleTimeline-entryCondition rdfs:range xsd:string .
}""" ;
    uo:expectedResult true ;
    dcterms:source rdfrepo:usdm_v4.ttl .

uof:narrative-content-text-by-reference a uo:Finding ;
    dcterms:title "NarrativeContent holds its text by reference" ;
    uo:statement "NarrativeContent is defined as \"The container that holds an instance of unstructured text and which may include objects such as tables, figures, and images.\" The class has no text attribute. Its text is a NarrativeContentItem, which NarrativeContent references (contentItemId, relationship type Ref, 0..1) and which StudyVersion composes (narrativeContentItems). The section and its text are separate instances, linked by reference." ;
    dcterms:subject usdm:NarrativeContent, usdm:NarrativeContentItem ;
    uo:evidenceTier uo:ModelStated ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Holding the text in a separate referenced item may be deliberate, for reuse across sections." ;
    uo:testQuery """PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX usdm: <https://w3id.org/cdisc/usdm/v4/>
ASK {
    usdm:NarrativeContent skos:definition ?def .
    FILTER (STRSTARTS(STR(?def), "The container that holds an instance of unstructured text"))
    usdm:NarrativeContent-contentItemId rdfs:domain usdm:NarrativeContent ;
        rdfs:range usdm:NarrativeContentItem ; usdm:relationshipType "Ref" .
    usdm:StudyVersion-narrativeContentItems rdfs:range usdm:NarrativeContentItem ; usdm:relationshipType "Value" .
    FILTER NOT EXISTS {
        ?p rdfs:domain usdm:NarrativeContent ; rdfs:range usdm:NarrativeContentItem ; usdm:relationshipType "Value" .
    }
    FILTER NOT EXISTS {
        ?p rdfs:domain usdm:NarrativeContent ; rdfs:range xsd:string .
        FILTER (?p NOT IN (usdm:NarrativeContent-id, usdm:NarrativeContent-instanceType, usdm:NarrativeContent-name,
                           usdm:NarrativeContent-sectionNumber, usdm:NarrativeContent-sectionTitle))
    }
}""" ;
    uo:expectedResult true ;
    dcterms:source rdfrepo:usdm_v4.ttl, ct:USDM_CT.xlsx .

# ---------------------------------------------------------------- model files

uof:abstract-class-attribute-ccodes a uo:Finding ;
    dcterms:title "Abstract-class attributes carry a subclass's C-code" ;
    uo:statement "For attributes declared on abstract classes, dataStructure.yml carries the C-code, preferred term and definition of one concrete subclass, not the abstract class's own entry in USDM_CT.xlsx. usdm-rdf renders the YAML, so its skos:exactMatch on these properties points to the subclass concept. Example: SyntaxTemplate.text carries C207478 Characteristic Text; USDM_CT.xlsx lists C207578 Syntax Template Text for SyntaxTemplate.text." ;
    dcterms:subject usdm:SyntaxTemplate, usdm:Identifier, usdm:PopulationDefinition, usdm:ScheduledInstance, usdm:StudyDesign ;
    uo:evidenceTier uo:ModelStated ;
    uo:standing uo:ReadyToRaise ;
    uo:standingRationale "Two published artefacts, dataStructure.yml and USDM_CT.xlsx, give different C-codes for the same attributes." ;
    uo:checkFunction "abstract_class_attribute_ccodes" ;
    dcterms:source uml:dataStructure.yml, ct:USDM_CT.xlsx, rdfrepo:usdm_v4.ttl .

uof:procedure-type-uncoded a uo:Finding ;
    dcterms:title "Procedure type is an uncoded classification" ;
    uo:statement "Procedure.procedureType and Endpoint.level share the definition pattern \"A characterization or classification of ...\". Endpoint.level has a value list; Procedure.procedureType has none and is a string." ;
    dcterms:subject usdm:Procedure, usdm:Endpoint ;
    uo:evidenceTier uo:DefinitionStated ;
    uo:standing uo:ReadyToRaise ;
    uo:standingRationale "USDM_CT.xlsx treats the same definition pattern as coded in one place and as a free string in another." ;
    uo:checkFunction "procedure_type_uncoded" ;
    dcterms:source ct:USDM_CT.xlsx .

uof:population-summary-term-vs-definition a uo:Finding ;
    dcterms:title "Population-level summary: term and definition disagree" ;
    uo:statement "Estimand.populationSummary has the preferred term \"Population-Level Summary\", the ICH E9(R1) estimand attribute. Its definition, \"A synopsis of the clinical endpoint of interest within the analysis target study population\", describes a narrative synopsis. The attribute is left unclassified in the overlay until the two are reconciled." ;
    dcterms:subject usdm:Estimand ;
    uo:evidenceTier uo:Authored ;
    uo:standing uo:ReadyToRaise ;
    uo:standingRationale "One USDM_CT.xlsx row carries two meanings: the preferred term is the ICH E9(R1) attribute, the definition a narrative synopsis." ;
    uo:rationale "ICH E9(R1), section A.3.3, describes the attribute as a population-level summary for the variable, providing a basis for comparison between treatment conditions. Read that way the value is a statistical summary measure, close to a classification. Read by the NCI definition it is prose." ;
    uo:checkFunction "population_summary_term_vs_definition" ;
    dcterms:source ct:USDM_CT.xlsx ;
    dcterms:source <https://www.ema.europa.eu/documents/scientific-guideline/ich-e9-r1-addendum-estimands-sensitivity-analysis-clinical-trials-guideline-statistical-principles_en.pdf> .

uof:intercurrent-event-strategy-textual a uo:Finding ;
    dcterms:title "Intercurrent event strategy: fixed set, specified as text" ;
    uo:statement "IntercurrentEvent.strategy is defined as a textual description and has no value list. ICH E9(R1), section A.3.2, names five strategies: treatment policy, hypothetical, composite variable, while on treatment, principal stratum. The overlay classifies the attribute as classification as text; read by its definition alone it would be prose." ;
    dcterms:subject usdm:IntercurrentEvent ;
    uo:evidenceTier uo:Authored ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "The gap to ICH E9(R1) is plain, but asking for a value list is a modelling request." ;
    uo:rationale "The substance is one of a fixed set named by the guideline, possibly with explanation. Classifying by substance shows where a value list could carry meaning that the model holds as text." ;
    uo:checkFunction "intercurrent_event_strategy_textual" ;
    dcterms:source ct:USDM_CT.xlsx ;
    dcterms:source <https://www.ema.europa.eu/documents/scientific-guideline/ich-e9-r1-addendum-estimands-sensitivity-analysis-clinical-trials-guideline-statistical-principles_en.pdf> .

# ---------------------------------------------------------------- published examples

uof:narrative-references-by-markup a uo:Finding ;
    dcterms:title "Narrative refers to model instances by markup in text" ;
    uo:statement "In the published examples, NarrativeContentItem.text refers to model instances by usdm:ref elements inside the XHTML string, each naming a class (klass), an instance (id) and one attribute. The reference runs from the section to one attribute value. dataStructure.yml does not mention the convention." ;
    dcterms:subject usdm:NarrativeContentItem ;
    uo:evidenceTier uo:ExampleObserved ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Rests on the published example files, which are not mature study definitions." ;
    uo:checkFunction "narrative_references_by_markup" ;
    dcterms:source uml:dataStructure.yml ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .

uof:syntax-template-parameters-rarely-used a uo:Finding ;
    dcterms:title "Syntax-template parameters are rarely used" ;
    uo:statement "In the published examples, most syntax-template instances (Objective, Endpoint, EligibilityCriterionItem, IntercurrentEvent, Condition, Characteristic) have no dictionary, so their text carries no parameters the model can see." ;
    dcterms:subject usdm:SyntaxTemplate, usdm:SyntaxTemplateDictionary ;
    uo:evidenceTier uo:ExampleObserved ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Rests on the published example files, which are not mature study definitions." ;
    uo:checkFunction "syntax_template_parameters_rarely_used" ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .

uof:timing-iso8601-convention a uo:Finding ;
    dcterms:title "Timing values follow ISO 8601 by convention only" ;
    uo:statement "In the published examples, every non-empty Timing.value, windowLower and windowUpper is an ISO 8601 duration. Neither dataStructure.yml nor USDM_CT.xlsx names a syntax for them; the range is xsd:string." ;
    dcterms:subject usdm:Timing ;
    uo:evidenceTier uo:ExampleObserved ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Rests on the published example files, which are not mature study definitions." ;
    uo:checkFunction "timing_iso8601_convention" ;
    dcterms:source uml:dataStructure.yml, ct:USDM_CT.xlsx ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .

uof:parameter-reference-by-markup a uo:Finding ;
    dcterms:title "Syntax-template parameters resolve through markup" ;
    uo:statement "In the published examples, ParameterMap.reference holds usdm:ref markup, the same convention as narrative text. A syntax-template parameter resolves to a model value through markup in a string, not through a model reference." ;
    dcterms:subject usdm:ParameterMap, usdm:SyntaxTemplateDictionary, usdm:SyntaxTemplate ;
    uo:evidenceTier uo:ExampleObserved ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Rests on the published example files, which are not mature study definitions." ;
    uo:checkFunction "parameter_reference_by_markup" ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .

uof:bc-property-datatype-names a uo:Finding ;
    dcterms:title "Biomedical concept property datatypes are uncontrolled names" ;
    uo:statement "BiomedicalConceptProperty.datatype has no value list. The published examples use a small set of datatype names, including both 'text' and 'string', with nothing in the model to say whether they differ." ;
    dcterms:subject usdm:BiomedicalConceptProperty ;
    uo:evidenceTier uo:ExampleObserved ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Rests on the published example files, which are not mature study definitions." ;
    uo:checkFunction "bc_property_datatype_names" ;
    dcterms:source ct:USDM_CT.xlsx ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .

uof:study-amendment-number-not-numerals a uo:Finding ;
    dcterms:title "Amendment number: definition says numerals, an example uses a letter" ;
    uo:statement "StudyAmendment.number is defined as \"A string of numerals that uniquely identifies a protocol amendment.\" A published example uses a letter." ;
    dcterms:subject usdm:StudyAmendment ;
    uo:evidenceTier uo:ExampleObserved ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Rests on the published example files, which are not mature study definitions." ;
    uo:checkFunction "study_amendment_number_not_numerals" ;
    dcterms:source ct:USDM_CT.xlsx ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .

uof:eligibility-identifier-needs-category a uo:Finding ;
    dcterms:title "Eligibility identifier identifies only together with the category" ;
    uo:statement "In some published examples, EligibilityCriterion.identifier restarts per category (inclusion and exclusion each start at 1) and is not repeated within a category. The identifier alone does not identify a criterion; the identifier with the category does." ;
    dcterms:subject usdm:EligibilityCriterion ;
    uo:evidenceTier uo:ExampleObserved ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Rests on the published example files, which are not mature study definitions." ;
    uo:checkFunction "eligibility_identifier_needs_category" ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .

uof:template-tags-by-markup a uo:Finding ;
    dcterms:title "Template parameters are matched by name inside text" ;
    uo:statement "Syntax-template text marks parameters with usdm:tag elements that name a ParameterMap.tag. The stored tag is a bare name; the angle brackets that the NCI definition of ParameterMap.tag describes appear only in the template text. Resolution is by name inside a string, so a tag can lack a matching ParameterMap, and the published examples include such a case." ;
    dcterms:subject usdm:ParameterMap, usdm:SyntaxTemplate, usdm:SyntaxTemplateDictionary ;
    uo:evidenceTier uo:ExampleObserved ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Rests on the published example files, which are not mature study definitions." ;
    uo:checkFunction "template_tags_by_markup" ;
    dcterms:source ct:USDM_CT.xlsx ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .

uof:timing-labels-restate-values a uo:Finding ;
    dcterms:title "Timing labels are typed, not generated from the value" ;
    uo:statement "Timing.valueLabel restates Timing.value in free text. In the published examples the same value carries differently spelled labels, so the label is not generated from the value." ;
    dcterms:subject usdm:Timing ;
    uo:evidenceTier uo:ExampleObserved ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Rests on the published example files, which are not mature study definitions." ;
    uo:checkFunction "timing_labels_restate_values" ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .

uof:code-system-free-strings a uo:Finding ;
    dcterms:title "Code systems are named by free strings" ;
    uo:statement "Code.codeSystem and Code.codeSystemVersion are free strings. In the published examples the code system is given in mixed forms, a URL for CDISC terminology and names for the others, and versions in several formats. A coded value is identified by strings, not by an IRI." ;
    dcterms:subject usdm:Code ;
    uo:evidenceTier uo:ExampleObserved ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Identifying code systems by strings is a modelling choice; the examples show its effect." ;
    uo:checkFunction "code_system_free_strings" ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .

uof:bc-reference-library-paths a uo:Finding ;
    dcterms:title "Biomedical concept references are relative API paths" ;
    uo:statement "In the published examples, every BiomedicalConcept.reference is a relative CDISC Library API path, most into SDTM dataset specializations and some into biomedical concept packages. Resolving one needs a base URL and access to the Library." ;
    dcterms:subject usdm:BiomedicalConcept ;
    uo:evidenceTier uo:ExampleObserved ;
    uo:standing uo:ForDiscussion ;
    uo:standingRationale "Rests on the published example files, which are not mature study definitions." ;
    uo:checkFunction "bc_reference_library_paths" ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .

uof:extension-attributes-undefined a uo:Finding ;
    dcterms:title "Extension classes carry no definitions" ;
    uo:statement "ExtensionAttribute and ExtensionClass have no rows in USDM_CT.xlsx and no definitions in usdm-rdf. No published example uses them." ;
    dcterms:subject usdm:ExtensionAttribute, usdm:ExtensionClass ;
    uo:evidenceTier uo:ModelStated ;
    uo:standing uo:ReadyToRaise ;
    uo:standingRationale "Two classes in the published model have no definitions in any published artefact." ;
    uo:checkFunction "extension_attributes_undefined" ;
    dcterms:source ct:USDM_CT.xlsx, rdfrepo:usdm_v4.ttl ;
    dcterms:source <https://github.com/cdisc-org/DDF-RA/tree/v4.0.0/Documents/Examples> .
