@prefix cov: <https://mustrd.org/coverage/> .
@prefix cq: <https://mustrd.org/competencyQuestion/> .
@prefix dqv: <http://www.w3.org/ns/dqv#> .
@prefix must: <https://mustrd.org/model/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

cov: a owl:Ontology ;
    rdfs:label "MustRD ontology coverage" ;
    rdfs:comment "An RDF view of a mustrd term-coverage run: how well a test suite exercises an ontology, expressed as W3C DQV quality measurements plus a per-term breakdown, so it can be merged into a knowledge graph and queried over time. This is a quality of the ONTOLOGY (measured by the tests), not of the test suite." ;
    owl:imports dqv:,
        prov:,
        must: .

cov:Covered a cov:CoverageRole ;
    skos:definition "Populated in a passing test's input data." ;
    skos:prefLabel "covered" .

cov:Failed a cov:Outcome ;
    skos:prefLabel "not passed" .

cov:Passed a cov:Outcome ;
    skos:prefLabel "passed" .

cov:QueryOnly a cov:CoverageRole ;
    skos:definition "Named by a query but never instantiated; the test passes without it. Not covered." ;
    skos:prefLabel "query only" .

cov:Skipped a cov:Outcome ;
    skos:prefLabel "skipped" .

cov:Structural a cov:CoverageRole ;
    skos:definition "Not instantiated or queried, but load-bearing (domain/range of a used property, superclass of a used class, or a metadata property). Excluded from the coverage ratio." ;
    skos:prefLabel "structural" .

cov:TBoxInTestData a cov:IssueType ;
    skos:definition "Class/property declarations or rdfs:subClassOf/domain/range axioms found in a test's input data, where only instance data belongs." ;
    skos:prefLabel "TBox in test data" .

cov:Unused a cov:CoverageRole ;
    skos:definition "Declared but neither instantiated, queried, nor structural." ;
    skos:prefLabel "unused" .

cov:UsedButNotDeclared a cov:IssueType ;
    skos:definition "A term referenced by a test, in a declared ontology's namespace, but not itself declared — likely a typo or a missing definition." ;
    skos:prefLabel "used but not declared" .

cov:aboutTerm a owl:ObjectProperty ;
    rdfs:label "about term" ;
    rdfs:comment "The term the issue concerns (which may be undeclared)." ;
    rdfs:domain cov:QualityIssue .

cov:aboutTest a owl:ObjectProperty ;
    rdfs:label "about test" ;
    rdfs:domain cov:QualityIssue ;
    rdfs:range must:TestSpec .

cov:ciRun a owl:ObjectProperty ;
    rdfs:label "CI run" ;
    rdfs:comment "A link to the CI job that produced the run (e.g. the GitHub Actions run), when run in CI." ;
    rdfs:domain cov:CoverageRun .

cov:className a owl:DatatypeProperty ;
    rdfs:label "class name" ;
    rdfs:domain cov:TestResult ;
    rdfs:range xsd:string .

cov:cqRole a owl:ObjectProperty ;
    rdfs:label "cq role" ;
    rdfs:comment "As cov:role, but counting only competency-question tests." ;
    rdfs:domain cov:TermCoverage ;
    rdfs:range cov:CoverageRole .

cov:detail a owl:DatatypeProperty ;
    rdfs:label "detail" ;
    rdfs:domain cov:QualityIssue ;
    rdfs:range xsd:string .

cov:duplicateOf a owl:ObjectProperty ;
    rdfs:label "duplicate of" ;
    rdfs:comment "On a cov:Assertion (whose cov:onCompetencyQuestion is the subject CQ): another CQ that shares its question text. Both are excluded from the coverage calculation as a likely copy/paste. The relation is symmetric between the members of a duplicate group. Modelling it as a run assertion keeps the finding off the CQ node itself." ;
    rdfs:domain cov:Assertion ;
    rdfs:range cq:CompetencyQuestion .

cov:duration a owl:DatatypeProperty ;
    rdfs:label "duration" ;
    rdfs:comment "Wall-clock execution time in seconds." ;
    rdfs:domain cov:TestResult ;
    rdfs:range xsd:decimal .

cov:embeddedSource a owl:ObjectProperty ;
    rdfs:label "embedded source" ;
    rdfs:comment "A source this test is defined by or executes." ;
    rdfs:domain must:TestSpec ;
    rdfs:range cov:SourceFile .

cov:exercise a owl:ObjectProperty ;
    rdfs:label "exercise" ;
    rdfs:comment "A per-test record of how one test exercises the term." ;
    rdfs:domain cov:TermCoverage ;
    rdfs:range cov:Exercise .

