How to disable inference in hermiT - owl-api

I am using OWL-Api and hermiT reasoner, while trying to retrieve the partOf subClasses using hermiT, it give back the right result, so the partOf subclasses, but it also give back the inferenced subclasses (which i don't need).
This is the function used to retrieve the partOf subClasses:
//ricerca delle classi che hanno come parti quella attuale
System.out.println("Questa classe è parte di: ");
OWLClassExpression domain = df.getOWLObjectIntersectionOf((Stream<? extends OWLClassExpression>) ontologia.objectPropertyDomainAxioms(partOf));
NodeSet<OWLClass> subClassesInDomain = hermit.getSubClasses(domain, false);
if(subClassesInDomain.isEmpty()) {
System.out.println("\tQuesta classe non è parte di nessun'altra");
}
else {
for(Node<OWLClass> parteDi : subClassesInDomain) {
OWLClass classe2 = parteDi.getRepresentativeElement();
System.out.println("\t"+ classe2.getIRI().getFragment());;
}
}
In this image, it is provided the actual result of the operation.
given result
In this, it is shown the result i need.
wanted result
Is there a way to disable hermiT inference engine only for this operation?

hermit.getSubClasses(domain, false);
Change this to
hermit.getSubClasses(domain, true);
To retrieve only direct subclasses.

Related

EOF Error Parsing Manchester Syntax in OWL-API

I have an API that receive a JSON document with classes, properties and axioms of an ontology. The file looks like this:
{
"id": "myontologyid",
"outformat": "OWL",
"ontoclass": ["Person", "Man", "Woman", "Animal", "Rational", "Arm"],
"ontoaxioms": ["Man subClassOf (Person)", "Person EquivalentTo: (Man OR Woman)", "hasBrother max 2 xsd:integer"],
"ontoproperties": ["hasPart", "isBrotherOf", "hasBrother"]
}
The ontoaxioms key is an array with all the axioms of the ontology. The values of this array MUST be in Manchester syntax as I will use the ManchesterOWLSyntaxParser to parse.
When I try to parse this code, I get the following error on hasBrother max 2 xsd:integer axiom:
[apache-tomcat-8.5.69-2]: org.semanticweb.owlapi.manchestersyntax.renderer.ParserException: Encountered |EOF| at line 1 column 29. Expected one of:
SubClassOf:
or
and
DisjointWith:
EquivalentTo:
I believe the Manchester syntax is incorrect. But I couldn't find any reference or documentation of OWL-API which indicates how to use it. Is there some?
Below is part of my code which tries to parse the axioms:
ManchesterOWLSyntaxParserImpl parser = (ManchesterOWLSyntaxParserImpl) OWLManager.createManchesterParser();
parser.setOWLEntityChecker(entityChecker);
try {
for (int i = 0; i < this.axiomas.length(); i++) {
parser.setStringToParse(this.axiomas.getString(i));
owlOntology.addAxiom(parser.parseAxiom());
}
} catch (Exception e) {
System.out.print(e.toString());
return null;
}
The questions are:
How to solve this EOF error?
How to insert correctly Manchester Syntax into OWL-API?
Where can I find some documentation on how to use Manchester Syntax to parse ontologies?
Many thanks in advance.
Your use of OWLAPI classes appears correct. The problem with the input that something else is expected to follow, i.e., that's not a full axiom.
Is the intent to say that hasBrother can only appear twice for an individual and has integer range?
As it happens, there's a unit test in the OWLAPI contract module that uses this string as input for parsing:
String in = "p max 1 owl:real";
ManchesterOWLSyntaxParser parser = OWLManager.createManchesterParser();
parser.setStringToParse(in);
OWLClassExpression cl = parser.parseClassExpression();
The string has the same format as what you're trying to parse, and it gives a class expression, not an axiom - specifically, a qualified max cardinality restriction for a data property. This can be the superclass or the subclass in a subclass axiom, for example, but the rest of the axiom is not present.

SuiteCRM invoice and ticket number

how can I make an unique number for invoice and ticketing system, something like
for tickets: ST-{yymm}-0000001
for Invoice: IN-{yymm}-0000001
Thank you
I recomend you create first a field that will be use to generate the code.
Once you have the field you have different options.
1- Assign that column in the database directly as autonumeric
2- Use a Logic Hook before_save that will be calculating the code in each save. For example:
<?php
//prevents directly accessing this file from a web browser
if(!defined('sugarEntry') ||!sugarEntry) die('Not A Valid Entry Point');
class CrearCodigoAutonumerico
{
public function CrearCodigoAutonumerico(&$bean, $event, $arguments)
{
// Si el campo está vacío...
if(empty($bean->codigo_c)) {
// Obtener el último código asignado
$db = DBManagerFactory::getInstance();
$query = "SELECT codigo_c
FROM <table_module>
ORDER BY codigo_c DESC LIMIT 1";
$result = $db->getOne($query, true);
$ultimo_codigo = $result;
// Calcular y asignar el nuevo código
$bean->codigo_c = $ultimo_codigo + 1;
}
}
}
Once you have this, you can create one more Logic Hook before save that constructs the name as you need it.

LDAP Ambiguous Name Resolution (ANR) equivalent on Microsoft Graph

I'm building a tool that can target both on-prem Active Directory and Azure AD that, amongst other things, searches user objects.
For on-prem, I can do an LDAP search using ambiguous name resolution with a query like this:
(anr=searchstring*)
Is there an equivalent filter string for the Microsoft Graph?
The equivalent to {string}* is the OData startsWith({property},'{string}') Filter parmeter:
/v1.0/users?$filter=startsWith(displayName,'Adele')
Note that the Microsoft Graph currently only supports a subset of OData query parameters, particularly when it comes to AAD filters:
The following $filter operators are not supported for Azure AD resources: ne, gt, ge, lt, le, and not.
Also, Microsoft Graph does not support contains or endswith string functions in any workload.
You can try test your queries this using Graph Explorer.
Okay, so after some trial & error, I managed to replicate Ambiguous Name Resolution using the filter syntax. It's not an exact match because not all attributes are searchable, but I guess it will have to do.
Here's my helper class I created for the job.
public static class QueryHelper
{
public static string GenerateAnrFilter(string query)
{
if (string.IsNullOrEmpty(query))
return query;
var tokens = query.Split(' ');
var filterClauses = new List<string>();
if (tokens.Count() > 1)
{
var otherTokens = string.Join(" ", tokens.Skip(1));
string nameFilter1 = $"({generateFilterClause(tokens[0], "givenName")} and {generateFilterClause(otherTokens, "surname")})";
filterClauses.Add(nameFilter1);
string nameFilter2 = $"({generateFilterClause(otherTokens, "givenName")} and {generateFilterClause(tokens[0], "surname")})";
filterClauses.Add(nameFilter2);
filterClauses.Add(generateFilterClause(query, "displayName"));
//filterClauses.Add(generateFilterClause(query, "officeLocation")); // not supported for filter
filterClauses.Add(generateMultiValueFilterClause(query, "proxyAddresses"));
filterClauses.Add(generateFilterClause(query, "userPrincipalName"));
//filterClauses.Add(generateFilterClause(query, "onPremisesSamAccountName")); // not supported for filter
filterClauses.Add(generateFilterClause(query, "mail"));
filterClauses.Add(generateFilterClause(query, "mailNickName"));
}
else
{
filterClauses.Add(generateFilterClause(query, "displayName"));
filterClauses.Add(generateFilterClause(query, "givenName"));
filterClauses.Add(generateFilterClause(query, "surname"));
//filterClauses.Add(generateFilterClause(query, "officeLocation")); // not supported for filter
filterClauses.Add(generateMultiValueFilterClause(query, "proxyAddresses"));
filterClauses.Add(generateFilterClause(query, "userPrincipalName"));
//filterClauses.Add(generateFilterClause(query, "onPremisesSamAccountName")); // not suported for filter
filterClauses.Add(generateFilterClause(query, "mail"));
filterClauses.Add(generateFilterClause(query, "mailNickName"));
}
var fullQuery = string.Join(" or ", filterClauses);
return fullQuery;
}
private static string generateMultiValueFilterClause(string query, string attributeName)
{
return $"{attributeName}/any(a:startswith(a,'{query}'))";
}
private static string generateFilterClause(string query, string attributeName)
{
return $"startsWith({attributeName},'{query}')";
}
}

Find all IRIs used in ontology which are not entities?

Is there any straight-forward way in OWLAPI to find all IRIs used in an ontology which have not been identified as Entities i.e. have not been declared and are not used in a context which would allowed them to be identified as a specific entity type? Hoping for something analogous to OWLOntology.signature(), didn't see anything.
An example of that situation appears in BFO 2.0 (http://purl.obolibrary.org/obo/bfo.owl) :
<rdf:Description rdf:about="http://example.com/bfo-spec-label">
<obo:IAO_0000119>Person:Alan Ruttenberg</obo:IAO_0000119>
</rdf:Description>
Here http://example.com/bfo-spec-label is just a "bare" IRI of unknown entity type and thus does not appear in the ontology signature.
Couldn't find any elegant way to find all of these bare IRI's but these can be found by looking in all places they could possibly occur. A simple method would look like:
private List findBareIRIs(OWLOntology onto) {
List bares = new ArrayList();
// bare IRIs can occur as AnnotationSubjects, AnnotationObjects or the domain/range of AnnotationProperties
List<OWLAnnotationAssertionAxiom> asserts = OWLAPIStreamUtils.asList(onto.axioms(AxiomType.ANNOTATION_ASSERTION));
List<OWLAnnotationPropertyDomainAxiom> domains = OWLAPIStreamUtils.asList(onto.axioms(AxiomType.ANNOTATION_PROPERTY_DOMAIN));
List<OWLAnnotationPropertyRangeAxiom> ranges = OWLAPIStreamUtils.asList(onto.axioms(AxiomType.ANNOTATION_PROPERTY_RANGE));
//check the subject and values of each AnnotationAsertion
for (OWLAnnotationAssertionAxiom ax : asserts) {
OWLAnnotationSubject subj = ax.getSubject();
OWLAnnotationValue value = ax.getValue();
if (subj.isIRI()) {
bares.add((IRI) subj);
}
if (value.isIRI()) {
bares.add((IRI) value);
}
}
// check the domain and ranges of each AnnotationProperty
for (OWLAnnotationPropertyDomainAxiom ax : domains) {
bares.add(ax.getDomain());
}
for (OWLAnnotationPropertyRangeAxiom ax : ranges) {
bares.add(ax.getRange());
}
return bares;
}

CakePHP, GET Parameters and routing

I am fairly new to cakephp but I have a question relating to urls and parameters. I would like to be able to have a url that looks like a standard url e.g:
http://www.mysite.com/controller/myaction?arg=value&arg2=val
I would like that url to map to an action in my controller as follows:
function myaction($arg = null, $arg2 = null)
{
// do work
}
I realize that cakephp has routing as described here, however, honestly this seems over engineered and results in a url string that is nonstandard.
In my current situation the url is being generated and invoked by an external (billing) system that knows nothing about cake and doesn't support the cake url format.
You can have your URL in any form. It's just CakePHP allows you to retrieve the variable passed through GET from the variable $this->params['url']
function myaction()
{
if(isset($this->params['url']['arg']))
$arg = $this->params['url']['arg'];
if(isset($this->params['url']['arg2']))
$arg2 = $this->params['url']['arg2'];
}
Solution in AppController for CakePHP 2.x
class AppController extends Controller {
....
/***
* Recupera los Named envias por URL
* si es null $key emtraga el array completo de named
*
* #param String $key
*
* #return mixed
*/
protected function getNamed($key=null){
// Is null..?
if(is_string($key)==true){
// get key in array
return Hash::get($this->request->param('named'), $key);
}else{
// all key in array
return $this->request->param('named');
}
}
...
}
I have a similar problem. Not because I have an external system, but because I don't like to put all parameters into the URL-path. In my example, I have some search queries that are assembled and passed to the controller. IMHO, these queries should be GET parameters and not part of the URL-path.
One advantage of using GET parameters is that the order of the given parameters is not important, in contrast to passing params via the URL path.
To solve this problem in a generic way, I'm replacing all method arguments with the value of the GET-param, if one with the same name is given:
class MyController extends AppController
{
function test($var1 = null, $var2 = "content2")
{
foreach (get_defined_vars() as $key => $value) {
if (isset($this->params['url'][$key])) {
$getvalue = $this->params['url'][$key];
$$key = $getvalue;
CakeLog::write("debug", "Setting:$key to $getvalue");
}
}
CakeLog::write("debug", print_r(get_defined_vars(), true));
}
}
Now I can access this controller method and pass parameters via GET like this:
http://myapp/mycontroller/test?var1=foo&var2=bar

Resources