diff --git a/client/Boundaries/Boundaries/DatalogCreator.cs b/client/Boundaries/Boundaries/DatalogCreator.cs index 2f278275..ad3a22f7 100644 --- a/client/Boundaries/Boundaries/DatalogCreator.cs +++ b/client/Boundaries/Boundaries/DatalogCreator.cs @@ -29,4 +29,25 @@ public string CreateBoundaryDatalogRule(string internalComponentLabel, IriRefere dexpi:PipingOrEquipment [?node]. """; } + + + public string CreateConnectedSparqlQuery() + { + return $"select * where {{?s a <{BoundaryGraph}>; ?tag.}}"; + } + public string CreateConnectedDatalogRule(string internalComponentLabel) + { + return $$""" + <{{BoundaryGraph}}> [?node] :- + rdfs:label [?internal, "{{internalComponentLabel}}"], + imf:connectedTo [?internal, ?node], + dexpi:PipingOrEquipment [?node]. + + <{{BoundaryGraph}}> [?node] :- + <{{BoundaryGraph}}> [?node1], + imf:connectedTo [?node1, ?node], + dexpi:PipingOrEquipment [?node], + NOT dexpi:Equipment [?node1]. + """; + } } \ No newline at end of file diff --git a/client/Boundaries/Boundaries/DexpiApi.cs b/client/Boundaries/Boundaries/DexpiApi.cs new file mode 100644 index 00000000..38a28f09 --- /dev/null +++ b/client/Boundaries/Boundaries/DexpiApi.cs @@ -0,0 +1,42 @@ +using IriTools; + +namespace Boundaries; + +public static class DexpiApi{ + public static async Task GetCommissioningPackage(string internalComponentLabel, IriReference[] borderComponentIris, string dexpiFilePath) + { + var datalogCreator = new DatalogCreator(); + var datalog = datalogCreator.CreateBoundaryDatalogRule(internalComponentLabel, borderComponentIris); + var conn = RdfoxApi.GetDefaultConnectionSettings(); + await RdfoxApi.LoadDatalog(conn, datalog); + + var data = File.ReadAllText(dexpiFilePath); + await RdfoxApi.LoadData(conn, data); + + var queryString = datalogCreator.CreateCommissioningSparqlQuery(); + var result = await RdfoxApi.QuerySparql(conn, queryString); + + await RdfoxApi.DeleteData(conn, data); + await RdfoxApi.DeleteDatalog(conn, datalog); + return result; + } + + + public static async Task GetConnectedEquipment(string internalComponentLabel, string dexpiFilePath) + { + var datalogCreator = new DatalogCreator(); + var datalog = datalogCreator.CreateConnectedDatalogRule(internalComponentLabel); + var conn = RdfoxApi.GetDefaultConnectionSettings(); + await RdfoxApi.LoadDatalog(conn, datalog); + + var data = File.ReadAllText(dexpiFilePath); + await RdfoxApi.LoadData(conn, data); + + var queryString = datalogCreator.CreateConnectedSparqlQuery(); + var result = await RdfoxApi.QuerySparql(conn, queryString); + + await RdfoxApi.DeleteData(conn, data); + await RdfoxApi.DeleteDatalog(conn, datalog); + return result; + } +} \ No newline at end of file diff --git a/client/Boundaries/Boundaries/Program.cs b/client/Boundaries/Boundaries/Program.cs index 8176c249..fe1f70a0 100644 --- a/client/Boundaries/Boundaries/Program.cs +++ b/client/Boundaries/Boundaries/Program.cs @@ -6,12 +6,13 @@ internal class Program { private static async Task Main(string[] args) { - if (args.Length < 3) + if (args.Length < 2) { Console.WriteLine( "Usage \"dotnet run filename-for-dexpi-in-rdf \"label-of-internal-componenet\" iri-of-border-component ... iri-of-border-component "); Console.WriteLine( - "For example \"dotnet run ../../../rml/pandid.trig \"T4750\" https://assetid.equinor.com/plantx#Nozzle-12 https://assetid.equinor.com/plantx#Nozzle-8 https://assetid.equinor.com/plantx#PlateHeatExchanger-1 https://assetid.equinor.com/plantx#ReciprocatingPump-1"); + "For finding a commissioning package from boundary use f.ex. \"dotnet run ../../../rml/pandid.trig \"T4750\" https://assetid.equinor.com/plantx#Nozzle-12 https://assetid.equinor.com/plantx#Nozzle-8 https://assetid.equinor.com/plantx#PlateHeatExchanger-1 https://assetid.equinor.com/plantx#ReciprocatingPump-1\""); + Console.WriteLine("For finding directly connected equipemnt use f.ex. \"dotnet run ../../../rml/pandid.trig \"P4711\""); return; } @@ -25,21 +26,11 @@ private static async Task Main(string[] args) } var borderComponentIris = args.Skip(2).Select(iri => new IriReference(iri)).ToArray(); - var datalogCreator = new DatalogCreator(); - var datalog = datalogCreator.CreateBoundaryDatalogRule(internalComponentLabel, borderComponentIris); - var conn = RdfoxApi.GetDefaultConnectionSettings(); - await RdfoxApi.LoadDatalog(conn, datalog); - - var data = File.ReadAllText(dexpiFilePath); - await RdfoxApi.LoadData(conn, data); - - var queryString = datalogCreator.CreateCommissioningSparqlQuery(); - var result = await RdfoxApi.QuerySparql(conn, queryString); + var result = borderComponentIris.Any() ? + await DexpiApi.GetCommissioningPackage(internalComponentLabel, borderComponentIris, dexpiFilePath) + : await DexpiApi.GetConnectedEquipment(internalComponentLabel, dexpiFilePath); Console.WriteLine("Commissioning package:"); Console.WriteLine(result); - - await RdfoxApi.DeleteData(conn, data); - await RdfoxApi.DeleteDatalog(conn, datalog); } } \ No newline at end of file diff --git a/client/Boundaries/README.md b/client/Boundaries/README.md index 4ad09ff0..940d1e6e 100644 --- a/client/Boundaries/README.md +++ b/client/Boundaries/README.md @@ -8,4 +8,6 @@ Start a rdfox server from the folder [../../rdfox/](../../rdfox) with the follow RDFox sandbox ../../rdfox boundaries ``` -Then run `dotnet run` and follow instructions +Then run `dotnet run` and follow instructions. + +There are two "modes". In both modes you must give an rdf file and the tag of an equipment. If you only give this, it finds all directly connected Equipment. If you also give a list of boundary IRIs it will give all components inside those boundary. Inside is defined as the same side as the equipment with the tag. diff --git a/datalog/surrounding.datalog b/datalog/surrounding.datalog new file mode 100644 index 00000000..0f61c32f --- /dev/null +++ b/datalog/surrounding.datalog @@ -0,0 +1,13 @@ +prefix data: + + +data:connectedEquipment [?node] :- + rdfs:label [?internal, "P4712"], + imf:connectedTo [?internal, ?node], + dexpi:PipingOrEquipment [?node]. + +data:connectedEquipment [?node] :- + data:connectedEquipment [?node1], + imf:connectedTo [?node1, ?node], + dexpi:PipingOrEquipment [?node], + NOT dexpi:Equipment [?node1]. diff --git a/rdfox/README.md b/rdfox/README.md index 03c4cb5d..a7e8fb35 100644 --- a/rdfox/README.md +++ b/rdfox/README.md @@ -5,7 +5,7 @@ Run the rml mapper scripts as described in [../rml/README.md](../rml/README.md) This will create a file [../rml/pandid.trig](../rml/pandid.trig) -## Running the example +## Running the example commmissioning package In this folder, run ``` RDFox sandbox . dexpi @@ -32,3 +32,12 @@ To run a server for use with [Boundaries cli](../client/Boundaries/Boundaries.sl RDFox sandbox . boundaries ``` This will load ontology and prefixes, but no data. + +## Running the pump connections example +In this folder, run +``` +RDFox sandbox . connected +``` +This will load ontology and datalog rules, and in addition load the data in [../rml/pandid.trig](../rml/pandid.trig) + +There are a lot of warnings about axioms in the IMF ontology that cannot be handled. This can safely be ignored. Other warnings and errors should be checked, especially if the last output is not the expected commissioning package output diff --git a/rdfox/commit-procedure.sparql b/rdfox/commit-procedure.sparql index 5809779a..cd630b0e 100644 --- a/rdfox/commit-procedure.sparql +++ b/rdfox/commit-procedure.sparql @@ -6,3 +6,9 @@ INSERT { TT SHACL_DN { schema:shacl ?s ?p ?o} . FILTER(?p IN (sh:sourceShape, sh:resultMessage, sh:value)) } + +INSERT { + ?s a . +} WHERE { + ?s a owl:Nothing. +} diff --git a/rdfox/connected.rdfox b/rdfox/connected.rdfox new file mode 100644 index 00000000..bfbd84d9 --- /dev/null +++ b/rdfox/connected.rdfox @@ -0,0 +1,9 @@ +boundaries.rdfox + +import ../datalog/surrounding.datalog +import +p "../rml/pandid.trig" + +endpoint start + +set output out +select * where {?s a data:connectedEquipment; ?tag.} \ No newline at end of file diff --git a/rml/element-map.rml.ttl b/rml/element-map.rml.ttl index 7127ca88..4aff8dfd 100644 --- a/rml/element-map.rml.ttl +++ b/rml/element-map.rml.ttl @@ -36,12 +36,4 @@ rr:constant "http://ns.imfid.org/imf#productAspect" ; rr:termType rr:IRI ]; -], - - [ - rr:predicate "http://ns.imfid.org/imf#partOf"; - rr:objectMap [ - rr:template "https://assetid.equinor.com/plantx#{../@ID}"; - rr:termType rr:IRI - ]; ]. \ No newline at end of file