cov:filePath a owl:DatatypeProperty ;
    rdfs:label "file path" ;
    rdfs:comment "Where the text came from, relative to the run's working directory. Absent for a query given inline in the spec." ;
    rdfs:domain cov:SourceFile ;
    rdfs:range xsd:string .

cov:fileReference a owl:DatatypeProperty ;
    rdfs:label "file reference" ;
    rdfs:comment "How a spec named this file — the must:file or must:fileurl value as written, when it differs from cov:filePath. Lets a report turn the reference inside a spec into a link to the embedded copy." ;
    rdfs:domain cov:SourceFile ;
    rdfs:range xsd:string .

cov:fileText a owl:DatatypeProperty ;
    rdfs:label "file text" ;
    rdfs:comment "The verbatim content." ;
    rdfs:domain cov:SourceFile ;
    rdfs:range xsd:string .

cov:gitCommit a owl:DatatypeProperty ;
    rdfs:label "git commit" ;
    rdfs:comment "The git commit SHA the run was computed at (GITHUB_SHA in CI, else the local HEAD)." ;
    rdfs:domain cov:CoverageRun ;
    rdfs:range xsd:string .

cov:gitCommitUrl a owl:ObjectProperty ;
    rdfs:label "git commit URL" ;
    rdfs:comment "A web link to that commit — cov:gitRepository + '/commit/' + cov:gitCommit (e.g. the GitHub commit page), when the repository is known. The clickable counterpart of the cov:gitCommit SHA." ;
    rdfs:domain cov:CoverageRun .

cov:gitRepository a owl:ObjectProperty ;
    rdfs:label "git repository" ;
    rdfs:comment "A link to the source repository the run was computed from (GITHUB_REPOSITORY in CI, else the local `origin` remote, normalised to an https URL)." ;
    rdfs:domain cov:CoverageRun .

cov:inData a owl:DatatypeProperty ;
    rdfs:label "in data" ;
    rdfs:range xsd:boolean .

cov:inQuery a owl:DatatypeProperty ;
    rdfs:label "in query" ;
    rdfs:range xsd:boolean .

cov:issueType a owl:ObjectProperty ;
    rdfs:label "issue type" ;
    rdfs:domain cov:QualityIssue ;
    rdfs:range cov:IssueType .

cov:kind a owl:DatatypeProperty ;
    rdfs:label "kind" ;
    rdfs:comment "Whether the term is a 'class' or a 'property'." ;
    rdfs:domain cov:TermCoverage ;
    rdfs:range xsd:string .

cov:mediaType a owl:DatatypeProperty ;
    rdfs:label "media type" ;
    rdfs:comment "'text/turtle' or 'application/sparql-query'." ;
    rdfs:domain cov:SourceFile ;
    rdfs:range xsd:string .

cov:module a owl:DatatypeProperty ;
    rdfs:label "module" ;
    rdfs:domain cov:TestResult ;
    rdfs:range xsd:string .

cov:onCompetencyQuestion a owl:ObjectProperty ;
    rdfs:label "on competency question" ;
    rdfs:domain cov:Assertion ;
    rdfs:range cq:CompetencyQuestion .

cov:onTest a owl:ObjectProperty ;
    rdfs:label "on test" ;
    rdfs:domain cov:Assertion ;
    rdfs:range must:TestSpec .

cov:outcome a owl:ObjectProperty ;
    rdfs:label "outcome" ;
    rdfs:domain cov:Assertion ;
    rdfs:range cov:Outcome .

cov:reference a owl:ObjectProperty ;
    rdfs:label "reference" ;
    rdfs:comment "A per-test record of where a term is referenced (data and/or SPARQL)." ;
    rdfs:domain cov:QualityIssue ;
    rdfs:range cov:Reference .

cov:requiresOntology a owl:ObjectProperty ;
    rdfs:label "requires ontology" ;
    rdfs:comment "An ontology the test matches its data only *through* (via that ontology's class hierarchy), so it must be loaded as an input for the test to pass. Absence means the test passes on its own data. Replaces an earlier boolean." ;
    rdfs:domain cov:Assertion ;
    rdfs:range owl:Ontology .

cov:resultOutcome a owl:ObjectProperty ;
    rdfs:label "result outcome" ;
    rdfs:domain cov:TestResult ;
    rdfs:range cov:Outcome .

cov:resultTest a owl:ObjectProperty ;
    rdfs:label "result test" ;
    rdfs:comment "The mustrd test spec this result is for (absent for plain pytest tests)." ;
    rdfs:domain cov:TestResult ;
    rdfs:range must:TestSpec .

cov:role a owl:ObjectProperty ;
    rdfs:label "role" ;
    rdfs:comment "How the term is exercised across all tests." ;
    rdfs:domain cov:TermCoverage ;
    rdfs:range cov:CoverageRole .

