manchester¶
Evaluate Manchester syntax
This module compiles restrictions and logical constructs in Manchester
syntax into Owlready2 classes. The main function in this module is
manchester.evaluate()
, see its docstring for usage example.
Pyparsing is used under the hood for parsing.
ManchesterError (EMMOntoPyException)
¶
Raised on invalid Manchester notation.
Source code in ontopy/manchester.py
class ManchesterError(EMMOntoPyException):
"""Raised on invalid Manchester notation."""
evaluate(ontology, expr)
¶
Evaluate expression in Manchester syntax.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
ontology |
Ontology |
The ontology within which the expression will be evaluated. |
required |
expr |
str |
Manchester expression to be evaluated. |
required |
Returns:
Type | Description |
---|---|
Construct |
An Owlready2 construct that corresponds to the expression. |
Examples:
from ontopy.manchester import evaluate from ontopy import get_ontology emmo = get_ontology().load()
restriction = evaluate(emmo, 'hasPart some Atom') cls = evaluate(emmo, 'Atom') expr = evaluate(emmo, 'Atom or Molecule')
Note
Logical expressions (with not
, and
and or
) are supported as
well as object property restrictions. For data properterties are
only value restrictions supported so far.
Source code in ontopy/manchester.py
def evaluate(ontology: owlready2.Ontology, expr: str) -> owlready2.Construct:
"""Evaluate expression in Manchester syntax.
Args:
ontology: The ontology within which the expression will be evaluated.
expr: Manchester expression to be evaluated.
Returns:
An Owlready2 construct that corresponds to the expression.
Example:
>>> from ontopy.manchester import evaluate
>>> from ontopy import get_ontology
>>> emmo = get_ontology().load()
>>> restriction = evaluate(emmo, 'hasPart some Atom')
>>> cls = evaluate(emmo, 'Atom')
>>> expr = evaluate(emmo, 'Atom or Molecule')
Note:
Logical expressions (with `not`, `and` and `or`) are supported as
well as object property restrictions. For data properterties are
only value restrictions supported so far.
"""
# pylint: disable=invalid-name
def _parse_literal(r):
"""Compiles literal to Owlready2 type."""
if r.language:
v = owlready2.locstr(r.string, r.language)
elif r.number:
v = r.number
else:
v = r.string
return v
# pylint: disable=invalid-name,no-else-return,too-many-return-statements
# pylint: disable=too-many-branches
def _eval(r):
"""Recursively evaluate expression produced by pyparsing into an
Owlready2 construct."""
def fneg(x):
"""Negates the argument if `neg` is true."""
return owlready2.Not(x) if neg else x
if isinstance(r, str): # r is atomic, returns its owlready2 repr
return ontology[r]
neg = False # whether the expression starts with "not"
while r[0] == "not":
r.pop(0) # strip off the "not" and proceed
neg = not neg
if len(r) == 1: # r is either a atomic or a parenthesised
# subexpression that should be further evaluated
if isinstance(r[0], str):
return fneg(ontology[r[0]])
else:
return fneg(_eval(r[0]))
elif r.op: # r contains a logical operator: and/or
ops = {"and": owlready2.And, "or": owlready2.Or}
op = ops[r.op]
if len(r) == 3:
return op([fneg(_eval(r[0])), _eval(r[2])])
else:
arg1 = fneg(_eval(r[0]))
r.pop(0)
r.pop(0)
return op([arg1, _eval(r)])
elif r.objProp: # r is a restriction
if r[0] == "inverse":
r.pop(0)
prop = owlready2.Inverse(ontology[r[0]])
else:
prop = ontology[r[0]]
rtype = r[1]
if rtype == "Self":
return fneg(prop.has_self())
r.pop(0)
r.pop(0)
f = getattr(prop, rtype)
if rtype == "value":
return fneg(f(_eval(r)))
elif rtype in ("some", "only"):
return fneg(f(_eval(r)))
elif rtype in ("min", "max", "exactly"):
cardinality = r.pop(0)
return fneg(f(cardinality, _eval(r)))
else:
raise ManchesterError(f"invalid restriction type: {rtype}")
elif r.dataProp: # r is a data property restriction
prop = ontology[r[0]]
rtype = r[1]
r.pop(0)
r.pop(0)
f = getattr(prop, rtype)
if rtype == "value":
return f(_parse_literal(r))
else:
raise ManchesterError(
f"unimplemented data property restriction: "
f"{prop} {rtype} {r}"
)
else:
raise ManchesterError(f"invalid expression: {r}")
grammar = manchester_expression()
return _eval(grammar.parseString(expr, parseAll=True))
manchester_expression()
¶
Returns pyparsing grammar for a Manchester expression.
This function is mostly for internal use.
See also: https://www.w3.org/TR/owl2-manchester-syntax/
Source code in ontopy/manchester.py
def manchester_expression():
"""Returns pyparsing grammar for a Manchester expression.
This function is mostly for internal use.
See also: https://www.w3.org/TR/owl2-manchester-syntax/
"""
# pylint: disable=global-statement,invalid-name,too-many-locals
global GRAMMAR
if GRAMMAR:
return GRAMMAR
# Subset of the Manchester grammar for expressions
# It is based on https://www.w3.org/TR/owl2-manchester-syntax/
# but allows logical constructs within restrictions (like Protege)
ident = pp.Word(pp.alphas + "_:-", pp.alphanums + "_:-", asKeyword=True)
uint = pp.Word(pp.nums)
alphas = pp.Word(pp.alphas)
string = pp.Word(pp.alphanums + ":")
quotedString = (
pp.QuotedString('"""', multiline=True) | pp.QuotedString('"')
)("string")
typedLiteral = pp.Combine(quotedString + "^^" + string("datatype"))
stringLanguageLiteral = pp.Combine(quotedString + "@" + alphas("language"))
stringLiteral = quotedString
numberLiteral = pp.pyparsing_common.number("number")
literal = (
typedLiteral | stringLanguageLiteral | stringLiteral | numberLiteral
)
logOp = pp.one_of(["and", "or"], asKeyword=True)
expr = pp.Forward()
restriction = pp.Forward()
primary = pp.Keyword("not")[...] + (
restriction | ident("cls") | pp.nested_expr("(", ")", expr)
)
objPropExpr = (
pp.Literal("inverse")
+ pp.Suppress("(")
+ ident("objProp")
+ pp.Suppress(")")
| pp.Literal("inverse") + ident("objProp")
| ident("objProp")
)
dataPropExpr = ident("dataProp")
restriction <<= (
objPropExpr + pp.Keyword("some") + expr
| objPropExpr + pp.Keyword("only") + expr
| objPropExpr + pp.Keyword("Self")
| objPropExpr + pp.Keyword("value") + ident("individual")
| objPropExpr + pp.Keyword("min") + uint + expr
| objPropExpr + pp.Keyword("max") + uint + expr
| objPropExpr + pp.Keyword("exactly") + uint + expr
| dataPropExpr + pp.Keyword("value") + literal
)
expr <<= primary + (logOp("op") + expr)[...]
GRAMMAR = expr
return expr