diff --git a/Assignment4/Francloz-24A245/task06.py b/Assignment4/Francloz-24A245/task06.py new file mode 100644 index 00000000..779207bc --- /dev/null +++ b/Assignment4/Francloz-24A245/task06.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +"""Task06.ipynb + +Automatically generated by Colaboratory. + +Original file is located at + https://colab.research.google.com/drive/1nyR-tTtqy8h8yv5vyeslI7oljBQElfoi + +**Task 06: Modifying RDF(s)** +""" + +github_storage = "https://raw.githubusercontent.com/FacultadInformatica-LinkedData/Curso2024-2025/master/Assignment4/course_materials" + +"""Read the RDF file as shown in class""" + +from rdflib import Graph, Namespace, Literal +from rdflib.namespace import RDF, RDFS +from rdflib import FOAF + +g = Graph() +vcard = Namespace("http://www.w3.org/2001/vcard-rdf/3.0#") +schema = Namespace("http://schema.org/") +g.namespace_manager.bind('ns', Namespace("http://somewhere#"), override=False) +g.namespace_manager.bind('vcard', Namespace("http://www.w3.org/2001/vcard-rdf/3.0#"), override=False) +g.parse(github_storage + "/rdf/example5.rdf", format="xml") + +"""Create a new class named Researcher""" + +ns = Namespace("http://somewhere#") +g.add((ns.Researcher, RDF.type, RDFS.Class)) +for s, p, o in g: + print(s, p, o) +print() +"""**TASK 6.1: Create new classes for "School" and "University. Add an rdfs:label in Spanish"** + +""" + +new_triples = [ + (ns.School, RDF.type, RDFS.Class), # (namespace.School, rdfs.isType, rdfs.Class) + (ns.University, RDF.type, RDFS.Class), # (namespace.School, rdfs.isType, rdfs.Class) + (ns.School, RDFS.label, Literal("Escuela")), # (namespace.University, rdfs.label, "Escuela") + (ns.University, RDFS.label, Literal("Universidad")) # (namespace.University, rdfs.label, "Universidad") +] + +for triple in new_triples: + g.add(triple) + +# Visualize the results +for s, p, o in g: + print(s, p, o) +print() +"""**TASK 6.2: Add "Researcher" as a subclass of "Person"**""" + +new_triples = [ + (ns.Researcher, RDFS.subClassOf, schema.Person), +] + +for triple in new_triples: + g.add(triple) + +# TO DO +# Visualize the results +for s, p, o in g: + print(s, p, o) +print() +"""**TASK 6.3: Create a new individual of Researcher named "Jane Smithers"**""" + +new_triples = [ + (ns.JaneSmithers, RDF.type, ns.Researcher), + (ns.JaneSmithers, RDFS.label, Literal("Jane Smithers")), +] + +for triple in new_triples: + g.add(triple) + +# Visualize the results +for s, p, o in g: + print(s, p, o) +print() +"""**TASK 6.4: Add to the individual JaneSmithers the email address, fullName, given and family names. Use the https://schema.org vocabulary**""" + +new_triples = [ + (ns.JaneSmithers, schema.name, Literal("Jane Smithers")), + (ns.JaneSmithers, schema.email, Literal("jane.smithers@upm.es")), + (ns.JaneSmithers, schema.givenName, Literal("Jane")), + (ns.JaneSmithers, schema.familyName, Literal("Smithers")), +] + +for triple in new_triples: + g.add(triple) + +# Visualize the results +for s, p, o in g: + print(s, p, o) +print() + +"""**TASK 6.5: Add UPM as the university where John Smith works. Use the "https://example.org/ namespace**""" + +# I assume we should use ns for the university, but not the property. +# Thus, using vcard.organization_name, as it is usually done that way. +# If not, we could use ns.worksAt +new_triples = [ + (ns.JohnSmith, vcard.organization_name, ns.UPM), + # (ns.JohnSmith, vcard.worksAt, ns.UPM), +] + +for triple in new_triples: + g.add(triple) + +for s, p, o in g: + print(s, p, o) + +"""**Task 6.6: Add that John knows Jane using the FOAF vocabulary. Make sure the relationship exists.**""" + +new_triples = [ + (ns.JohnSmith, FOAF.knows, ns.JaneSmithers), +] + +for triple in new_triples: + g.add(triple) + +# Visualize the results +for s, p, o in g: + print(s, p, o) diff --git a/Assignment4/Francloz-24A245/task07.py b/Assignment4/Francloz-24A245/task07.py new file mode 100644 index 00000000..bfff4e3d --- /dev/null +++ b/Assignment4/Francloz-24A245/task07.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +"""Task07.ipynb + +Automatically generated by Colaboratory. + +Original file is located at + https://colab.research.google.com/drive/1yPniC8cCIRK0ofpUQK_h0bcNOa4CroCF + +**Task 07: Querying RDF(s)** +""" + +github_storage = "https://raw.githubusercontent.com/FacultadInformatica-LinkedData/Curso2024-2025/master/Assignment4/course_materials" + +"""First let's read the RDF file""" + +from rdflib import Graph, Namespace, Literal +from rdflib.namespace import RDF, RDFS + +g = Graph() +vcard = Namespace("http://www.w3.org/2001/vcard-rdf/3.0#") +schema = Namespace("http://schema.org/") +ns = Namespace("http://somewhere#") +g.namespace_manager.bind('ns', Namespace("http://somewhere#"), override=False) +g.namespace_manager.bind('vcard', Namespace("http://www.w3.org/2001/vcard-rdf/3.0#"), override=False) +g.parse(github_storage + "/rdf/example5.rdf", format="xml") +g.parse(github_storage + "/rdf/example6.rdf", format="xml") + +"""**TASK 7.1: List all subclasses of "LivingThing" with RDFLib and SPARQL**""" + +# I AM ASSUMING HERE DIRECT SUBCLASSES +q1 = """ + SELECT ?subclass + WHERE { + ?subclass rdfs:subClassOf ns:LivingThing . + } +""" + +for r in g.query(q1): + print(r) + +print() + +for subclass in g.subjects(RDFS.subClassOf, ns.LivingThing): + print(subclass) + +print() + +"""**TASK 7.2: List all individuals of "Person" with RDFLib and SPARQL (remember the subClasses)**""" + +q2 = """ + SELECT ?individual + WHERE { + ?individual a ?type . + ?type rdfs:subClassOf* ns:Person . + } +""" + +for r in g.query(q2): + print(r) + +print() + + +def recursiveSubClassOf(graph, class_uri): + subclasses = {class_uri} + for subclass in graph.subjects(RDFS.subClassOf, class_uri): + subclasses += recursiveSubClassOf(graph, subclass) # Get subclasses* of subclass too + return subclasses + + +# Get all subclasses of ns:Person +person_subclasses = recursiveSubClassOf(g, ns.Person) + +# Find all individuals of Person and its subclasses +for subclass in person_subclasses: + for individual in g.subjects(RDF.type, subclass): + print(individual) + +print() + +"""**TASK 7.3: List all individuals of just "Person" or "Animal". You do not need to list the individuals of the subclasses of person (in SPARQL only)**""" + +q3 = """ + SELECT ?individual + WHERE { + { + ?individual a ns:Person . + } + UNION + { + ?individual a ns:Animal . + } + } + +""" + +for r in g.query(q3): + print(r) + +print() + +"""**TASK 7.4: List the name of the persons who know Rocky (in SPARQL only)**""" + +q4 = """ + SELECT ?person ?name + WHERE { + { + {?person foaf:knows ns:RockySmith .} + UNION + {ns:RockySmith foaf:knows ?person .} + } + ?person ?name . + } +""" + +for r in g.query(q4): + print(r) + +print() + +"""**Task 7.5: List the name of those animals who know at least another animal in the graph (in SPARQL only)**""" + +q5 = """ + SELECT ?animal ?c ?name + WHERE { + ?animal a ns:Animal . + ?animal foaf:knows ?otherAnimal . + ?otherAnimal a ns:Animal . + ?animal ?name . + } +""" + +for r in g.query(q5): + print(r) + +print() + +"""**Task 7.6: List the age of all living things in descending order (in SPARQL only)**""" + +q6 = """ + SELECT ?livingThing ?c ?age + WHERE { + ?subClass rdfs:subClassOf* ns:LivingThing . + ?livingThing a ?subClass . + ?livingThing a ?subClass . + ?livingThing ?age . + } + ORDER BY DESC(?age) +""" + +for r in g.query(q6): + print(r) + +print() diff --git a/Assignment4/Francloz-24A245/task08.py b/Assignment4/Francloz-24A245/task08.py new file mode 100644 index 00000000..ef190dea --- /dev/null +++ b/Assignment4/Francloz-24A245/task08.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +"""Task08.ipynb + +Automatically generated by Colaboratory. + +Original file is located at + https://colab.research.google.com/drive/18P0xTS31q1P7nR4efg0Yy3QrClOxqMAe + +**Task 08: Completing missing data** +""" + +github_storage = "https://raw.githubusercontent.com/FacultadInformatica-LinkedData/Curso2024-2025/master/Assignment4/course_materials/" + +from rdflib import Graph, Namespace, Literal, URIRef + +g1 = Graph() +g2 = Graph() +g1.parse(github_storage + "rdf/data01.rdf", format="xml") +g2.parse(github_storage + "rdf/data02.rdf", format="xml") + +vcard = Namespace("http://www.w3.org/2001/vcard-rdf/3.0#") +schema = Namespace("http://schema.org/") +ns = Namespace("http://somewhere#") +data = Namespace("http://data.org#") +g1.namespace_manager.bind('ns', Namespace("http://somewhere#"), override=False) +g1.namespace_manager.bind('vcard', Namespace("http://www.w3.org/2001/vcard-rdf/3.0#"), override=False) + +"""Tarea: lista todos los elementos de la clase Person en el primer grafo (data01.rdf) y completa los campos (given +name, family name y email) que puedan faltar con los datos del segundo grafo (data02.rdf). Puedes usar consultas +SPARQL o iterar el grafo, o ambas cosas.""" + + +q1 = """ +PREFIX ns: +PREFIX vcard: +PREFIX data: + +SELECT ?person ?givenName ?familyName ?email +WHERE { + ?person a ?type . + ?type rdfs:subClassOf* data:Person . + OPTIONAL { ?person vcard:givenName ?givenName } . + OPTIONAL { ?person vcard:Family ?familyName } . + OPTIONAL { ?person vcard:email ?email } +} +""" + +to_fill = g1.query(q1) +for t in to_fill: + print(t) +print() + + +q1 = """ +PREFIX ns: +PREFIX vcard: +PREFIX data: + +SELECT ?person ?givenName ?familyName ?email +WHERE { + ?person a ?type . + ?type rdfs:subClassOf* data:Person . + # OPTIONAL { ?person ?property ?value } . + OPTIONAL { ?person vcard:Given ?givenName } . + OPTIONAL { ?person vcard:FN ?familyName } . + OPTIONAL { ?person vcard:EMAIL ?email } +} +""" + +filled = g2.query(q1) +for t in filled: + print(t) +print() + + +for t1 in to_fill: + for t2 in filled: + if t1[0] == t2[0]: + if t1[1] is not None: g1.add((t1[0], vcard.Given, t1[1])) + if t1[2] is not None: g1.add((t1[0], vcard.Family, t1[2])) + if t1[3] is not None: g1.add((t1[0], vcard.EMAIL, t1[3])) diff --git a/Assignment4/Francloz-24A245/task09.py b/Assignment4/Francloz-24A245/task09.py new file mode 100644 index 00000000..365ebfb6 --- /dev/null +++ b/Assignment4/Francloz-24A245/task09.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +"""Task09.ipynb + +Automatically generated by Colaboratory. + +Original file is located at + https://colab.research.google.com/drive/1aA_7cDJnS46kKnLS5uuCGN5_s3QANqk- + +**Task 09: Data linking** +""" + +github_storage = "https://raw.githubusercontent.com/FacultadInformatica-LinkedData/Curso2024-2025/master/Assignment4/course_materials" + +from rdflib import Graph, Namespace, Literal, URIRef, OWL + +g1 = Graph() +g2 = Graph() +g3 = Graph() +g1.parse(github_storage+"/rdf/data03.rdf", format="xml") +g2.parse(github_storage+"/rdf/data04.rdf", format="xml") + + +vcard = Namespace("http://www.w3.org/2001/vcard-rdf/3.0#") +schema = Namespace("http://schema.org/") +ns = Namespace("http://somewhere#") +g1.namespace_manager.bind('ns', Namespace("http://somewhere#"), override=False) +g1.namespace_manager.bind('vcard', Namespace("http://www.w3.org/2001/vcard-rdf/3.0#"), override=False) + +"""Busca individuos en los dos grafos y enlázalos mediante la propiedad OWL:sameAs, inserta estas coincidencias en +g3. Consideramos dos individuos iguales si tienen el mismo apodo y nombre de familia. Ten en cuenta que las URI no +tienen por qué ser iguales para un mismo individuo en los dos grafos.""" + +t1s = g1.query(""" +PREFIX ns: +PREFIX vcard: +PREFIX data: +SELECT ?person ?givenName ?familyName ?type +WHERE { + ?person a ?type . + ?type rdfs:subClassOf* data:Person . + ?person vcard:Given ?givenName . + ?person vcard:Family ?familyName +} +""") +t2s = g2.query(""" +PREFIX ns: +PREFIX vcard: +PREFIX data: +SELECT ?person ?givenName ?familyName +WHERE { + ?person a ?type . + ?type rdfs:subClassOf* data:Person . + ?person vcard:Given ?givenName . + ?person vcard:Family ?familyName +} +""") + +for t1 in t1s: + for t2 in t2s: + # print((t1[1], t2[1], t1[2], t2[2])) + if t1[1].eq(t2[1]) and t1[2].eq(t2[2]): + g3.add((t1[0], OWL.sameAs, t2[0])) + g3.add((t2[0], OWL.sameAs, t1[0])) + print((t1[1], t2[1], t1[2], t2[2])) + +for t in g3: + print(t) \ No newline at end of file