cov:sourceFile a owl:DatatypeProperty ;
    rdfs:label "source file" ;
    rdfs:comment "The file an ontology was read from, as a path relative to the run's working directory (for report links)." ;
    rdfs:range xsd:string .

cov:structuralReason a owl:DatatypeProperty ;
    rdfs:label "structural reason" ;
    rdfs:comment "Why a structural term is load-bearing (e.g. domain/range of a used property)." ;
    rdfs:domain cov:TermCoverage ;
    rdfs:range xsd:string .

cov:term a owl:ObjectProperty ;
    rdfs:label "term" ;
    rdfs:comment "The ontology term (class or property) this record is about." ;
    rdfs:domain cov:TermCoverage .

cov:termCoverageByCompetencyQuestions a dqv:Metric ;
    skos:definition "As cov:termCoverageByTests, but crediting only tests linked from a competency question." ;
    skos:prefLabel "Term coverage by competency questions" ;
    dqv:expectedDataType xsd:decimal ;
    dqv:inDimension cov:OntologyTermCoverage .

cov:termCoverageByTests a dqv:Metric ;
    skos:definition "Ratio (0..1) of declared, non-structural ontology terms that a passing test populates in its input data." ;
    skos:prefLabel "Term coverage by tests" ;
    dqv:expectedDataType xsd:decimal ;
    dqv:inDimension cov:OntologyTermCoverage .

cov:test a owl:ObjectProperty ;
    rdfs:label "test" ;
    rdfs:comment "The mustrd test spec of an exercise or reference." ;
    rdfs:range must:TestSpec .

cov:testName a owl:DatatypeProperty ;
    rdfs:label "test name" ;
    rdfs:domain cov:TestResult ;
    rdfs:range xsd:string .

cov:testType a owl:DatatypeProperty ;
    rdfs:label "test type" ;
    rdfs:comment "'mustrd' or 'pytest'." ;
    rdfs:domain cov:TestResult ;
    rdfs:range xsd:string .

cov:usesInData a owl:ObjectProperty ;
    rdfs:label "uses in data" ;
    rdfs:comment "A domain term (declared or not) the test asserts in its input data." ;
    rdfs:domain must:TestSpec .

cov:usesInQuery a owl:ObjectProperty ;
    rdfs:label "uses in query" ;
    rdfs:comment "A domain term (declared or not) the test names in its SPARQL." ;
    rdfs:domain must:TestSpec .

cov:Completeness a dqv:Category ;
    skos:prefLabel "Completeness" .

cov:Exercise a owl:Class ;
    rdfs:label "Exercise" ;
    rdfs:comment "One test's contribution to a term: whether it appears in that test's data and/or SPARQL." .

cov:Reference a owl:Class ;
    rdfs:label "Reference" ;
    rdfs:comment "One test's reference to an undeclared term (in its data and/or SPARQL)." .

cov:OntologyTermCoverage a dqv:Dimension ;
    skos:definition "How many of an ontology's declared terms the tests exercise." ;
    skos:prefLabel "Ontology term coverage" ;
    dqv:inCategory cov:Completeness .

cov:IssueType a owl:Class ;
    rdfs:label "Issue type" ;
    rdfs:subClassOf skos:Concept .

cov:CoverageRun a owl:Class ;
    rdfs:label "Coverage run" ;
    rdfs:comment "One mustrd coverage computation over one or more ontologies. Each run gets a fresh URI so successive runs accumulate in a knowledge graph rather than clobber. Carries prov:startedAtTime (when it ran), cov:gitCommit / cov:commit (the revision), and cov:ciRun (the CI job) when available." ;
    rdfs:subClassOf prov:Activity .

cov:Assertion a owl:Class ;
    rdfs:label "Assertion" ;
    rdfs:comment "Something a run asserts about a competency question: either one test's verification of it (cov:onTest + cov:outcome), or that it duplicates another CQ (cov:duplicateOf)." .

cov:Outcome a owl:Class ;
    rdfs:label "Outcome" ;
    rdfs:subClassOf skos:Concept .

cov:QualityIssue a owl:Class ;
    rdfs:label "Quality issue" ;
    rdfs:comment "A problem surfaced while computing coverage." .

cov:SourceFile a owl:Class ;
    rdfs:label "Source file" ;
    rdfs:comment "The verbatim text of a file (or query) a run read." .

cov:CoverageRole a owl:Class ;
    rdfs:label "Coverage role" ;
    rdfs:subClassOf skos:Concept .

cov:TermCoverage a owl:Class ;
    rdfs:label "Term coverage" ;
    rdfs:comment "How one declared ontology term is exercised by the tests in a run." .

cov:TestResult a owl:Class ;
    rdfs:label "Test Result" ;
    rdfs:comment "One test's execution outcome in a run (mustrd spec or plain pytest test)." .

