scala programming for semantic web developers eswc semdev2015
Post on 28-Jul-2015
298 Views
Preview:
TRANSCRIPT
Scalable and Reactive Programming for
Semantic Web Developers
Jean-Paul CalbimonteLSIR EPFL
Developers Workshop. Extended Semantic Web Conference ESWC 2015
Portoroz, 31.05.2015
@jpcik
Semantic Web Devs
2
Have funLove challengesNeed cool tools
Sesame
Scala: Functions and Objects
3
JVM languageBoth object and functional orientedEasy Java-interopReuse Java librariesGrowing community
RDF in Jena: in Scala
String personURI = "http://somewhere/JohnSmith";Model model = ModelFactory.createDefaultModel();model.createResource(personURI).addProperty(VCARD.FN,"John Smith"); Jav
aType inference
Not too useful ; and ()
4
Terser & compact codeType-safe DSLCompiler takes care
val personURI = "http://somewhere/JohnSmith"val model = ModelFactory.createDefaultModelmodel.createResource(personURI).addProperty(VCARD.FN,"John Smith")
sw:JohnSmith “John Smith”vcard:FN
val personURI = "http://somewhere/JohnSmith"implicit val model = createDefaultModeladd(personURI,VCARD.FN->"John Smith")
Scala
boilerplate
String converted to Resource
Some more RDF
5
String personURI = "http://somewhere/JohnSmith";String givenName = "John";String familyName = "Smith";String fullName = givenName + " " + familyName;Model model = ModelFactory.createDefaultModel();model.createResource(personURI) .addProperty(VCARD.FN,fullName) .addProperty(VCARD.N,model.createResource() .addProperty(VCARD.Given,givenName) .addProperty(VCARD.Family,familyName));
val personURI = "http://somewhere/JohnSmith"val givenName = "John"val familyName = "Smith"val fullName = s"$givenName $familyName"implicit val model = createDefaultModeladd(personURI,VCARD.FN->fullName, VCARD.N ->add(bnode,VCARD.Given -> givenName, VCARD.Family->familyName))
sw:JohnSmith“John Smith”
vcard:FN
_:n
“John”
“Smith”vcard:N
vcard:Given
vcard:Family
Blank node
Scala DSLs customizable
Predicate-objects are pairs
Some more RDF in Jena
6
implicit val m=createDefaultModel val ex="http://example.org/" val alice=iri(ex+"alice") val bob=iri(ex+"bob") val charlie=iri(ex+"charlie")
alice+(RDF.`type`->FOAF.Person, FOAF.name->"Alice", FOAF.mbox->iri("mailto:alice@example.org"), FOAF.knows->bob, FOAF.knows->charlie, FOAF.knows->bnode) bob+ (FOAF.name->"Bob", FOAF.knows->charlie) charlie+(FOAF.name->"Charlie", FOAF.knows->alice)
Scala
Still valid Jena RDFYou can do it even nicer
Exploring an RDF Graph
7
ArrayList<String> names=new ArrayList<String>();NodeIterator iter=model.listObjectsOfProperty(VCARD.N);while (iter.hasNext()){ RDFNode obj=iter.next(); if (obj.isResource()) names.add(obj.asResource() .getProperty(VCARD.Family).getObject().toString()); else if (obj.isLiteral()) names.add(obj.asLiteral().getString());}
val names=model.listObjectsOfProperty(VCARD.N).map{ case r:Resource=> r.getProperty(VCARD.Family).obj.toString case l:Literal=> l.getString}
Imperative iteration of collections
Type-based conditional execution
Type casting
Case typeMap applied to operators
8
Query with SPARQL
9
val queryStr = """select distinct ?Concept where {[] a ?Concept} LIMIT 10"""val query = sparql(queryStr)
query.serviceSelect("http://dbpedia.org/sparql").foreach{implicit qs=> println(res("Concept").getURI)}
val f=Future(query.serviceSelect("http://es.dbpedia.org/sparql")).fallbackTo( Future(query.serviceSelect("http://dbpedia.org/sparql")))
f.recover{ case e=> println("Error "+e.getMessage)}f.map(_.foreach{implicit qs=> println(res("Concept").getValue)})
Remote SPARQL endpointSimplified access to Query solutions
Futures: asnyc executionNon blocking codeFallback alternative execution
Actor Model
10
Actor1
Actor2
m No shared mutable stateAvoid blocking operatorsLightweight objectsLoose coupling
communicate through messages
mailboxstate
behaviornon-blocking response
send: fire-forget
Implementations: e.g. Akka for Java/Scala
Parent
Actor1
Supervisionhierarchy
Supervision
Actor2
Actor4 XActor
2
Actor1
Actor2
m
Actor3
Actor4
m
m
Remoting
Reactive Systems
Event-Driven
Jonas Boner. Go Reactive: Event-Driven, Scalable, Resilient & Responsive Systems. 2013.
Events:
reac
t to
ScalableLoad:ResilientFailure:
ResponsiveUsers:
11
RDF Streams: Actors
12
val sys=ActorSystem.create("system")val consumer=sys.actorOf(Props[RdfConsumer])
class Streamer extends StreamRDF{ override def triple(triple:Triple){ consumer ! triple }}
class RdfConsumer extends Actor{ def receive= { case t:Triple => if (t.predicateMatches(RDF.‘type‘)) println(s"received triple $t") }
RDF consumerActor receive method Implements behaviorMessage-passing model
RDF producerAsync message passing
Web RDF Services
13
GET /containers/:containerid/ org.rsp.ldp.ContainerApp.retrieve(containerid:String)POST /containers/:containerid/ org.rsp.ldp.ContainerApp.add(containerid:String)
object ContainerApp extends Controller { def retrieve(id:String) = Action.async {implicit request=> val sw=new StringWriter val statements=m.listStatements(iri(prefix+id+"/"),null,null) val model=createDefaultModel statements.foreach(i=>model.add(i)) model.write(sw, "TURTLE") Future(Ok(sw.toString).as("text/turtle").withHeaders( ETAG->tag, ALLOW->"GET,POST" ))}
Routing rules
Controller returns RDF async
OWLAPI: reasoning
14
val onto=mgr.createOntology
val artist=clazz(pref+"Artist")val singer=clazz(pref +"Singer")onto += singer subClassOf artist
val reasoner = new RELReasonerFactory.createReasoner(onto)
val elvis=ind(pref+"Elvis")reasoner += elvis ofClass singer
reasoner.reclassify
reasoner.getIndividuals(artist) foreach{a=> println(a.getRepresentativeElement.getIRI)}
Creating OWL classesDeclaring class relationships
Declare instances
How is it done?
15
object OwlApiTips{ implicit class TrowlRelReasoner(reasoner:RELReasoner){ def += (axiom:OWLAxiom)= reasoner.add(Set(axiom)) } implicit class OwlClassPlus(theClass:OWLClass){ def subClassOf(superclass:OWLClass)(implicit fac:OWLDataFactory)= fac.getOWLSubClassOfAxiom(theClass, superclass) } implicit class OwlOntologyPlus(onto:OWLOntology){ def += (axiom:OWLAxiom)(implicit mgr:OWLOntologyManager)= mgr.addAxiom(onto, axiom) } implicit class OwlIndividualPlus(ind:OWLIndividual){ def ofClass (theclass:OWLClass)(implicit fac:OWLDataFactory)= fac.getOWLClassAssertionAxiom(theclass, ind) } implicit def str2Iri(s:String):IRI=IRI.create(s) object clazz{ def apply(iri:String)(implicit fac:OWLDataFactory)= fac.getOWLClass(iri) } object ind{ def apply(iri:String)(implicit fac:OWLDataFactory)= fac.getOWLNamedIndividual(iri) } }
Muchas gracias!
Jean-Paul CalbimonteLSIR EPFL
@jpcik
top related