linkml / linkml-model

Link Modeling Language (LinkML) model
https://linkml.github.io/linkml-model/docs/
33 stars 16 forks source link

Make maximum_value and minimum_value accept linkml:Any #176

Closed sneakers-the-rat closed 5 months ago

sneakers-the-rat commented 5 months ago

Fix: https://github.com/linkml/linkml/issues/1384

Per the discussion on 1384, Relax the range constraint on minimum_value and maximum_value to accept linkml:Any, pending a fuller rework to create an Ordinal meta-type.

Changes

I tried running gen-project but it seemed to not just change the minimum_value and maximum_value, but rework most of the generated schema, so I held off adding that to the PR - not sure how that typically works in PRs for this repo. lmk if i should include.

turbomam commented 5 months ago

The ranges asserting here are Anything. Isn't there also a LinkML Any? What's the difference?

sneakers-the-rat commented 5 months ago

I just followed the example of the other existing Anything range. It looks like its an alias: https://github.com/sneakers-the-rat/linkml-model/blob/3ad48fc0c1fd0cc5664ac85f36b26aea7c7901c2/linkml_model/model/schema/meta.yaml#L2345

Docs have an Anything page: https://linkml.io/linkml-model/latest/docs/Anything/

But no Any: https://linkml.io/linkml-model/latest/docs/Any

Accordingly W3ID purl for Any does not dereference: https://w3id.org/linkml/Any

But Anything does: https://w3id.org/linkml/Anything

The mappings on that page are similarly ambiguous. So it seems like its an alias but an incomplete/imperfect one?

ddooley commented 5 months ago

Now I presume the LinkML validation scripts still continue with business as usual by testing integers against minimum_value and maximum_value, but now LinkML does not apply that validation to anything other than integers?

sneakers-the-rat commented 4 months ago

Now I presume the LinkML validation scripts still continue with business as usual by testing integers against minimum_value and maximum_value, but now LinkML does not apply that validation to anything other than integers?

it appears to work for any number:

id: https://example.com
name: example

imports:
  - linkml:types

classes:
  Person:
    attributes:
      age:
        range: float
        minimum_value: 5.5
        maximum_value: 10.6
      age_int:
        range: integer
        minimum_value: 10
        maximum_value: 20
      age_str:
        range: string
        minimum_value: "a"
        maximum_value: "f"
>>> from linkml.validator import validate
>>> from pprint import pprint

>>> eg = {'age': 9.5, 'age_int': 15, 'age_str': 'd'}
>>> validate(eg, 'testschema.yaml', 'Person')
ValidationReport(results=[])

>>> eg = {'age': 15.5, 'age_int': 25, 'age_str': 'g'}
>>> report = validate(eg, 'testschema.yaml', 'Person')
>>> pprint(report.results)
[ValidationResult(type='jsonschema validation', severity=<Severity.ERROR: 'ERROR'>, message='15.5 is greater than the maximum of 10.6 in /age', instance={'age': 15.5, 'age_int': 25, 'age_str': 'g'}, instance_index=0, instantiates='Person'),
 ValidationResult(type='jsonschema validation', severity=<Severity.ERROR: 'ERROR'>, message='25 is greater than the maximum of 20 in /age_int', instance={'age': 15.5, 'age_int': 25, 'age_str': 'g'}, instance_index=0, instantiates='Person')]

Generated JSON schema is:

{"$schema": "https://json-schema.org/draft/2019-09/schema",
 "$id": "https://example.com",
 "metamodel_version": "1.7.0",
 "version": null,
 "title": "example",
 "type": "object",
 "additionalProperties": true,
 "$defs": {"Person": {"type": "object",
   "additionalProperties": false,
   "description": "",
   "properties": {"age": {"type": "number", "minimum": 5.5, "maximum": 10.6},
    "age_int": {"type": "integer", "minimum": 10, "maximum": 20},
    "age_str": {"type": "string", "minimum": "a", "maximum": "f"}},
   "title": "Person"}}}

so it allows strings and adds a minimum and maximum value to them even if that doesn't make sense, but otherwise works as expected