Skip to content

Rethinking restrictions #262

@liamhuber

Description

@liamhuber

And the other keywords, although I think restrictions is at the heart of it. I'm still not sure what this should look like, as evidenced by fulfills introducing its own set of problems (#252). I keep running into issues where things behave in ways that are either outright broken, or suboptimal from my subjective perspective:

Since I'm not even sure what a solution would look like for these issues, but they keep multiplying, I want a central location to keep track of them.

I also thought it would be useful to begin collecting a set of MWE and how they are failing (or "failing" for subjective cases) so that when we do set about to change things, we can get a good test suite up and running quickly.

To that end (on v0.0.22):

import rdflib

from semantikon import ontology as onto
from semantikon import workflow
from semantikon.metadata import u

EX = rdflib.Namespace("http://example.org/")

def provides_it(x: str) -> u(
    str,
    uri=EX.Something,
    triples=(EX.hasProperty, EX.it),
):
    return x

def requires_it_and_provides_other(
    y: u(
        str,
        uri=EX.Something,
        restrictions=(
            (rdflib.OWL.onProperty, EX.hasProperty),
            (rdflib.OWL.someValuesFrom, EX.it),
        ),
    ),
) -> u(
    str,
    derived_from="inputs.y",
    triples=(EX.hasProperty, EX.other),
):
    return y

def requires_other(
    z: u(
        str,
        uri=EX.Something,
        restrictions=(
            (rdflib.OWL.onProperty, EX.hasProperty),
            (rdflib.OWL.someValuesFrom, EX.other),
        ),
    ),
) -> str:
    return z


def wf(w: str) -> str:
    gives_it = provides_it(w)
    # takes_it_and_gives_other = requires_it_and_provides_other(gives_it)
    takes_it_and_gives_other = requires_it_and_provides_other()  # Break link
    needs_other = requires_other(takes_it_and_gives_other)
    return needs_other

wf_dict = workflow.get_workflow_dict(wf)
graph = onto.get_knowledge_graph(wf_dict)
val = onto.validate_values(graph)
val
>>> {'missing_triples': [(rdflib.term.URIRef('wf.requires_it_and_provides_other_0.outputs.y'),
...    rdflib.term.URIRef('http://example.org/hasProperty'),
...    rdflib.term.URIRef('http://example.org/it')),
...   (rdflib.term.URIRef('wf.requires_it_and_provides_other_0.inputs.y'),
...    rdflib.term.URIRef('http://example.org/hasProperty'),
...    rdflib.term.URIRef('http://example.org/it')),
...   (rdflib.term.URIRef('wf.requires_other_0.inputs.z'),
...    rdflib.term.URIRef('http://example.org/hasProperty'),
...    rdflib.term.URIRef('http://example.org/it'))],
...  'incompatible_connections': [],
...  'distinct_units': {}}

The nature of the failure here is a false positive -- 'wf.requires_other_0.inputs.z' has only specifically demanded the EX.other property, but because of the way types are inherited (so that uri= correctly gets inherited, #241), we see here that it also demands EX.it.

I suspect the nature of the solution here is, in some way, to distinguish between triples that are added and triples that are required, and to inherit all those added from upstream but not to inherit those required.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions