# Getting Started with Corese-Core This tutorial shows how to use the Corese-Core library through simple examples of its main features. We assume basic knowledge of Java programming and the Semantic Web. - The first section describes how to create, load, and export a Graph. - The second section shows how to query a graph using [SPARQL](https://www.w3.org/TR/sparql11-query/). - The third section details how to validate a graph using the [Shapes Constraint Language (SHACL)](https://www.w3.org/TR/shacl/). - The fourth section shows how to transform a graph using the extension language [SPARQL Template Transformation Language (STTL)](https://files.inria.fr/corese/doc/sttl.html). - The fifth section details how to apply a set of rules on a graph using the [SPARQL Rule](https://files.inria.fr/corese/doc/rule.html) extension language. - Finally, the sixth section describes how to define and use functions with the [LDScript](https://files.inria.fr/corese/doc/ldscript.html) extension language. ## **1. Installation** Installation instructions are available on the [installation page](../install.md). ## **2. Graph** This section describes how to create a graph manually, load a graph from a file, and serialize a graph to a file. ### **2.1. Build a Graph Programmatically** The example below shows how to create the following RDF graph: ```mermaid graph LR; classDef IRI fill:#FEAE65,stroke-width:0px classDef DT fill:#FEFEFE,stroke-width:0px iri:EdithPiaf(["ex:EdithPiaf"]) iri:Singer(["ex:Singer"]) dt:Edith(["''Edith''"]) dt:Piaf(["''Piaf''"]) class iri:EdithPiaf,iri:Singer IRI class dt:Edith,dt:Piaf DT iri:EdithPiaf--rdf:type-->iri:Singer; iri:EdithPiaf--ex:firstName-->dt:Edith; iri:EdithPiaf--ex:lastName-->dt:Piaf; ``` This graph represents three RDF statements: - Edith Piaf is a singer. - Edith Piaf's first name is Edith. - Edith Piaf's last name is Piaf. ```java import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.logic.RDF; public class Example { public static void main(String[] args) { // Define the namespace 'ex' String ex = "http://example.org/"; // Create a new empty Graph Graph graph = Graph.create(); // Create and add IRIs to the Graph Node edithPiafIRI = graph.addResource(ex + "EdithPiaf"); Node singerIRI = graph.addResource(ex + "Singer"); // Create and add properties to the Graph Node rdfTypeProperty = graph.addProperty(RDF.TYPE); Node firstNameProperty = graph.addProperty(ex + "firstName"); Node lastNameProperty = graph.addProperty(ex + "lastName"); // Create and add literals to the Graph Node edithLiteral = graph.addLiteral("Edith"); Node piafLiteral = graph.addLiteral("Piaf"); // Add statements to the graph graph.addEdge(edithPiafIRI, rdfTypeProperty, singerIRI); graph.addEdge(edithPiafIRI, firstNameProperty, edithLiteral); graph.addEdge(edithPiafIRI, lastNameProperty, piafLiteral); } } ``` ### **2.2. Load a Graph from a File** This example shows how to load a graph from a file. ```java import fr.inria.corese.core.api.Loader; import fr.inria.corese.core.load.Load; import fr.inria.corese.core.load.LoadException; public class Example { public static void main(String[] args) throws LoadException { // Create a new empty Graph Graph graph = Graph.create(); // Create loader and parse file Load loader = Load.create(graph); loader.parse("input_graph_file.ttl", Loader.format.TURTLE_FORMAT); } } ``` Corese Loader supports the following formats: - RDF/XML (`Loader.format.RDFXML_FORMAT`) - Turtle (`Loader.format.TURTLE_FORMAT`) - TriG (`Loader.format.TRIG_FORMAT`) - JSON-LD (`Loader.format.JSONLD_FORMAT`) - N-Triples (`Loader.format.NT_FORMAT`) - N-Quads (`Loader.format.NQUADS_FORMAT`) - RDFa (`Loader.format.RDFA_FORMAT`) ### **2.3. Export a Graph to a File** This example shows how to serialize a graph into a file in Turtle format. ```java import java.io.FileWriter; import java.io.IOException; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.print.ResultFormat; import fr.inria.corese.core.sparql.api.ResultFormatDef; public class Example { public static void main(String[] args) throws IOException { // Create a new empty Graph Graph graph = Graph.create(); // Add some triples to the graph String ex = "http://example.org/"; Node edithPiafIRI = graph.addResource(ex + "EdithPiaf"); Node firstNameProperty = graph.addProperty(ex + "firstName"); Node edithLiteral = graph.addLiteral("Edith"); graph.addEdge(edithPiafIRI, firstNameProperty, edithLiteral); // Create exporter ResultFormat exporter = ResultFormat.create(graph, ResultFormatDef.format.TURTLE_FORMAT); String result = exporter.toString(); // Write result to a file try (FileWriter writer = new FileWriter("output_graph.ttl")) { writer.write(result); } } } ``` Corese can serialize graphs into the following formats: - RDF/XML (`ResultFormatDef.format.RDF_XML_FORMAT`) - Turtle (`ResultFormatDef.format.TURTLE_FORMAT`) - TriG (`ResultFormatDef.format.TRIG_FORMAT`) - JSON-LD (`ResultFormatDef.format.JSONLD_FORMAT`) - N-Triples (`ResultFormatDef.format.NTRIPLES_FORMAT`) - N-Quads (`ResultFormatDef.format.NQUADS_FORMAT`) - Canonical RDF SHA-256 (`ResultFormatDef.format.RDFC10_FORMAT`) - Canonical RDF SHA-384 (`ResultFormatDef.format.RDFC10_SHA384_FORMAT`) ## **3. SPARQL Queries** This section describes how to query a graph using [SPARQL](https://www.w3.org/TR/sparql11-query/) in Corese. ### **3.1. Executing a SPARQL SELECT Query** This example shows how to execute a SPARQL `SELECT` query and retrieve results. ```java import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.print.ResultFormat; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.exceptions.EngineException; public class Example { public static void main(String[] args) throws EngineException { // Create a new empty Graph Graph graph = Graph.create(); // Add some triples to the graph String ex = "http://example.org/"; Node edithPiafIRI = graph.addResource(ex + "EdithPiaf"); Node firstNameProperty = graph.addProperty(ex + "firstName"); Node edithLiteral = graph.addLiteral("Edith"); graph.addEdge(edithPiafIRI, firstNameProperty, edithLiteral); // Load and execute SPARQL query QueryProcess exec = QueryProcess.create(graph); Mappings map = exec.query("select * where { ?s ?p ?o }"); // Print results in Markdown format System.out.println(ResultFormat.create(map, ResultFormat.format.CSV_FORMAT).toString()); } } ``` Other supported formats: ```java ResultFormat.format.XML_FORMAT ResultFormat.format.JSON_FORMAT ResultFormat.format.CSV_FORMAT ResultFormat.format.TSV_FORMAT ResultFormat.format.MARKDOWN_FORMAT ``` ### 3.2. SPARQL ASK Query This example shows how to execute a SPARQL `ASK` query and print results. ```java import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.exceptions.EngineException; public class Example { public static void main(String[] args) throws EngineException { // Create a new empty Graph Graph graph = Graph.create(); // Add some triples to the graph String ex = "http://example.org/"; Node edithPiafIRI = graph.addResource(ex + "EdithPiaf"); Node firstNameProperty = graph.addProperty(ex + "firstName"); Node edithLiteral = graph.addLiteral("Edith"); graph.addEdge(edithPiafIRI, firstNameProperty, edithLiteral); // Load and execute SPARQL query QueryProcess exec = QueryProcess.create(graph); Mappings map = exec.query("PREFIX ex: SELECT ?x WHERE { ex:EdithPiaf ex:firstName ?x }"); // Print boolean result // If the mapping is empty, the result is false; otherwise, it is true. System.out.println(!map.isEmpty()); } } ``` ### **3.3. SPARQL CONSTRUCT Query** This example shows how to execute a SPARQL `CONSTRUCT` query and retrieve results. ```java import fr.inria.corese.core.api.Loader; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.load.Load; import fr.inria.corese.core.print.ResultFormat; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.exceptions.EngineException; public class Example { public static void main(String[] args) throws EngineException { // Create a new empty Graph Graph graph = Graph.create(); // Add some triples to the graph Load loader = Load.create(graph); loader.parse("input_graph_file.ttl", Loader.format.TURTLE_FORMAT); // Load and execute SPARQL query QueryProcess exec = QueryProcess.create(graph); Mappings map = exec.query(""" prefix foaf: prefix vcard: construct { ?person vcard:FN ?name } where { ?person foaf:name ?name. } """); // Get result graph Graph resultGraph = (Graph) map.getGraph(); // Print results in TriG format System.out.println(ResultFormat.create(resultGraph, ResultFormat.format.TRIG_FORMAT).toString()); } } ``` Other supported formats: ```java ResultFormat.format.RDF_XML_FORMAT ResultFormat.format.TURTLE_FORMAT ResultFormat.format.TRIG_FORMAT ResultFormat.format.JSONLD_FORMAT ResultFormat.format.NTRIPLES_FORMAT ResultFormat.format.NQUADS_FORMAT ResultFormat.format.RDFC10_FORMAT ResultFormat.format.RDFC10_SHA384_FORMAT ``` ### **3.4. SPARQL UPDATE Query** This example shows how to execute a SPARQL `UPDATE` query. ```java import fr.inria.corese.core.api.Loader; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.load.Load; import fr.inria.corese.core.print.ResultFormat; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.exceptions.EngineException; public class Example { public static void main(String[] args) throws EngineException { // Create a new empty Graph Graph graph = Graph.create(); // Add some triples to the graph Load loader = Load.create(graph); loader.parse("input_graph_file.ttl", Loader.format.TURTLE_FORMAT); // Load and execute SPARQL query QueryProcess exec = QueryProcess.create(graph); exec.query(""" PREFIX foaf: PREFIX vcard: INSERT { ?person vcard:FN ?name } WHERE { ?person foaf:name ?name. } """); // Print updated graph in Turtle format System.out.println(ResultFormat.create(graph, ResultFormat.format.TURTLE_FORMAT).toString()); } } ``` Other supported formats: ```java ResultFormat.format.RDF_XML_FORMAT ResultFormat.format.TURTLE_FORMAT ResultFormat.format.TRIG_FORMAT ResultFormat.format.JSONLD_FORMAT ResultFormat.format.NTRIPLES_FORMAT ResultFormat.format.NQUADS_FORMAT ResultFormat.format.RDFC10_FORMAT ResultFormat.format.RDFC10_SHA384_FORMAT ``` ## **4. Shapes Constraint Language (SHACL)** This section shows how to validate a graph using [SHACL](https://www.w3.org/TR/shacl/). ```java import fr.inria.corese.core.load.Load; import fr.inria.corese.core.load.LoadException; import fr.inria.corese.core.print.ResultFormat; import fr.inria.corese.core.shacl.Shacl; import fr.inria.corese.core.sparql.api.ResultFormatDef; import fr.inria.corese.core.sparql.exceptions.EngineException; public class Example { public static void main(String[] args) throws LoadException, EngineException { // Load data graph Graph dataGraph = Graph.create(); Load loader = Load.create(dataGraph); loader.parse("data.ttl"); // Load shape graph Graph shapeGraph = Graph.create(); loader = Load.create(shapeGraph); loader.parse("shapes.ttl"); // Validate the data Shacl shacl = new Shacl(dataGraph, shapeGraph); Graph result = shacl.eval(); // Print results ResultFormat exporter = ResultFormat.create(result, ResultFormatDef.format.TURTLE_FORMAT); System.out.println(exporter.toString()); } } ``` **Input graph file path:** ```turtle @prefix ex: . @prefix rdf: . ex:Alice ex:ssn "987-65-4323" ; ex:worksFor ex:Haribo, ex:KitKat ; rdf:type ex:Person . ex:Bob ex:ssn "124-35-6789" ; ex:worksFor ex:Twitch ; rdf:type ex:Person . ex:Calvin ex:ssn "648-67-6545" ; ex:worksFor ex:UntypedCompany ; rdf:type ex:Person . ex:Haribo rdf:type ex:Company . ex:KitKat rdf:type ex:Company . ex:Twitch rdf:type ex:Company . ex:UntypedCompany rdf:type ex:Company . ``` **Input shape file path:** ```turtle @prefix sh: . @prefix xsd: . @prefix ex: . @prefix rdf: . ex:PersonShape a sh:NodeShape ; sh:targetClass ex:Person ; sh:property [ sh:path ex:ssn ; sh:maxCount 1 ; sh:datatype xsd:string ; sh:pattern "^\\d{3}-\\d{2}-\\d{4}$" ; ] ; sh:property [ sh:path ex:worksFor ; sh:class ex:Company ; sh:nodeKind sh:IRI ; ] ; sh:closed true ; sh:ignoredProperties ( rdf:type ) . ``` **Result:** ```turtle @prefix xsh: . @prefix sh: . [a sh:ValidationReport ; sh:conforms true] . ``` ## 5. SPARQL Template Transformation Language (STTL) This section shows how to transform a graph using a subset of the [SPARQL Template Transformation Language (STTL)](https://files.inria.fr/corese/doc/sttl.html). ### 5.1. Transform a graph into a visual HTML format This example details how to load a data graph from a file, transform it into a visual HTML format, and export the result to a file. ```java import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.load.Load; import fr.inria.corese.core.load.LoadException; import fr.inria.corese.core.print.ResultFormat; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.exceptions.EngineException; public class Example { public static void main(String[] args) throws LoadException, EngineException, IOException { // Open template file Path path = Path.of("input template file path"); String sttl_query = Files.readString(path, StandardCharsets.UTF_8); // Load data graph Graph dataGraph = Graph.create(); Load ld = Load.create(dataGraph); ld.parse("input graph file path"); // Apply STTL query QueryProcess exec = QueryProcess.create(dataGraph); Mappings map = exec.query(sttl_query); // Export result ResultFormat result_xml = ResultFormat.create(map); result_xml.write("output file path"); } } ``` **Input template file:** ```rq template { format { "\n\n\n\t\n%s\t
\n\n\n" group { format { "\t\t\n\t\t\t%s\n\t\t\t%s\n\t\t\t%s\n\t\t\n" ?s ?p ?o } } } } where { ?s ?p ?o } order by ?s ?p ?o ``` **Result:** ```html
http://example.org/EdithPiaf http://example.org/firstName Edith
http://example.org/EdithPiaf http://example.org/lastName Piaf
http://example.org/EdithPiaf http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://example.org/Singer
``` | ?s | ?p | ?o | | ------------------------------ | ------------------------------------------------- | --------------------------- | | | | Edith | | | | Piaf | | | | | ## 6. **SPARQL Rule** This section details how to apply a set of rules on a graph using the [SPARQL Rule extension language](https://files.inria.fr/corese/doc/rule.html). ### 6.1. Load rules from a file The example below shows the application of two rules (symmetry and transitivity) on a simple graph. ```java import fr.inria.corese.core.load.Load; import fr.inria.corese.core.load.LoadException; import fr.inria.corese.core.load.RuleLoad; import fr.inria.corese.core.rule.RuleEngine; import fr.inria.corese.core.sparql.exceptions.EngineException; public class Example { public static void main(String[] args) throws LoadException, EngineException { // Create and load data in a graph Graph dataGraph = Graph.create(); Load dataLoader = Load.create(dataGraph); dataLoader.parse("input graph file path"); // Create and load rules into a rules engine RuleEngine ruleEngine = RuleEngine.create(dataGraph); RuleLoad ruleLoader = RuleLoad.create(ruleEngine); ruleLoader.parse("input rules file path.rul"); // Apply rules on the graph ruleEngine.process(); } } ``` **Original graph:** ```mermaid graph LR; classDef IRI fill:#FEAE65,stroke-width:0px iri:alice(["ex:Alice"]) iri:bob(["ex:Bob"]) iri:camille(["ex:Camille"]) iri:daniel(["ex:Daniel"]) iri:elise(["ex:Elise"]) class iri:alice,iri:bob,iri:camille,iri:daniel,iri:elise IRI iri:alice--ex:friend-->iri:bob; iri:bob--ex:friend-->iri:camille; iri:daniel--ex:isMarriedTo-->iri:elise; ``` **Rules file:** - Symmetry: `if X➝Y then Y➝X` - Transitivity: `if X➝Y➝Z then X➝Z` ```xml construct { ?x ?p ?z } where { ?p a owl:TransitiveProperty . ?x ?p ?y . ?y ?p ?z } ]]> construct { ?y ?p ?x } where { ?p a owl:SymmetricProperty . ?x ?p ?y . } ]]> ``` **Result graph:** ```mermaid graph LR; classDef IRI fill:#FEAE65,stroke-width:0px; iri_alice["ex:Alice"]; iri_bob["ex:Bob"]; iri_camille["ex:Camille"]; iri_daniel["ex:Daniel"]; iri_elise["ex:Elise"]; class iri_alice,iri_bob,iri_camille,iri_daniel,iri_elise IRI; iri_alice -- ex:friend --> iri_bob; iri_bob -- ex:friend --> iri_camille; iri_alice -. ex:friend .-> iri_camille; iri_daniel -- ex:isMarriedTo --> iri_elise; iri_elise -. ex:isMarriedTo .-> iri_daniel; ``` ### 6.2. OWL Rules The example below shows the application of OWL RL rules. ```java import fr.inria.corese.core.api.Loader; import fr.inria.corese.core.load.Load; import fr.inria.corese.core.load.LoadException; import fr.inria.corese.core.rule.RuleEngine; import fr.inria.corese.core.sparql.exceptions.EngineException; public class Example { public static void main(String[] args) throws LoadException, EngineException { // Create a new empty Graph Graph graph = Graph.create(); // Add some triples to the graph Load loader = Load.create(graph); loader.parse("input_graph_file.ttl", Loader.format.TURTLE_FORMAT); // Apply rules RuleEngine engine = RuleEngine.create(graph); engine.setProfile(RuleEngine.OWL_RL); engine.process(); } } ``` ## 7. LDScript This section describes how to define and use functions with the [LDScript extension language](https://files.inria.fr/corese/doc/ldscript.html). ### 7.1. Fibonacci function call from Java This example shows how to define and compute the twelfth number of the Fibonacci sequence. ```java import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.exceptions.EngineException; public class Example { public static void main(String[] args) throws EngineException, IOException { // Open LDScript file Path path = Path.of("input LDScript file path.rq"); String ldScript = Files.readString(path, StandardCharsets.UTF_8); // Compile LDScript QueryProcess exec = QueryProcess.create(); exec.compile(ldScript); // Compute the twelfth number of the Fibonacci sequence String name = "http://ns.inria.fr/fibonacci"; IDatatype dt = exec.funcall(name, DatatypeMap.newInstance(12)); // Print result System.out.println(dt); } } ``` **Input LDScript file path:** ```rq prefix fun: @public function fun:fibonacci(n) { if (n < 0) { error() } else if (n = 0) { return(0) } else if (n = 1) { return(1) } else { return (fun:fibonacci(n - 1) + fun:fibonacci(n - 2)) } } ``` ### 7.2. LDScript in SPARQL This example shows how to call an LDScript function from a SPARQL query. ```java import java.io.IOException; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.load.Load; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.exceptions.EngineException; public class Example { public static void main(String[] args) throws EngineException, IOException { String check_query = """ prefix ex: prefix rdf: prefix fun: select ?name ?area where { ?city rdf:type ex:city ; ex:name ?name ; ex:area ?area . filter(?area > fun:toSquareKm(40)) } # Convert square mile to square kilometer function fun:toSquareKm(squareMile) { return (squareMile * 2.59) } """; // Load graph Graph graph = Graph.create(); Load ld = Load.create(graph); ld.parse("input file path"); // SPARQL query QueryProcess exec = QueryProcess.create(graph); Mappings map = exec.query(check_query); } } ``` ### 7.3. Advanced Example The following Java program computes the percentage of people subscribed to social networks in a city compared to its total number of inhabitants. The data is collected from Wikidata. ```java import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.exceptions.EngineException; public class Example { public static void main(String[] args) throws EngineException, IOException { // Open LDScript file Path path = Path.of("input LDScript file path.rq"); String ldScript = Files.readString(path, StandardCharsets.UTF_8); // Compile LDScript QueryProcess exec = QueryProcess.create(); exec.compile(ldScript); // Execute program String name = "http://ns.inria.fr/main"; IDatatype dt = exec.funcall(name); // Print result System.out.println(dt); } } ``` **Input LDScript File:** ```rq prefix fun: prefix wd: prefix wdt: prefix wikibase: prefix bd: prefix rdfs: @public function fun:percentage(sub, total) { return (sub / total * 100) } @public function fun:citypopulationsocialmedia() { query( select ?city ?citylabel ?population ?socialmediafollower where { service { ?city wdt:P31 wd:Q1549591; wdt:P8687 ?socialmediafollower; wdt:P1082 ?population. optional { ?city rdfs:label ?citylabel filter (lang(?citylabel) = "en"). } } } order by desc (?socialmediafollower) limit 100 ) } @public function fun:main() { xt:sort( maplist ( function(x) { let ((citylabel population socialmediafollower) = x) { return (xt:list(citylabel, fun:percentage(socialmediafollower, population))) } }, fun:citypopulationsocialmedia() ), function(x,y) { let ((x_name, x_value) = x, (y_name, y_value) = y) { if (x_value < y_value, 1, if(x=y, o, -1)) } } ) } ```