From 413c424cc1fe761f3544aa9b504e1dca2ce9db6f Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sun, 1 Dec 2019 10:22:55 +0200 Subject: [PATCH 01/27] WIP --- linkedql.json | 1056 ++++++++++++++++++++++++++ query/linkedql/client/client.go | 71 ++ query/linkedql/client/client2.go | 35 + query/linkedql/client/client_test.go | 13 + query/linkedql/client/owl_api.go | 29 + 5 files changed, 1204 insertions(+) create mode 100644 linkedql.json create mode 100644 query/linkedql/client/client.go create mode 100644 query/linkedql/client/client2.go create mode 100644 query/linkedql/client/client_test.go create mode 100644 query/linkedql/client/owl_api.go diff --git a/linkedql.json b/linkedql.json new file mode 100644 index 000000000..bfc4f8d8c --- /dev/null +++ b/linkedql.json @@ -0,0 +1,1056 @@ +{ + "@context": { + "rdf": { "@id": "http://www.w3.org/1999/02/22-rdf-syntax-ns#" }, + "rdfs": { "@id": "http://www.w3.org/2000/01/rdf-schema#" }, + "owl": { "@id": "http://www.w3.org/2002/07/owl#" }, + "xsd": { "@id": "http://www.w3.org/2001/XMLSchema#" }, + "linkedql": { "@id": "http://cayley.io/linkedql#" } + }, + "@graph": [ + { + "@id": "linkedql:Limit", + "@type": "rdfs:Class", + "rdfs:comment": "Limit a number of nodes for current path.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n8440732519379756303", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n3712322762825274014", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:limit" + } + } + ] + }, + { + "@id": "linkedql:Value", + "@type": "rdfs:Class", + "rdfs:comment": "Value returns a single value matched in the query", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n4579355384285360119", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Intersect", + "@type": "rdfs:Class", + "rdfs:comment": "Intersect resolves to all the same values resolved by the from step and the provided steps.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n4514190024430663212", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:ReversePropertyNames", + "@type": "rdfs:Class", + "rdfs:comment": "Get the list of predicates that are pointing in to a node.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n8660593491344506672", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Labels", + "@type": "rdfs:Class", + "rdfs:comment": "Get the list of inbound and outbound quad labels", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n3966336922519947481", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Order", + "@type": "rdfs:Class", + "rdfs:comment": "Order sorts the results in ascending order according to the current entity / value", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n6687051227661129038", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:SelectFirst", + "@type": "rdfs:Class", + "rdfs:comment": "Like Select but only returns the first result", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n8213583569693444697", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Out", + "@type": "rdfs:Class", + "rdfs:comment": "Alias for View", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n1219656053828715988", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n2330159957297390889", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:properties" + } + } + ] + }, + { + "@id": "linkedql:In", + "@type": "rdfs:Class", + "rdfs:comment": "Alias for ViewReverse", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n888163984235468022", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n6694906304984451453", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:properties" + } + } + ] + }, + { + "@id": "linkedql:Has", + "@type": "rdfs:Class", + "rdfs:comment": "Filter all paths which are, at this point, on the subject for the given predicate and object, but do not follow the path, merely filter the possible paths. Usually useful for starting with all nodes, or limiting to a subset depending on some predicate/value pair.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n175100899574574219", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n1044889261799882442", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:property" + } + } + ] + }, + { + "@id": "linkedql:PropertyNamesAs", + "@type": "rdfs:Class", + "rdfs:comment": "Tag the list of predicates that are pointing out from a node.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n292297794499813908", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n6225281244837245777", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:tag" + } + } + ] + }, + { + "@id": "linkedql:Skip", + "@type": "rdfs:Class", + "rdfs:comment": "Skip a number of nodes for current path.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n130022202379099635", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n6588229958767122733", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:offset" + } + } + ] + }, + { + "@id": "linkedql:Vertex", + "@type": "rdfs:Class", + "rdfs:comment": "Vertex resolves to all the existing objects and primitive values in the graph. If provided with values resolves to a sublist of all the existing values in the graph.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + } + ] + }, + { + "@id": "linkedql:As", + "@type": "rdfs:Class", + "rdfs:comment": "As assigns the resolved values of the from step to a given name. The name can be used with the Select and Documents steps to retreive the values or to return to the values in further steps with the Back step. It resolves to the values of the from step.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n6798046550741287208", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n286452450666657184", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:name" + } + } + ] + }, + { + "@id": "linkedql:FollowReverse", + "@type": "rdfs:Class", + "rdfs:comment": "The same as follow but follows the chain in the reverse direction. Flips View and ViewReverse where appropriate, the net result being a virtual predicate followed in the reverse direction. Starts at the end of the morphism and follows it backwards (with appropriate flipped directions) to the g.M() location.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n421149569477813134", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n8713908741985514185", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:followed" + } + } + ] + }, + { + "@id": "linkedql:Back", + "@type": "rdfs:Class", + "rdfs:comment": "Back resolves to the values of the previous the step or the values assigned to name in a former step.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n6224931844063977691", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n7828451043486737760", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:name" + } + } + ] + }, + { + "@id": "linkedql:ViewBoth", + "@type": "rdfs:Class", + "rdfs:comment": "ViewBoth is like View but resolves to both the object values and references to the values of the given properties in via. It is the equivalent for the Union of View and ViewReverse of the same property.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n5094381124248830937", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n3925447844365248023", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:properties" + } + } + ] + }, + { + "@id": "linkedql:Unique", + "@type": "rdfs:Class", + "rdfs:comment": "Remove duplicate values from the path.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n5542740196010578693", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Count", + "@type": "rdfs:Class", + "rdfs:comment": "Count resolves to the number of the resolved values of the from step", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n3865310955534739904", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:ViewReverse", + "@type": "rdfs:Class", + "rdfs:comment": "The inverse of View. Starting with the nodes in `path` on the object, follow the quads with predicates defined by `predicatePath` to their subjects.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n5018575002663944481", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n4550818690762018934", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:properties" + } + } + ] + }, + { + "@id": "linkedql:Properties", + "@type": "rdfs:Class", + "rdfs:comment": "Adds tags for all properties of the current entity", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n2729739665710486886", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:HasReverse", + "@type": "rdfs:Class", + "rdfs:comment": "The same as Has, but sets constraint in reverse direction.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n7199307538045442194", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n1649650420342137981", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:property" + } + } + ] + }, + { + "@id": "linkedql:ReversePropertyNamesAs", + "@type": "rdfs:Class", + "rdfs:comment": "Tag the list of predicates that are pointing in to a node.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n824169249890386973", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n912081101491472970", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:tag" + } + } + ] + }, + { + "@id": "linkedql:Union", + "@type": "rdfs:Class", + "rdfs:comment": "Return the combined paths of the two queries. Notice that it's per-path, not per-node. Once again, if multiple paths reach the same destination, they might have had different ways of getting there (and different tags).", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n8251106634341539663", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Placeholder", + "@type": "rdfs:Class", + "rdfs:comment": "Placeholder is like Vertex but resolves to the values in the context it is placed in. It should only be used where a PathStep is expected and can't be resolved on its own.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + } + ] + }, + { + "@id": "linkedql:View", + "@type": "rdfs:Class", + "rdfs:comment": "View resolves to the values of the given property or properties in via of the current objects. If via is a path it's resolved values will be used as properties.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n5414025948682150736", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n337958186940316772", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:properties" + } + } + ] + }, + { + "@id": "linkedql:Difference", + "@type": "rdfs:Class", + "rdfs:comment": "Difference resolves to all the values resolved by the from step different then the values resolved by the provided steps. Caution: it might be slow to execute.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n2352625201874167266", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Select", + "@type": "rdfs:Class", + "rdfs:comment": "Select returns flat records of tags matched in the query", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n7185668025961658720", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Is", + "@type": "rdfs:Class", + "rdfs:comment": "Is resolves to all the values resolved by the from step which are included in provided values.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n7434626777184219064", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Filter", + "@type": "rdfs:Class", + "rdfs:comment": "Apply constraints to a set of nodes. Can be used to filter values by range or match strings.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n308561566335026255", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n7752481218121017300", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:filter" + } + } + ] + }, + { + "@id": "linkedql:Follow", + "@type": "rdfs:Class", + "rdfs:comment": "The way to use a path prepared with Morphism. Applies the path chain on the morphism object to the current path. Starts as if at the g.M() and follows through the morphism path.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n5924982697949066515", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n3698252949431811663", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:followed" + } + } + ] + }, + { + "@id": "linkedql:PropertyNames", + "@type": "rdfs:Class", + "rdfs:comment": "Get the list of predicates that are pointing out from a node.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n2100531796371300813", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:ReverseProperties", + "@type": "rdfs:Class", + "rdfs:comment": "Gets all the properties the current entity / value is referenced at", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n4543797063415686792", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:names", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n2009243660815281193", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:Properties" + }, + { + "@id": "linkedql:ReverseProperties" + } + ] + } + }, + "rdfs:range": { + "@id": "xsd:string" + } + }, + { + "@id": "linkedql:from", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n1898025205901327062", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:HasReverse" + }, + { + "@id": "linkedql:Labels" + }, + { + "@id": "linkedql:Order" + }, + { + "@id": "linkedql:Skip" + }, + { + "@id": "linkedql:ViewBoth" + }, + { + "@id": "linkedql:Count" + }, + { + "@id": "linkedql:Properties" + }, + { + "@id": "linkedql:PropertyNamesAs" + }, + { + "@id": "linkedql:As" + }, + { + "@id": "linkedql:Union" + }, + { + "@id": "linkedql:Is" + }, + { + "@id": "linkedql:ReverseProperties" + }, + { + "@id": "linkedql:Out" + }, + { + "@id": "linkedql:ReversePropertyNamesAs" + }, + { + "@id": "linkedql:View" + }, + { + "@id": "linkedql:Limit" + }, + { + "@id": "linkedql:SelectFirst" + }, + { + "@id": "linkedql:Unique" + }, + { + "@id": "linkedql:Value" + }, + { + "@id": "linkedql:Back" + }, + { + "@id": "linkedql:Select" + }, + { + "@id": "linkedql:Follow" + }, + { + "@id": "linkedql:ReversePropertyNames" + }, + { + "@id": "linkedql:FollowReverse" + }, + { + "@id": "linkedql:Difference" + }, + { + "@id": "linkedql:Intersect" + }, + { + "@id": "linkedql:ViewReverse" + }, + { + "@id": "linkedql:Filter" + }, + { + "@id": "linkedql:PropertyNames" + }, + { + "@id": "linkedql:In" + }, + { + "@id": "linkedql:Has" + } + ] + } + }, + "rdfs:range": { + "@id": "linkedql:PathStep" + } + }, + { + "@id": "linkedql:tags", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n5703457665831349039", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:SelectFirst" + }, + { + "@id": "linkedql:Select" + } + ] + } + }, + "rdfs:range": { + "@id": "xsd:string" + } + }, + { + "@id": "linkedql:offset", + "@type": "owl:DatatypeProperty", + "rdfs:domain": "linkedql:Skip", + "rdfs:range": { + "@id": "xsd:int" + } + }, + { + "@id": "linkedql:name", + "@type": "owl:DatatypeProperty", + "rdfs:domain": { + "@id": "_:n441910633043105813", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:As" + }, + { + "@id": "linkedql:Back" + } + ] + } + }, + "rdfs:range": { + "@id": "xsd:string" + } + }, + { + "@id": "linkedql:followed", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n5918147121052823382", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:Follow" + }, + { + "@id": "linkedql:FollowReverse" + } + ] + } + }, + "rdfs:range": { + "@id": "linkedql:PathStep" + } + }, + { + "@id": "linkedql:tag", + "@type": "owl:DatatypeProperty", + "rdfs:domain": { + "@id": "_:n2861998284995186465", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:PropertyNamesAs" + }, + { + "@id": "linkedql:ReversePropertyNamesAs" + } + ] + } + }, + "rdfs:range": { + "@id": "xsd:string" + } + }, + { + "@id": "linkedql:filter", + "@type": "owl:ObjectProperty", + "rdfs:domain": "linkedql:Filter", + "rdfs:range": { + "@id": "linkedql:Operator" + } + }, + { + "@id": "linkedql:limit", + "@type": "owl:DatatypeProperty", + "rdfs:domain": "linkedql:Limit", + "rdfs:range": { + "@id": "xsd:int" + } + }, + { + "@id": "linkedql:steps", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n1702138994867097388", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:Intersect" + }, + { + "@id": "linkedql:Union" + }, + { + "@id": "linkedql:Difference" + } + ] + } + }, + "rdfs:range": { + "@id": "linkedql:PathStep" + } + }, + { + "@id": "linkedql:properties", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n716290370629566278", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:Out" + }, + { + "@id": "linkedql:In" + }, + { + "@id": "linkedql:ViewBoth" + }, + { + "@id": "linkedql:ViewReverse" + }, + { + "@id": "linkedql:View" + } + ] + } + }, + "rdfs:range": { + "@id": "linkedql:PathStep" + } + }, + { + "@id": "linkedql:property", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n2774302972298001908", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:Has" + }, + { + "@id": "linkedql:HasReverse" + } + ] + } + }, + "rdfs:range": { + "@id": "linkedql:PathStep" + } + }, + { + "@id": "linkedql:values", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n993961146967673695", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:Has" + }, + { + "@id": "linkedql:Vertex" + }, + { + "@id": "linkedql:HasReverse" + }, + { + "@id": "linkedql:Is" + } + ] + } + }, + "rdfs:range": { + "@id": "rdfs:Resource" + } + } + ] +} diff --git a/query/linkedql/client/client.go b/query/linkedql/client/client.go new file mode 100644 index 000000000..22727aa89 --- /dev/null +++ b/query/linkedql/client/client.go @@ -0,0 +1,71 @@ +package client + +import ( + "encoding/json" + "fmt" + "go/format" + "io/ioutil" + "os" +) + +type StepType struct { + ID string `json:"@id"` + Type string `json:"@type"` + Comment string `json:"rdfs:comment"` +} + +func GenerateClient() (string, error) { + jsonFile, err := os.Open("schema.json") + if err != nil { + return "", err + } + byteValue, _ := ioutil.ReadAll(jsonFile) + var a []StepType + err = json.Unmarshal(byteValue, &a) + if err != nil { + return "", err + } + fmt.Printf("%v\n", a) + src := ` +package client + +type Step map[string]interface{} + +type Path struct{ + cursor Step +} +` + stepName := "Vertex" + argumentNames := []string{ + "values", + } + argumentsString := "" + for _, argument := range argumentNames { + argumentsString += argument + " " + "[]interface{}" + } + fieldsString := "" + for _, argument := range argumentNames { + fieldsString += "\n\"" + argument + "\": " + argument + "," + } + generated := fmt.Sprintf(` +func (p *Path) %s (%s) *Path { + return Path{ + cursor: Step{ + "@type": "linkedql:%s", + "from": p.cursor,%s + }, + } +} + `, stepName, argumentsString, stepName, fieldsString) + + all := src + generated + + formatted, err := format.Source([]byte(all)) + formattedStr := string(formatted) + + if err != nil { + return "", err + } + + return formattedStr, nil +} diff --git a/query/linkedql/client/client2.go b/query/linkedql/client/client2.go new file mode 100644 index 000000000..dc7624cd3 --- /dev/null +++ b/query/linkedql/client/client2.go @@ -0,0 +1,35 @@ +package main + +import ( + "bytes" + "fmt" + "go/ast" + "go/format" + "go/token" +) + +func main() { + file := &ast.File{ + Name: ast.NewIdent("example"), + Decls: []ast.Decl{ + &ast.FuncDecl{ + Name: ast.NewIdent("foo"), + Type: &ast.FuncType{ + Params: &ast.FieldList{}, + Results: &ast.FieldList{}, + }, + }, + }, + } + // Create a FileSet for node. Since the node does not come + // from a real source file, fset will be empty. + fset := token.NewFileSet() + + var buf bytes.Buffer + err := format.Node(&buf, fset, file) + if err != nil { + panic(err) + } + + fmt.Println(buf.String()) +} diff --git a/query/linkedql/client/client_test.go b/query/linkedql/client/client_test.go new file mode 100644 index 000000000..d61ecd3a9 --- /dev/null +++ b/query/linkedql/client/client_test.go @@ -0,0 +1,13 @@ +package client + +import "testing" + +import "fmt" + +func TestGenerateClient(t *testing.T) { + code, err := GenerateClient() + if err != nil { + panic(err) + } + fmt.Println(code) +} diff --git a/query/linkedql/client/owl_api.go b/query/linkedql/client/owl_api.go new file mode 100644 index 000000000..2a0436f86 --- /dev/null +++ b/query/linkedql/client/owl_api.go @@ -0,0 +1,29 @@ +package client + +import ( + "github.com/cayleygraph/cayley/graph" + "github.com/cayleygraph/quad" +) + +type Class quad.Value +type Property quad.IRI + +func getProperties(qs graph.QuadStore, class Class) []Property { + panic("Not implemented") +} + +func getCardinality(qs graph.QuadStore, class Class, property Property) (int, error) { + panic("Not implemented") +} + +func getMaxCardinality(qs graph.QuadStore, class Class, property Property) (int, error) { + panic("Not implemented") +} + +func getRange(qs graph.QuadStore, property Property) quad.Value { + panic("Not implemented") +} + +func getAllClasses(qs graph.QuadStore) []Class { + panic("Not implemented") +} From 13e3d546190f5175938d08dc6bca0e13bad1d969 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sun, 1 Dec 2019 23:17:07 +0200 Subject: [PATCH 02/27] Defined better API and loaded json schema to quad store --- owl/owl.go | 40 ++++++++++++++++++++++++++++ query/linkedql/client/client2.go | 45 +++++++++++++++++++++++++++++++- query/linkedql/client/owl_api.go | 29 -------------------- 3 files changed, 84 insertions(+), 30 deletions(-) create mode 100644 owl/owl.go delete mode 100644 query/linkedql/client/owl_api.go diff --git a/owl/owl.go b/owl/owl.go new file mode 100644 index 000000000..a98ab8f95 --- /dev/null +++ b/owl/owl.go @@ -0,0 +1,40 @@ +package owl + +import ( + "github.com/cayleygraph/cayley/graph" + "github.com/cayleygraph/quad" +) + +type Class struct { + qs graph.QuadStore + Identifier quad.Value +} + +func (c *Class) Properties() []Property { + panic("Not implemented") +} + +func (c *Class) CardinalityOf(property Property) (int, error) { + panic("Not implemented") +} + +func (c *Class) MaxCardinalityOf(property Property) (int, error) { + panic("Not implemented") +} + +func (c *Class) SubClasses() []Class { + panic("Not implemented") +} + +func GetClass(qs graph.QuadStore, identifier quad.Value) Class { + return Class{Identifier: identifier} +} + +type Property struct { + qs graph.QuadStore + Identifier quad.IRI +} + +func (p *Property) Range(property Property) quad.Value { + panic("Not implemented") +} diff --git a/query/linkedql/client/client2.go b/query/linkedql/client/client2.go index dc7624cd3..0a0534b28 100644 --- a/query/linkedql/client/client2.go +++ b/query/linkedql/client/client2.go @@ -2,13 +2,56 @@ package main import ( "bytes" + "encoding/json" "fmt" "go/ast" "go/format" "go/token" + "io" + "os" + + "github.com/cayleygraph/cayley/graph" + "github.com/cayleygraph/cayley/graph/memstore" + "github.com/cayleygraph/cayley/owl" + "github.com/cayleygraph/quad" + "github.com/cayleygraph/quad/jsonld" ) +const schemaFile = "linkedql.json" + +func loadSchema() (graph.QuadStore, error) { + jsonFile, err := os.Open(schemaFile) + if err != nil { + return nil, err + } + var o interface{} + qs := memstore.New() + json.NewDecoder(jsonFile).Decode(&o) + reader := jsonld.NewReaderFromMap(o) + for true { + quad, err := reader.ReadQuad() + if err == io.EOF { + break + } else if err != nil { + return nil, err + } + qs.AddQuad(quad) + } + return qs, nil +} + func main() { + qs, err := loadSchema() + + stepClass := owl.GetClass(qs, quad.IRI("linkedql:Step")) + stepSubClasses := stepClass.SubClasses() + + fmt.Printf("%v\n", stepSubClasses) + + if err != nil { + panic(err) + } + file := &ast.File{ Name: ast.NewIdent("example"), Decls: []ast.Decl{ @@ -26,7 +69,7 @@ func main() { fset := token.NewFileSet() var buf bytes.Buffer - err := format.Node(&buf, fset, file) + err = format.Node(&buf, fset, file) if err != nil { panic(err) } diff --git a/query/linkedql/client/owl_api.go b/query/linkedql/client/owl_api.go deleted file mode 100644 index 2a0436f86..000000000 --- a/query/linkedql/client/owl_api.go +++ /dev/null @@ -1,29 +0,0 @@ -package client - -import ( - "github.com/cayleygraph/cayley/graph" - "github.com/cayleygraph/quad" -) - -type Class quad.Value -type Property quad.IRI - -func getProperties(qs graph.QuadStore, class Class) []Property { - panic("Not implemented") -} - -func getCardinality(qs graph.QuadStore, class Class, property Property) (int, error) { - panic("Not implemented") -} - -func getMaxCardinality(qs graph.QuadStore, class Class, property Property) (int, error) { - panic("Not implemented") -} - -func getRange(qs graph.QuadStore, property Property) quad.Value { - panic("Not implemented") -} - -func getAllClasses(qs graph.QuadStore) []Class { - panic("Not implemented") -} From 7b13b02169ac45b7c3f5a982860871c80dc0576c Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Mon, 2 Dec 2019 23:34:29 +0200 Subject: [PATCH 03/27] Start implementing OWL module and test it --- owl/owl.go | 173 +++++++++++++++++++++++++++++++++++++++++++++--- owl/owl_test.go | 54 +++++++++++++++ 2 files changed, 217 insertions(+), 10 deletions(-) create mode 100644 owl/owl_test.go diff --git a/owl/owl.go b/owl/owl.go index a98ab8f95..4df1751f2 100644 --- a/owl/owl.go +++ b/owl/owl.go @@ -1,40 +1,193 @@ package owl import ( + "context" + "fmt" + + "github.com/cayleygraph/cayley/clog" "github.com/cayleygraph/cayley/graph" + "github.com/cayleygraph/cayley/graph/iterator" + "github.com/cayleygraph/cayley/query/path" "github.com/cayleygraph/quad" + "github.com/cayleygraph/quad/voc/rdf" + "github.com/cayleygraph/quad/voc/rdfs" ) type Class struct { + ctx context.Context qs graph.QuadStore + ref graph.Ref Identifier quad.Value } -func (c *Class) Properties() []Property { - panic("Not implemented") +func (c *Class) path() *path.Path { + return path.StartPath(c.qs, c.Identifier) +} + +func (c *Class) unionsPath() *path.Path { + reverseListPath := path.NewPath(c.qs).In(quad.IRI(rdf.First).Full()) + return c.path().FollowRecursive(reverseListPath, 10, []string{}) +} + +func classFromRef(ctx context.Context, qs graph.QuadStore, ref graph.Ref) *Class { + val := qs.NameOf(ref) + return &Class{ + ctx: ctx, + qs: qs, + ref: ref, + Identifier: val, + } +} + +var domain = quad.IRI(rdfs.Domain).Full() + +// Properties return all the properties a class instance may have +func (c *Class) Properties() []*Property { + ctx := context.TODO() + p := c. + path(). + Or(c.unionsPath().In(quad.IRI("http://www.w3.org/2002/07/owl#unionOf").Full())). + In(domain) + it := p.BuildIterator(ctx).Iterate() + var properties []*Property + for it.Next(ctx) { + property, err := propertyFromRef(ctx, c.qs, it.Result()) + if err != nil { + clog.Warningf(err.Error()) + continue + } + properties = append(properties, property) + } + return properties +} + +func (c *Class) ParentClasses() []*Class { + it := c.path().Out(rdfs.SubClassOf).BuildIterator(c.ctx).Iterate() + var classes []*Class + for it.Next(c.ctx) { + class := classFromRef(c.ctx, c.qs, it.Result()) + classes = append(classes, class) + } + return classes } +func propertyRestrictionsPath(c *Class, property Property, restrictionProperty quad.IRI) *path.Path { + subClassesPath := c.path().Out(quad.IRI(rdfs.SubClassOf).Full()) + restrictionsPath := subClassesPath.Has(quad.IRI(rdf.Type).Full(), quad.IRI("owl:Restriction").Full()) + propertyRestrictionsPath := restrictionsPath.Has(quad.IRI("owl:onProperty").Full(), property.Identifier) + return propertyRestrictionsPath.Out(restrictionProperty) +} + +func intFromScanner(ctx context.Context, it iterator.Scanner, qs graph.QuadStore) (int, error) { + for it.Next(ctx) { + ref := it.Result() + value := qs.NameOf(ref) + typedString, ok := value.(quad.TypedString) + if !ok { + return -1, fmt.Errorf("Unexpected value %v of type %t", value, value) + } + native := typedString.Native() + i, ok := native.(int) + if !ok { + return -1, fmt.Errorf("Unexpected value %v of type %t", native, native) + } + return i, nil + } + return -1, fmt.Errorf("Iterator has not emitted any value") +} + +// CardinalityOf returns the defined exact cardinality for the property for the class +// If exact cardinality is not defined for the class returns an error func (c *Class) CardinalityOf(property Property) (int, error) { - panic("Not implemented") + p := propertyRestrictionsPath(c, property, quad.IRI("owl:cardinality").Full()) + it := p.BuildIterator(c.ctx).Iterate() + cardinality, err := intFromScanner(c.ctx, it, c.qs) + if err != nil { + return -1, fmt.Errorf("No cardinality is defined for property %v for class %v", property, c) + } + return cardinality, nil } +// MaxCardinalityOf returns the defined max cardinality for the property for the class +// If max cardinality is not defined for the class returns an error func (c *Class) MaxCardinalityOf(property Property) (int, error) { - panic("Not implemented") + p := propertyRestrictionsPath(c, property, quad.IRI("owl:maxCardinality").Full()) + it := p.BuildIterator(c.ctx).Iterate() + cardinality, err := intFromScanner(c.ctx, it, c.qs) + if err != nil { + return -1, fmt.Errorf("No maxCardinality is defined for property %v for class %v", property, c) + } + return cardinality, nil } -func (c *Class) SubClasses() []Class { - panic("Not implemented") +var subClassOf = quad.IRI(rdfs.SubClassOf).Full() + +// SubClasses returns all the classes defined as sub classes of the class +func (c *Class) SubClasses() []*Class { + p := c.path().In(subClassOf) + it := p.BuildIterator(c.ctx).Iterate() + var subClasses []*Class + for it.Next(c.ctx) { + class := classFromRef(c.ctx, c.qs, it.Result()) + subClasses = append(subClasses, class) + } + return subClasses } -func GetClass(qs graph.QuadStore, identifier quad.Value) Class { - return Class{Identifier: identifier} +// GetClass returns for given identifier a class object representing a class defined in given store. +// If the identifier is not of a class in the store returns an error. +func GetClass(ctx context.Context, qs graph.QuadStore, identifier quad.IRI) (*Class, error) { + ref := qs.ValueOf(identifier) + if ref == nil { + return nil, fmt.Errorf("Identifier %v does not exist in the store", identifier) + } + // TODO(iddan): validate given identifier is an OWL class + return &Class{Identifier: identifier, ref: ref, qs: qs, ctx: ctx}, nil } type Property struct { + ctx context.Context qs graph.QuadStore + ref graph.Ref Identifier quad.IRI } -func (p *Property) Range(property Property) quad.Value { - panic("Not implemented") +func GetProperty(ctx context.Context, qs graph.QuadStore, identifier quad.IRI) (*Property, error) { + ref := qs.ValueOf(identifier) + if ref == nil { + return nil, fmt.Errorf("Identifier %v does not exist in the store", identifier) + } + // TODO(iddan): validate given identifier is an OWL property + return &Property{ + ctx: ctx, + qs: qs, + ref: ref, + Identifier: identifier, + }, nil +} + +func propertyFromRef(ctx context.Context, qs graph.QuadStore, ref graph.Ref) (*Property, error) { + val := qs.NameOf(ref) + iri, ok := val.(quad.IRI) + if !ok { + return nil, fmt.Errorf("Predicate of unexpected type %t. Predicates should be IRIs", val) + } + return &Property{ + ctx: ctx, + qs: qs, + ref: ref, + Identifier: iri, + }, nil +} + +// Range returns the expected target type of a property +func (p *Property) Range() (quad.Value, error) { + rangePath := path.StartPath(p.qs, p.Identifier).Out(quad.IRI(rdfs.Range).Full()) + it := rangePath.BuildIterator(p.ctx).Iterate() + for it.Next(p.ctx) { + ref := it.Result() + value := p.qs.NameOf(ref) + return value, nil + } + return nil, fmt.Errorf("No range was defined for property %v", p) } diff --git a/owl/owl_test.go b/owl/owl_test.go new file mode 100644 index 000000000..f8b52254d --- /dev/null +++ b/owl/owl_test.go @@ -0,0 +1,54 @@ +package owl + +import ( + "context" + "testing" + + "github.com/cayleygraph/cayley/graph/memstore" + "github.com/cayleygraph/quad" + "github.com/cayleygraph/quad/voc/rdf" + "github.com/cayleygraph/quad/voc/rdfs" + "github.com/stretchr/testify/require" +) + +var fooID = quad.IRI("ex:Foo").Full() +var barID = quad.IRI("ex:Bar").Full() +var bazID = quad.IRI("ex:baz").Full() +var exampleGraph = quad.IRI("ex:graph") +var testSet = []quad.Quad{ + quad.Quad{Subject: fooID, Predicate: quad.IRI(rdf.Type).Full(), Object: quad.IRI(rdfs.SubClassOf).Full(), Label: exampleGraph}, + quad.Quad{Subject: barID, Predicate: quad.IRI(rdfs.SubClassOf).Full(), Object: fooID, Label: exampleGraph}, + quad.Quad{Subject: bazID, Predicate: quad.IRI(rdfs.Domain).Full(), Object: fooID, Label: exampleGraph}, +} + +func TestGetClass(t *testing.T) { + ctx := context.TODO() + qs := memstore.New(testSet...) + class, err := GetClass(ctx, qs, fooID) + require.NoError(t, err) + require.Equal(t, class.Identifier, fooID) +} + +func TestSubClasses(t *testing.T) { + ctx := context.TODO() + qs := memstore.New(testSet...) + fooClass, err := GetClass(ctx, qs, fooID) + require.NoError(t, err) + barClass, err := GetClass(ctx, qs, barID) + require.NoError(t, err) + subClasses := fooClass.SubClasses() + require.Len(t, subClasses, 1) + require.Contains(t, subClasses, barClass) +} + +func TestProperties(t *testing.T) { + ctx := context.TODO() + qs := memstore.New(testSet...) + fooClass, err := GetClass(ctx, qs, fooID) + require.NoError(t, err) + bazProperty, err := GetProperty(ctx, qs, bazID) + require.NoError(t, err) + properties := fooClass.Properties() + require.Len(t, properties, 1) + require.Contains(t, properties, bazProperty) +} From a4a2bc7748d2a861a229c689187261aed3eb5381 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Fri, 6 Dec 2019 14:32:20 +0200 Subject: [PATCH 04/27] Complete OWL module --- owl/owl.go | 53 +++++++++++----- owl/owl_test.go | 160 +++++++++++++++++++++++++++++++++++++++++++++++- owl/voc.go | 21 +++++++ 3 files changed, 214 insertions(+), 20 deletions(-) create mode 100644 owl/voc.go diff --git a/owl/owl.go b/owl/owl.go index 4df1751f2..c6144595a 100644 --- a/owl/owl.go +++ b/owl/owl.go @@ -46,7 +46,7 @@ func (c *Class) Properties() []*Property { ctx := context.TODO() p := c. path(). - Or(c.unionsPath().In(quad.IRI("http://www.w3.org/2002/07/owl#unionOf").Full())). + Or(c.unionsPath().In(quad.IRI("owl:unionOf").Full())). In(domain) it := p.BuildIterator(ctx).Iterate() var properties []*Property @@ -62,7 +62,7 @@ func (c *Class) Properties() []*Property { } func (c *Class) ParentClasses() []*Class { - it := c.path().Out(rdfs.SubClassOf).BuildIterator(c.ctx).Iterate() + it := parentClassesPath(c).BuildIterator(c.ctx).Iterate() var classes []*Class for it.Next(c.ctx) { class := classFromRef(c.ctx, c.qs, it.Result()) @@ -71,23 +71,42 @@ func (c *Class) ParentClasses() []*Class { return classes } -func propertyRestrictionsPath(c *Class, property Property, restrictionProperty quad.IRI) *path.Path { - subClassesPath := c.path().Out(quad.IRI(rdfs.SubClassOf).Full()) - restrictionsPath := subClassesPath.Has(quad.IRI(rdf.Type).Full(), quad.IRI("owl:Restriction").Full()) - propertyRestrictionsPath := restrictionsPath.Has(quad.IRI("owl:onProperty").Full(), property.Identifier) - return propertyRestrictionsPath.Out(restrictionProperty) +func parentClassesPath(c *Class) *path.Path { + return c.path().Out(quad.IRI(rdfs.SubClassOf).Full()) } -func intFromScanner(ctx context.Context, it iterator.Scanner, qs graph.QuadStore) (int, error) { +func restrictionsPath(c *Class) *path.Path { + return parentClassesPath(c). + Has(quad.IRI(rdf.Type).Full(), quad.IRI(Restriction)) +} + +func allPropertyRestrictionsPath(c *Class, property *Property) *path.Path { + return restrictionsPath(c). + Has(quad.IRI(OnProperty), property.Identifier) +} + +func propertyRestrictionPath(c *Class, property *Property, restrictionProperty quad.IRI) *path.Path { + return allPropertyRestrictionsPath(c, property). + Out(restrictionProperty) +} + +func intFromScanner(ctx context.Context, it iterator.Scanner, qs graph.QuadStore) (int64, error) { for it.Next(ctx) { ref := it.Result() value := qs.NameOf(ref) + intValue, ok := value.(quad.Int) + var native interface{} + if ok { + native = intValue.Native() + } typedString, ok := value.(quad.TypedString) - if !ok { + if ok { + native = typedString.Native() + } + if native == nil { return -1, fmt.Errorf("Unexpected value %v of type %t", value, value) } - native := typedString.Native() - i, ok := native.(int) + i, ok := native.(int64) if !ok { return -1, fmt.Errorf("Unexpected value %v of type %t", native, native) } @@ -98,24 +117,24 @@ func intFromScanner(ctx context.Context, it iterator.Scanner, qs graph.QuadStore // CardinalityOf returns the defined exact cardinality for the property for the class // If exact cardinality is not defined for the class returns an error -func (c *Class) CardinalityOf(property Property) (int, error) { - p := propertyRestrictionsPath(c, property, quad.IRI("owl:cardinality").Full()) +func (c *Class) CardinalityOf(property *Property) (int64, error) { + p := propertyRestrictionPath(c, property, quad.IRI(Cardinality)) it := p.BuildIterator(c.ctx).Iterate() cardinality, err := intFromScanner(c.ctx, it, c.qs) if err != nil { - return -1, fmt.Errorf("No cardinality is defined for property %v for class %v", property, c) + return -1, fmt.Errorf("No cardinality is defined for property %v for class %v", property.Identifier, c.Identifier) } return cardinality, nil } // MaxCardinalityOf returns the defined max cardinality for the property for the class // If max cardinality is not defined for the class returns an error -func (c *Class) MaxCardinalityOf(property Property) (int, error) { - p := propertyRestrictionsPath(c, property, quad.IRI("owl:maxCardinality").Full()) +func (c *Class) MaxCardinalityOf(property *Property) (int64, error) { + p := propertyRestrictionPath(c, property, quad.IRI(MaxCardinality)) it := p.BuildIterator(c.ctx).Iterate() cardinality, err := intFromScanner(c.ctx, it, c.qs) if err != nil { - return -1, fmt.Errorf("No maxCardinality is defined for property %v for class %v", property, c) + return -1, fmt.Errorf("No maxCardinality is defined for property %v for class %v", property.Identifier, c.Identifier) } return cardinality, nil } diff --git a/owl/owl_test.go b/owl/owl_test.go index f8b52254d..616e473b5 100644 --- a/owl/owl_test.go +++ b/owl/owl_test.go @@ -4,7 +4,9 @@ import ( "context" "testing" + "github.com/cayleygraph/cayley/graph" "github.com/cayleygraph/cayley/graph/memstore" + "github.com/cayleygraph/cayley/query/path" "github.com/cayleygraph/quad" "github.com/cayleygraph/quad/voc/rdf" "github.com/cayleygraph/quad/voc/rdfs" @@ -14,11 +16,82 @@ import ( var fooID = quad.IRI("ex:Foo").Full() var barID = quad.IRI("ex:Bar").Full() var bazID = quad.IRI("ex:baz").Full() +var fooBazCardinalityRestriction = quad.RandomBlankNode() +var barBazMaxCardinalityRestriction = quad.RandomBlankNode() var exampleGraph = quad.IRI("ex:graph") var testSet = []quad.Quad{ - quad.Quad{Subject: fooID, Predicate: quad.IRI(rdf.Type).Full(), Object: quad.IRI(rdfs.SubClassOf).Full(), Label: exampleGraph}, - quad.Quad{Subject: barID, Predicate: quad.IRI(rdfs.SubClassOf).Full(), Object: fooID, Label: exampleGraph}, - quad.Quad{Subject: bazID, Predicate: quad.IRI(rdfs.Domain).Full(), Object: fooID, Label: exampleGraph}, + quad.Quad{ + Subject: fooID, + Predicate: quad.IRI(rdf.Type).Full(), + Object: quad.IRI(rdfs.Class).Full(), + Label: exampleGraph, + }, + quad.Quad{ + Subject: fooID, + Predicate: quad.IRI(rdfs.SubClassOf).Full(), + Object: fooBazCardinalityRestriction, + Label: exampleGraph, + }, + quad.Quad{ + Subject: fooBazCardinalityRestriction, + Predicate: quad.IRI(rdf.Type).Full(), + Object: quad.IRI(Restriction), + Label: exampleGraph, + }, + quad.Quad{ + Subject: fooBazCardinalityRestriction, + Predicate: quad.IRI(OnProperty), + Object: bazID, + Label: exampleGraph, + }, + quad.Quad{ + Subject: fooBazCardinalityRestriction, + Predicate: quad.IRI(Cardinality), + Object: quad.Int(1), + Label: exampleGraph, + }, + quad.Quad{ + Subject: barBazMaxCardinalityRestriction, + Predicate: quad.IRI(rdf.Type).Full(), + Object: quad.IRI(Restriction), + Label: exampleGraph, + }, + quad.Quad{ + Subject: barBazMaxCardinalityRestriction, + Predicate: quad.IRI(OnProperty), + Object: bazID, + Label: exampleGraph, + }, + quad.Quad{ + Subject: barBazMaxCardinalityRestriction, + Predicate: quad.IRI(MaxCardinality), + Object: quad.Int(1), + Label: exampleGraph, + }, + quad.Quad{ + Subject: barID, + Predicate: quad.IRI(rdfs.SubClassOf).Full(), + Object: fooID, + Label: exampleGraph, + }, + quad.Quad{ + Subject: barID, + Predicate: quad.IRI(rdfs.SubClassOf).Full(), + Object: barBazMaxCardinalityRestriction, + Label: exampleGraph, + }, + quad.Quad{ + Subject: bazID, + Predicate: quad.IRI(rdfs.Domain).Full(), + Object: fooID, + Label: exampleGraph, + }, + quad.Quad{ + Subject: bazID, + Predicate: quad.IRI(rdfs.Range).Full(), + Object: barID, + Label: exampleGraph, + }, } func TestGetClass(t *testing.T) { @@ -52,3 +125,84 @@ func TestProperties(t *testing.T) { require.Len(t, properties, 1) require.Contains(t, properties, bazProperty) } + +func TestParentClasses(t *testing.T) { + ctx := context.TODO() + qs := memstore.New(testSet...) + fooClass, err := GetClass(ctx, qs, fooID) + require.NoError(t, err) + bazProperty, err := GetProperty(ctx, qs, bazID) + require.NoError(t, err) + properties := fooClass.Properties() + require.Len(t, properties, 1) + require.Contains(t, properties, bazProperty) +} + +func TestCardinalityOf(t *testing.T) { + ctx := context.TODO() + qs := memstore.New(testSet...) + fooClass, err := GetClass(ctx, qs, fooID) + require.NoError(t, err) + bazProperty, err := GetProperty(ctx, qs, bazID) + require.NoError(t, err) + cardinality, err := fooClass.CardinalityOf(bazProperty) + require.NoError(t, err) + require.Equal(t, cardinality, int64(1)) +} + +func TestMaxCardinalityOf(t *testing.T) { + ctx := context.TODO() + qs := memstore.New(testSet...) + fooClass, err := GetClass(ctx, qs, barID) + require.NoError(t, err) + bazProperty, err := GetProperty(ctx, qs, bazID) + require.NoError(t, err) + cardinality, err := fooClass.MaxCardinalityOf(bazProperty) + require.NoError(t, err) + require.Equal(t, cardinality, int64(1)) +} + +func TestRange(t *testing.T) { + ctx := context.TODO() + qs := memstore.New(testSet...) + bazProperty, err := GetProperty(ctx, qs, bazID) + require.NoError(t, err) + _range, err := bazProperty.Range() + require.NoError(t, err) + require.Equal(t, _range, barID) +} + +func collectPath(ctx context.Context, qs graph.QuadStore, p *path.Path) []quad.Value { + var values []quad.Value + it := p.BuildIterator(ctx).Iterate() + for it.Next(ctx) { + ref := it.Result() + value := qs.NameOf(ref) + values = append(values, value) + } + return values +} + +func TestParentClassesPath(t *testing.T) { + ctx := context.TODO() + qs := memstore.New(testSet...) + fooClass, err := GetClass(ctx, qs, fooID) + require.NoError(t, err) + p := parentClassesPath(fooClass) + values := collectPath(ctx, qs, p) + require.Equal(t, []quad.Value{ + fooBazCardinalityRestriction, + }, values) +} + +func TestRestrictionsPath(t *testing.T) { + ctx := context.TODO() + qs := memstore.New(testSet...) + fooClass, err := GetClass(ctx, qs, fooID) + require.NoError(t, err) + p := restrictionsPath(fooClass) + values := collectPath(ctx, qs, p) + require.Equal(t, []quad.Value{ + fooBazCardinalityRestriction, + }, values) +} diff --git a/owl/voc.go b/owl/voc.go new file mode 100644 index 000000000..7af2655ff --- /dev/null +++ b/owl/voc.go @@ -0,0 +1,21 @@ +// Package owl contains constants of the Web Ontology Language (OWL) +package owl + +import "github.com/cayleygraph/quad/voc" + +func init() { + voc.RegisterPrefix(Prefix, NS) +} + +const ( + NS = `http://www.w3.org/2002/07/owl#` + Prefix = `owl:` +) + +const ( + UnionOf = NS + "unionOf" + Restriction = NS + "Restriction" + OnProperty = NS + "onProperty" + Cardinality = NS + "cardinality" + MaxCardinality = NS + "maxCardinality" +) From 54fb844352abcd933f3d947cb8a3b70bc06cb0f7 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 14:39:23 +0200 Subject: [PATCH 05/27] Make union properties work --- owl/owl.go | 30 ++++--- owl/owl_test.go | 146 +++++++++++++++++++++++++------ query/linkedql/client/client2.go | 16 +++- 3 files changed, 151 insertions(+), 41 deletions(-) diff --git a/owl/owl.go b/owl/owl.go index c6144595a..d3efc6c65 100644 --- a/owl/owl.go +++ b/owl/owl.go @@ -24,9 +24,22 @@ func (c *Class) path() *path.Path { return path.StartPath(c.qs, c.Identifier) } -func (c *Class) unionsPath() *path.Path { - reverseListPath := path.NewPath(c.qs).In(quad.IRI(rdf.First).Full()) - return c.path().FollowRecursive(reverseListPath, 10, []string{}) +// listContainingPath returns a path of lists containing given value +func listContainignPath(qs graph.QuadStore, value quad.Value) *path.Path { + return path.StartPath(qs, value). + In(quad.IRI(rdf.First)). + Follow( + path.StartMorphism(). + Or( + path.StartMorphism(). + FollowRecursive( + path.StartMorphism(). + In(quad.IRI(rdf.Rest).Full()), + 0, + nil, + ), + ), + ) } func classFromRef(ctx context.Context, qs graph.QuadStore, ref graph.Ref) *Class { @@ -43,15 +56,12 @@ var domain = quad.IRI(rdfs.Domain).Full() // Properties return all the properties a class instance may have func (c *Class) Properties() []*Property { - ctx := context.TODO() - p := c. - path(). - Or(c.unionsPath().In(quad.IRI("owl:unionOf").Full())). + p := c.path().Or(listContainignPath(c.qs, c.Identifier).In(quad.IRI(UnionOf))). In(domain) - it := p.BuildIterator(ctx).Iterate() + it := p.BuildIterator(c.ctx).Iterate() var properties []*Property - for it.Next(ctx) { - property, err := propertyFromRef(ctx, c.qs, it.Result()) + for it.Next(c.ctx) { + property, err := propertyFromRef(c.ctx, c.qs, it.Result()) if err != nil { clog.Warningf(err.Error()) continue diff --git a/owl/owl_test.go b/owl/owl_test.go index 616e473b5..4d3488345 100644 --- a/owl/owl_test.go +++ b/owl/owl_test.go @@ -15,23 +15,42 @@ import ( var fooID = quad.IRI("ex:Foo").Full() var barID = quad.IRI("ex:Bar").Full() +var garID = quad.IRI("ex:Gar").Full() var bazID = quad.IRI("ex:baz").Full() +var fooBarGarUnion = quad.RandomBlankNode() var fooBazCardinalityRestriction = quad.RandomBlankNode() var barBazMaxCardinalityRestriction = quad.RandomBlankNode() var exampleGraph = quad.IRI("ex:graph") -var testSet = []quad.Quad{ +var fooClassQuads = []quad.Quad{ quad.Quad{ Subject: fooID, Predicate: quad.IRI(rdf.Type).Full(), Object: quad.IRI(rdfs.Class).Full(), Label: exampleGraph, }, +} +var bazPropertyQuads = []quad.Quad{ quad.Quad{ - Subject: fooID, + Subject: barID, Predicate: quad.IRI(rdfs.SubClassOf).Full(), - Object: fooBazCardinalityRestriction, + Object: fooID, + Label: exampleGraph, + }, + + quad.Quad{ + Subject: bazID, + Predicate: quad.IRI(rdfs.Domain).Full(), + Object: fooID, + Label: exampleGraph, + }, + quad.Quad{ + Subject: bazID, + Predicate: quad.IRI(rdfs.Range).Full(), + Object: barID, Label: exampleGraph, }, +} +var fooBazCardinalityRestrictionQuads = []quad.Quad{ quad.Quad{ Subject: fooBazCardinalityRestriction, Predicate: quad.IRI(rdf.Type).Full(), @@ -50,6 +69,14 @@ var testSet = []quad.Quad{ Object: quad.Int(1), Label: exampleGraph, }, + quad.Quad{ + Subject: fooID, + Predicate: quad.IRI(rdfs.SubClassOf).Full(), + Object: fooBazCardinalityRestriction, + Label: exampleGraph, + }, +} +var barBazCardinalityRestrictionQuad = []quad.Quad{ quad.Quad{ Subject: barBazMaxCardinalityRestriction, Predicate: quad.IRI(rdf.Type).Full(), @@ -68,35 +95,96 @@ var testSet = []quad.Quad{ Object: quad.Int(1), Label: exampleGraph, }, - quad.Quad{ - Subject: barID, - Predicate: quad.IRI(rdfs.SubClassOf).Full(), - Object: fooID, - Label: exampleGraph, - }, quad.Quad{ Subject: barID, Predicate: quad.IRI(rdfs.SubClassOf).Full(), Object: barBazMaxCardinalityRestriction, Label: exampleGraph, }, - quad.Quad{ - Subject: bazID, - Predicate: quad.IRI(rdfs.Domain).Full(), - Object: fooID, - Label: exampleGraph, - }, - quad.Quad{ - Subject: bazID, - Predicate: quad.IRI(rdfs.Range).Full(), - Object: barID, +} + +func listQuads(items []quad.Value, label quad.Value) (quad.Value, []quad.Quad) { + var quads []quad.Quad + list := quad.RandomBlankNode() + cursor := list + for i, item := range items { + first := quad.Quad{ + Subject: cursor, + Predicate: quad.IRI(rdf.First).Full(), + Object: item, + Label: label, + } + var rest quad.Quad + if i < len(items)-1 { + rest = quad.Quad{ + Subject: cursor, + Predicate: quad.IRI(rdf.Rest).Full(), + Object: quad.IRI(rdf.Nil).Full(), + Label: label, + } + } else { + nextCursor := quad.RandomBlankNode() + rest = quad.Quad{ + Subject: cursor, + Predicate: quad.IRI(rdf.Rest).Full(), + Object: nextCursor, + Label: label, + } + cursor = nextCursor + } + quads = append(quads, first, rest) + } + return list, quads +} + +func getUnionQuads() []quad.Quad { + var unionQuads []quad.Quad + membersList, membersQuads := listQuads( + []quad.Value{fooID, barID, garID}, + exampleGraph, + ) + unionQuads = append(unionQuads, membersQuads...) + unionQuads = append(unionQuads, quad.Quad{ + Subject: fooBarGarUnion, + Predicate: quad.IRI(UnionOf), + Object: membersList, Label: exampleGraph, - }, + }) + return unionQuads +} + +func getTestSet() []quad.Quad { + var testSet []quad.Quad + testSet = append(testSet, fooBazCardinalityRestrictionQuads...) + testSet = append(testSet, barBazCardinalityRestrictionQuad...) + testSet = append(testSet, bazPropertyQuads...) + testSet = append(testSet, getUnionQuads()...) + return testSet +} + +func TestListContainingPath(t *testing.T) { + ctx := context.TODO() + qs := memstore.New(getTestSet()...) + p := listContainignPath(qs, fooID).In(quad.IRI(UnionOf)) + values := collectPath(ctx, qs, p) + require.Equal(t, []quad.Value{ + fooBarGarUnion, + }, values) + p = listContainignPath(qs, barID).In(quad.IRI(UnionOf)) + values = collectPath(ctx, qs, p) + require.Equal(t, []quad.Value{ + fooBarGarUnion, + }, values) + p = listContainignPath(qs, garID).In(quad.IRI(UnionOf)) + values = collectPath(ctx, qs, p) + require.Equal(t, []quad.Value{ + fooBarGarUnion, + }, values) } func TestGetClass(t *testing.T) { ctx := context.TODO() - qs := memstore.New(testSet...) + qs := memstore.New(getTestSet()...) class, err := GetClass(ctx, qs, fooID) require.NoError(t, err) require.Equal(t, class.Identifier, fooID) @@ -104,7 +192,7 @@ func TestGetClass(t *testing.T) { func TestSubClasses(t *testing.T) { ctx := context.TODO() - qs := memstore.New(testSet...) + qs := memstore.New(getTestSet()...) fooClass, err := GetClass(ctx, qs, fooID) require.NoError(t, err) barClass, err := GetClass(ctx, qs, barID) @@ -116,7 +204,7 @@ func TestSubClasses(t *testing.T) { func TestProperties(t *testing.T) { ctx := context.TODO() - qs := memstore.New(testSet...) + qs := memstore.New(getTestSet()...) fooClass, err := GetClass(ctx, qs, fooID) require.NoError(t, err) bazProperty, err := GetProperty(ctx, qs, bazID) @@ -128,7 +216,7 @@ func TestProperties(t *testing.T) { func TestParentClasses(t *testing.T) { ctx := context.TODO() - qs := memstore.New(testSet...) + qs := memstore.New(getTestSet()...) fooClass, err := GetClass(ctx, qs, fooID) require.NoError(t, err) bazProperty, err := GetProperty(ctx, qs, bazID) @@ -140,7 +228,7 @@ func TestParentClasses(t *testing.T) { func TestCardinalityOf(t *testing.T) { ctx := context.TODO() - qs := memstore.New(testSet...) + qs := memstore.New(getTestSet()...) fooClass, err := GetClass(ctx, qs, fooID) require.NoError(t, err) bazProperty, err := GetProperty(ctx, qs, bazID) @@ -152,7 +240,7 @@ func TestCardinalityOf(t *testing.T) { func TestMaxCardinalityOf(t *testing.T) { ctx := context.TODO() - qs := memstore.New(testSet...) + qs := memstore.New(getTestSet()...) fooClass, err := GetClass(ctx, qs, barID) require.NoError(t, err) bazProperty, err := GetProperty(ctx, qs, bazID) @@ -164,7 +252,7 @@ func TestMaxCardinalityOf(t *testing.T) { func TestRange(t *testing.T) { ctx := context.TODO() - qs := memstore.New(testSet...) + qs := memstore.New(getTestSet()...) bazProperty, err := GetProperty(ctx, qs, bazID) require.NoError(t, err) _range, err := bazProperty.Range() @@ -185,7 +273,7 @@ func collectPath(ctx context.Context, qs graph.QuadStore, p *path.Path) []quad.V func TestParentClassesPath(t *testing.T) { ctx := context.TODO() - qs := memstore.New(testSet...) + qs := memstore.New(getTestSet()...) fooClass, err := GetClass(ctx, qs, fooID) require.NoError(t, err) p := parentClassesPath(fooClass) @@ -197,7 +285,7 @@ func TestParentClassesPath(t *testing.T) { func TestRestrictionsPath(t *testing.T) { ctx := context.TODO() - qs := memstore.New(testSet...) + qs := memstore.New(getTestSet()...) fooClass, err := GetClass(ctx, qs, fooID) require.NoError(t, err) p := restrictionsPath(fooClass) diff --git a/query/linkedql/client/client2.go b/query/linkedql/client/client2.go index 0a0534b28..f8579276c 100644 --- a/query/linkedql/client/client2.go +++ b/query/linkedql/client/client2.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "context" "encoding/json" "fmt" "go/ast" @@ -43,10 +44,21 @@ func loadSchema() (graph.QuadStore, error) { func main() { qs, err := loadSchema() - stepClass := owl.GetClass(qs, quad.IRI("linkedql:Step")) + ctx := context.TODO() + stepClass, err := owl.GetClass(ctx, qs, quad.IRI("http://cayley.io/linkedql#PathStep")) + + if err != nil { + panic(err) + } + stepSubClasses := stepClass.SubClasses() - fmt.Printf("%v\n", stepSubClasses) + for _, stepSubClass := range stepSubClasses { + properties := stepSubClass.Properties() + if properties == nil { + fmt.Printf("%v has no properties\n", stepSubClass) + } + } if err != nil { panic(err) From 49eb81eb2a5ded842e4b148210e6aad4f30e7c5f Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 14:44:51 +0200 Subject: [PATCH 06/27] Correct list containing --- owl/owl.go | 18 ++++-------------- owl/owl_test.go | 3 +++ query/linkedql/client/client2.go | 5 +++-- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/owl/owl.go b/owl/owl.go index d3efc6c65..73f890f18 100644 --- a/owl/owl.go +++ b/owl/owl.go @@ -26,20 +26,10 @@ func (c *Class) path() *path.Path { // listContainingPath returns a path of lists containing given value func listContainignPath(qs graph.QuadStore, value quad.Value) *path.Path { - return path.StartPath(qs, value). - In(quad.IRI(rdf.First)). - Follow( - path.StartMorphism(). - Or( - path.StartMorphism(). - FollowRecursive( - path.StartMorphism(). - In(quad.IRI(rdf.Rest).Full()), - 0, - nil, - ), - ), - ) + firstPath := path.StartPath(qs, value).In(quad.IRI(rdf.First).Full()) + return firstPath.Or( + firstPath.FollowRecursive(path.StartMorphism().In(quad.IRI(rdf.Rest).Full()), 0, nil), + ) } func classFromRef(ctx context.Context, qs graph.QuadStore, ref graph.Ref) *Class { diff --git a/owl/owl_test.go b/owl/owl_test.go index 4d3488345..815b145ea 100644 --- a/owl/owl_test.go +++ b/owl/owl_test.go @@ -180,6 +180,9 @@ func TestListContainingPath(t *testing.T) { require.Equal(t, []quad.Value{ fooBarGarUnion, }, values) + p = listContainignPath(qs, bazID).In(quad.IRI(UnionOf)) + values = collectPath(ctx, qs, p) + require.Equal(t, []quad.Value(nil), values) } func TestGetClass(t *testing.T) { diff --git a/query/linkedql/client/client2.go b/query/linkedql/client/client2.go index f8579276c..0a8bafd6b 100644 --- a/query/linkedql/client/client2.go +++ b/query/linkedql/client/client2.go @@ -54,9 +54,10 @@ func main() { stepSubClasses := stepClass.SubClasses() for _, stepSubClass := range stepSubClasses { + fmt.Printf("%v\n", stepSubClass.Identifier) properties := stepSubClass.Properties() - if properties == nil { - fmt.Printf("%v has no properties\n", stepSubClass) + for _, property := range properties { + fmt.Printf("\t%v\n", property.Identifier) } } From a3ab0c45607b00858e45a69badf820f2bb0d5a22 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 15:35:17 +0200 Subject: [PATCH 07/27] Creating a basic file, types are still not correct --- owl/owl.go | 7 +- query/linkedql/client/client2.go | 144 ++++++++++++++++++++++++++++--- 2 files changed, 134 insertions(+), 17 deletions(-) diff --git a/owl/owl.go b/owl/owl.go index 73f890f18..5d28bf42f 100644 --- a/owl/owl.go +++ b/owl/owl.go @@ -46,6 +46,7 @@ var domain = quad.IRI(rdfs.Domain).Full() // Properties return all the properties a class instance may have func (c *Class) Properties() []*Property { + // TODO(@iddan): check for super classes properties p := c.path().Or(listContainignPath(c.qs, c.Identifier).In(quad.IRI(UnionOf))). In(domain) it := p.BuildIterator(c.ctx).Iterate() @@ -104,11 +105,11 @@ func intFromScanner(ctx context.Context, it iterator.Scanner, qs graph.QuadStore native = typedString.Native() } if native == nil { - return -1, fmt.Errorf("Unexpected value %v of type %t", value, value) + return -1, fmt.Errorf("Unexpected value %v of type %T", value, value) } i, ok := native.(int64) if !ok { - return -1, fmt.Errorf("Unexpected value %v of type %t", native, native) + return -1, fmt.Errorf("Unexpected value %v of type %T", native, native) } return i, nil } @@ -189,7 +190,7 @@ func propertyFromRef(ctx context.Context, qs graph.QuadStore, ref graph.Ref) (*P val := qs.NameOf(ref) iri, ok := val.(quad.IRI) if !ok { - return nil, fmt.Errorf("Predicate of unexpected type %t. Predicates should be IRIs", val) + return nil, fmt.Errorf("Predicate of unexpected type %T. Predicates should be IRIs", val) } return &Property{ ctx: ctx, diff --git a/query/linkedql/client/client2.go b/query/linkedql/client/client2.go index 0a8bafd6b..f14c4e9e8 100644 --- a/query/linkedql/client/client2.go +++ b/query/linkedql/client/client2.go @@ -7,6 +7,7 @@ import ( "fmt" "go/ast" "go/format" + "go/parser" "go/token" "io" "os" @@ -41,6 +42,10 @@ func loadSchema() (graph.QuadStore, error) { return qs, nil } +func iriToIdent(iri quad.IRI) *ast.Ident { + return ast.NewIdent(string(iri)[26:]) +} + func main() { qs, err := loadSchema() @@ -52,34 +57,145 @@ func main() { } stepSubClasses := stepClass.SubClasses() + var decls []ast.Decl for _, stepSubClass := range stepSubClasses { - fmt.Printf("%v\n", stepSubClass.Identifier) + iri, ok := stepSubClass.Identifier.(quad.IRI) + if !ok { + panic(fmt.Errorf("Unexpected class identifier %v of type %T", stepSubClass.Identifier, stepSubClass.Identifier)) + } properties := stepSubClass.Properties() + + var paramsList []*ast.Field + for _, property := range properties { + paramsList = append(paramsList, &ast.Field{ + Names: []*ast.Ident{iriToIdent(property.Identifier)}, + Type: ast.NewIdent("string"), + }) + } + + stmtList := []ast.Stmt{ + &ast.AssignStmt{ + Lhs: []ast.Expr{ + ast.NewIdent("s"), + }, + Rhs: []ast.Expr{ + &ast.CompositeLit{ + Type: ast.NewIdent("step"), + Elts: []ast.Expr{ + &ast.KeyValueExpr{ + Key: &ast.BasicLit{ + Kind: token.STRING, + Value: "\"@type\"", + }, + Value: &ast.BasicLit{ + Kind: token.STRING, + Value: "\"" + string(iri) + "\"", + }, + }, + }, + }, + }, + Tok: token.DEFINE, + }, + } for _, property := range properties { - fmt.Printf("\t%v\n", property.Identifier) + stmtList = append(stmtList, &ast.AssignStmt{ + Lhs: []ast.Expr{ + &ast.IndexExpr{ + Index: &ast.BasicLit{ + Kind: token.STRING, + Value: "\"" + string(property.Identifier) + "\"", + }, + X: ast.NewIdent("s"), + }, + }, + Rhs: []ast.Expr{ + iriToIdent(property.Identifier), + }, + Tok: token.ASSIGN, + }) } + stmtList = append(stmtList, &ast.ReturnStmt{ + Results: []ast.Expr{ + &ast.UnaryExpr{ + Op: token.AND, + X: &ast.CompositeLit{ + Type: ast.NewIdent("Path"), + Elts: []ast.Expr{ + &ast.KeyValueExpr{ + Key: ast.NewIdent("steps"), + Value: &ast.CallExpr{ + Fun: ast.NewIdent("append"), + Args: []ast.Expr{ + &ast.SelectorExpr{ + Sel: ast.NewIdent("steps"), + X: ast.NewIdent("p"), + }, + ast.NewIdent("s"), + }, + }, + }, + }, + }, + }, + }, + }) + + decls = append(decls, &ast.FuncDecl{ + Name: iriToIdent(iri), + Type: &ast.FuncType{ + Params: &ast.FieldList{List: paramsList}, + Results: &ast.FieldList{ + List: []*ast.Field{ + &ast.Field{ + Names: nil, + Type: &ast.StarExpr{ + X: ast.NewIdent("Path"), + }, + }, + }, + }, + }, + Recv: &ast.FieldList{ + List: []*ast.Field{ + &ast.Field{ + Names: []*ast.Ident{ast.NewIdent("p")}, + Type: &ast.StarExpr{ + X: ast.NewIdent("Path"), + }, + }, + }, + }, + Body: &ast.BlockStmt{ + List: stmtList, + }, + }) } if err != nil { panic(err) } - file := &ast.File{ - Name: ast.NewIdent("example"), - Decls: []ast.Decl{ - &ast.FuncDecl{ - Name: ast.NewIdent("foo"), - Type: &ast.FuncType{ - Params: &ast.FieldList{}, - Results: &ast.FieldList{}, - }, - }, - }, - } // Create a FileSet for node. Since the node does not come // from a real source file, fset will be empty. fset := token.NewFileSet() + src := ` +package client + +type step map[string]interface{} + +type Path struct { + steps []step +} + ` + file, err := parser.ParseFile(fset, "", src, 0) + + if err != nil { + panic(err) + } + + file.Decls = append(file.Decls, decls...) var buf bytes.Buffer err = format.Node(&buf, fset, file) From 38d9a37c65a08564f5130e43c0b92ad12bfa9249 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 15:37:07 +0200 Subject: [PATCH 08/27] Remove old client files --- query/linkedql/client/client.go | 71 ---------------------------- query/linkedql/client/client_test.go | 13 ----- 2 files changed, 84 deletions(-) delete mode 100644 query/linkedql/client/client.go delete mode 100644 query/linkedql/client/client_test.go diff --git a/query/linkedql/client/client.go b/query/linkedql/client/client.go deleted file mode 100644 index 22727aa89..000000000 --- a/query/linkedql/client/client.go +++ /dev/null @@ -1,71 +0,0 @@ -package client - -import ( - "encoding/json" - "fmt" - "go/format" - "io/ioutil" - "os" -) - -type StepType struct { - ID string `json:"@id"` - Type string `json:"@type"` - Comment string `json:"rdfs:comment"` -} - -func GenerateClient() (string, error) { - jsonFile, err := os.Open("schema.json") - if err != nil { - return "", err - } - byteValue, _ := ioutil.ReadAll(jsonFile) - var a []StepType - err = json.Unmarshal(byteValue, &a) - if err != nil { - return "", err - } - fmt.Printf("%v\n", a) - src := ` -package client - -type Step map[string]interface{} - -type Path struct{ - cursor Step -} -` - stepName := "Vertex" - argumentNames := []string{ - "values", - } - argumentsString := "" - for _, argument := range argumentNames { - argumentsString += argument + " " + "[]interface{}" - } - fieldsString := "" - for _, argument := range argumentNames { - fieldsString += "\n\"" + argument + "\": " + argument + "," - } - generated := fmt.Sprintf(` -func (p *Path) %s (%s) *Path { - return Path{ - cursor: Step{ - "@type": "linkedql:%s", - "from": p.cursor,%s - }, - } -} - `, stepName, argumentsString, stepName, fieldsString) - - all := src + generated - - formatted, err := format.Source([]byte(all)) - formattedStr := string(formatted) - - if err != nil { - return "", err - } - - return formattedStr, nil -} diff --git a/query/linkedql/client/client_test.go b/query/linkedql/client/client_test.go deleted file mode 100644 index d61ecd3a9..000000000 --- a/query/linkedql/client/client_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package client - -import "testing" - -import "fmt" - -func TestGenerateClient(t *testing.T) { - code, err := GenerateClient() - if err != nil { - panic(err) - } - fmt.Println(code) -} From c57f5f4687867dd6e22884f40c4e772da3b9d55d Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 15:38:08 +0200 Subject: [PATCH 09/27] Rename client2 to generate_client.go --- query/linkedql/client/{client2.go => generate_client.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename query/linkedql/client/{client2.go => generate_client.go} (100%) diff --git a/query/linkedql/client/client2.go b/query/linkedql/client/generate_client.go similarity index 100% rename from query/linkedql/client/client2.go rename to query/linkedql/client/generate_client.go From 5abd1d801447eea8e98d6101b07daa44d8bff0fe Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 15:41:10 +0200 Subject: [PATCH 10/27] Share identifier vars --- query/linkedql/client/generate_client.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/query/linkedql/client/generate_client.go b/query/linkedql/client/generate_client.go index f14c4e9e8..5460e10ae 100644 --- a/query/linkedql/client/generate_client.go +++ b/query/linkedql/client/generate_client.go @@ -46,6 +46,11 @@ func iriToIdent(iri quad.IRI) *ast.Ident { return ast.NewIdent(string(iri)[26:]) } +var stepTypeIdent = ast.NewIdent("step") +var stepIdent = ast.NewIdent("s") +var pathTypeIdent = ast.NewIdent("Path") +var pathIdent = ast.NewIdent("p") + func main() { qs, err := loadSchema() @@ -77,11 +82,11 @@ func main() { stmtList := []ast.Stmt{ &ast.AssignStmt{ Lhs: []ast.Expr{ - ast.NewIdent("s"), + stepIdent, }, Rhs: []ast.Expr{ &ast.CompositeLit{ - Type: ast.NewIdent("step"), + Type: stepTypeIdent, Elts: []ast.Expr{ &ast.KeyValueExpr{ Key: &ast.BasicLit{ @@ -107,7 +112,7 @@ func main() { Kind: token.STRING, Value: "\"" + string(property.Identifier) + "\"", }, - X: ast.NewIdent("s"), + X: stepIdent, }, }, Rhs: []ast.Expr{ @@ -121,7 +126,7 @@ func main() { &ast.UnaryExpr{ Op: token.AND, X: &ast.CompositeLit{ - Type: ast.NewIdent("Path"), + Type: pathTypeIdent, Elts: []ast.Expr{ &ast.KeyValueExpr{ Key: ast.NewIdent("steps"), @@ -130,9 +135,9 @@ func main() { Args: []ast.Expr{ &ast.SelectorExpr{ Sel: ast.NewIdent("steps"), - X: ast.NewIdent("p"), + X: pathIdent, }, - ast.NewIdent("s"), + stepIdent, }, }, }, @@ -151,7 +156,7 @@ func main() { &ast.Field{ Names: nil, Type: &ast.StarExpr{ - X: ast.NewIdent("Path"), + X: pathTypeIdent, }, }, }, @@ -160,9 +165,9 @@ func main() { Recv: &ast.FieldList{ List: []*ast.Field{ &ast.Field{ - Names: []*ast.Ident{ast.NewIdent("p")}, + Names: []*ast.Ident{pathIdent}, Type: &ast.StarExpr{ - X: ast.NewIdent("Path"), + X: pathTypeIdent, }, }, }, From dbf4493a72992d0b6693c49edd9e653b2a11cacd Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 16:01:20 +0200 Subject: [PATCH 11/27] Correct value types --- query/linkedql/client/generate_client.go | 49 +++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/query/linkedql/client/generate_client.go b/query/linkedql/client/generate_client.go index 5460e10ae..e3f635539 100644 --- a/query/linkedql/client/generate_client.go +++ b/query/linkedql/client/generate_client.go @@ -46,6 +46,49 @@ func iriToIdent(iri quad.IRI) *ast.Ident { return ast.NewIdent(string(iri)[26:]) } +func propertyToValueType(class *owl.Class, property *owl.Property) (ast.Expr, error) { + _range, err := property.Range() + if err != nil { + return nil, err + } + isPTR := false + isSlice := true + cardinality, err := class.CardinalityOf(property) + if err != nil && cardinality == 1 { + isSlice = false + isPTR = false + } + maxCardinality, err := class.MaxCardinalityOf(property) + if err != nil && maxCardinality == 1 { + isSlice = false + isPTR = true + } + var t ast.Expr + if _range == quad.IRI("http://www.w3.org/2001/XMLSchema#string") { + t = ast.NewIdent("string") + } else if _range == quad.IRI("http://cayley.io/linkedql#PathStep") { + // TOOD star expr + t = &ast.StarExpr{ + X: ast.NewIdent("Path"), + } + } else if _range == quad.IRI("http://www.w3.org/2000/01/rdf-schema#Resource") { + t = ast.NewIdent("Value") + } else { + return nil, fmt.Errorf("Unexpected range %v", _range) + } + if isPTR { + t = &ast.StarExpr{ + X: t, + } + } + if isSlice { + t = &ast.ArrayType{ + Elt: t, + } + } + return t, nil +} + var stepTypeIdent = ast.NewIdent("step") var stepIdent = ast.NewIdent("s") var pathTypeIdent = ast.NewIdent("Path") @@ -73,9 +116,13 @@ func main() { var paramsList []*ast.Field for _, property := range properties { + _type, err := propertyToValueType(stepSubClass, property) + if err != nil { + panic(err) + } paramsList = append(paramsList, &ast.Field{ Names: []*ast.Ident{iriToIdent(property.Identifier)}, - Type: ast.NewIdent("string"), + Type: _type, }) } From fce236766fca3dd8d4e4cfdde14860e932656b65 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 16:16:20 +0200 Subject: [PATCH 12/27] Correct slice types --- query/linkedql/client/generate_client.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/query/linkedql/client/generate_client.go b/query/linkedql/client/generate_client.go index e3f635539..0c93ff2a9 100644 --- a/query/linkedql/client/generate_client.go +++ b/query/linkedql/client/generate_client.go @@ -51,15 +51,15 @@ func propertyToValueType(class *owl.Class, property *owl.Property) (ast.Expr, er if err != nil { return nil, err } - isPTR := false isSlice := true + isPTR := false cardinality, err := class.CardinalityOf(property) - if err != nil && cardinality == 1 { + if cardinality == int64(1) { isSlice = false isPTR = false } maxCardinality, err := class.MaxCardinalityOf(property) - if err != nil && maxCardinality == 1 { + if maxCardinality == int64(1) { isSlice = false isPTR = true } From e7219c42bd6c7f12e73714589ef209999ca0aef4 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 16:22:36 +0200 Subject: [PATCH 13/27] Don't use Path ptr --- query/linkedql/client/generate_client.go | 46 +++++++++++------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/query/linkedql/client/generate_client.go b/query/linkedql/client/generate_client.go index 0c93ff2a9..001a3be42 100644 --- a/query/linkedql/client/generate_client.go +++ b/query/linkedql/client/generate_client.go @@ -67,10 +67,7 @@ func propertyToValueType(class *owl.Class, property *owl.Property) (ast.Expr, er if _range == quad.IRI("http://www.w3.org/2001/XMLSchema#string") { t = ast.NewIdent("string") } else if _range == quad.IRI("http://cayley.io/linkedql#PathStep") { - // TOOD star expr - t = &ast.StarExpr{ - X: ast.NewIdent("Path"), - } + t = ast.NewIdent("Path") } else if _range == quad.IRI("http://www.w3.org/2000/01/rdf-schema#Resource") { t = ast.NewIdent("Value") } else { @@ -113,6 +110,7 @@ func main() { panic(fmt.Errorf("Unexpected class identifier %v of type %T", stepSubClass.Identifier, stepSubClass.Identifier)) } properties := stepSubClass.Properties() + propertyToType := make(map[quad.IRI]ast.Expr) var paramsList []*ast.Field for _, property := range properties { @@ -120,6 +118,7 @@ func main() { if err != nil { panic(err) } + propertyToType[property.Identifier] = _type paramsList = append(paramsList, &ast.Field{ Names: []*ast.Ident{iriToIdent(property.Identifier)}, Type: _type, @@ -152,6 +151,8 @@ func main() { }, } for _, property := range properties { + rhs := iriToIdent(property.Identifier) + // t := propertyToType[property.Identifier] stmtList = append(stmtList, &ast.AssignStmt{ Lhs: []ast.Expr{ &ast.IndexExpr{ @@ -163,29 +164,26 @@ func main() { }, }, Rhs: []ast.Expr{ - iriToIdent(property.Identifier), + rhs, }, Tok: token.ASSIGN, }) } stmtList = append(stmtList, &ast.ReturnStmt{ Results: []ast.Expr{ - &ast.UnaryExpr{ - Op: token.AND, - X: &ast.CompositeLit{ - Type: pathTypeIdent, - Elts: []ast.Expr{ - &ast.KeyValueExpr{ - Key: ast.NewIdent("steps"), - Value: &ast.CallExpr{ - Fun: ast.NewIdent("append"), - Args: []ast.Expr{ - &ast.SelectorExpr{ - Sel: ast.NewIdent("steps"), - X: pathIdent, - }, - stepIdent, + &ast.CompositeLit{ + Type: pathTypeIdent, + Elts: []ast.Expr{ + &ast.KeyValueExpr{ + Key: ast.NewIdent("steps"), + Value: &ast.CallExpr{ + Fun: ast.NewIdent("append"), + Args: []ast.Expr{ + &ast.SelectorExpr{ + Sel: ast.NewIdent("steps"), + X: pathIdent, }, + stepIdent, }, }, }, @@ -202,9 +200,7 @@ func main() { List: []*ast.Field{ &ast.Field{ Names: nil, - Type: &ast.StarExpr{ - X: pathTypeIdent, - }, + Type: pathTypeIdent, }, }, }, @@ -213,9 +209,7 @@ func main() { List: []*ast.Field{ &ast.Field{ Names: []*ast.Ident{pathIdent}, - Type: &ast.StarExpr{ - X: pathTypeIdent, - }, + Type: pathTypeIdent, }, }, }, From ce6b1c63181b686b2a42d7c9b75488748bd01aba Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 16:30:07 +0200 Subject: [PATCH 14/27] Correctly use path arguments --- query/linkedql/client/generate_client.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/query/linkedql/client/generate_client.go b/query/linkedql/client/generate_client.go index 001a3be42..29dff729f 100644 --- a/query/linkedql/client/generate_client.go +++ b/query/linkedql/client/generate_client.go @@ -67,7 +67,7 @@ func propertyToValueType(class *owl.Class, property *owl.Property) (ast.Expr, er if _range == quad.IRI("http://www.w3.org/2001/XMLSchema#string") { t = ast.NewIdent("string") } else if _range == quad.IRI("http://cayley.io/linkedql#PathStep") { - t = ast.NewIdent("Path") + t = pathTypeIdent } else if _range == quad.IRI("http://www.w3.org/2000/01/rdf-schema#Resource") { t = ast.NewIdent("Value") } else { @@ -151,8 +151,15 @@ func main() { }, } for _, property := range properties { - rhs := iriToIdent(property.Identifier) - // t := propertyToType[property.Identifier] + var rhs ast.Expr + rhs = iriToIdent(property.Identifier) + t := propertyToType[property.Identifier] + if t == pathTypeIdent { + rhs = &ast.SelectorExpr{ + Sel: ast.NewIdent("steps"), + X: rhs, + } + } stmtList = append(stmtList, &ast.AssignStmt{ Lhs: []ast.Expr{ &ast.IndexExpr{ From bd77eb989e162b734ac56423aca5b4056e5829a0 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 16:45:52 +0200 Subject: [PATCH 15/27] Correct path creation --- query/linkedql/client/generate_client.go | 124 ++++++++++------------- 1 file changed, 54 insertions(+), 70 deletions(-) diff --git a/query/linkedql/client/generate_client.go b/query/linkedql/client/generate_client.go index 29dff729f..8beb84f8d 100644 --- a/query/linkedql/client/generate_client.go +++ b/query/linkedql/client/generate_client.go @@ -46,6 +46,11 @@ func iriToIdent(iri quad.IRI) *ast.Ident { return ast.NewIdent(string(iri)[26:]) } +var quadValueType = &ast.SelectorExpr{ + Sel: ast.NewIdent("Value"), + X: ast.NewIdent("quad"), +} + func propertyToValueType(class *owl.Class, property *owl.Property) (ast.Expr, error) { _range, err := property.Range() if err != nil { @@ -69,7 +74,7 @@ func propertyToValueType(class *owl.Class, property *owl.Property) (ast.Expr, er } else if _range == quad.IRI("http://cayley.io/linkedql#PathStep") { t = pathTypeIdent } else if _range == quad.IRI("http://www.w3.org/2000/01/rdf-schema#Resource") { - t = ast.NewIdent("Value") + t = quadValueType } else { return nil, fmt.Errorf("Unexpected range %v", _range) } @@ -86,8 +91,6 @@ func propertyToValueType(class *owl.Class, property *owl.Property) (ast.Expr, er return t, nil } -var stepTypeIdent = ast.NewIdent("step") -var stepIdent = ast.NewIdent("s") var pathTypeIdent = ast.NewIdent("Path") var pathIdent = ast.NewIdent("p") @@ -119,85 +122,57 @@ func main() { panic(err) } propertyToType[property.Identifier] = _type + ident := iriToIdent(property.Identifier) + if ident.Name == "from" { + continue + } paramsList = append(paramsList, &ast.Field{ - Names: []*ast.Ident{iriToIdent(property.Identifier)}, + Names: []*ast.Ident{ident}, Type: _type, }) } - - stmtList := []ast.Stmt{ - &ast.AssignStmt{ - Lhs: []ast.Expr{ - stepIdent, + elts := []ast.Expr{ + &ast.KeyValueExpr{ + Key: &ast.BasicLit{ + Kind: token.STRING, + Value: "\"@type\"", }, - Rhs: []ast.Expr{ - &ast.CompositeLit{ - Type: stepTypeIdent, - Elts: []ast.Expr{ - &ast.KeyValueExpr{ - Key: &ast.BasicLit{ - Kind: token.STRING, - Value: "\"@type\"", - }, - Value: &ast.BasicLit{ - Kind: token.STRING, - Value: "\"" + string(iri) + "\"", - }, - }, - }, - }, + Value: &ast.BasicLit{ + Kind: token.STRING, + Value: "\"" + string(iri) + "\"", }, - Tok: token.DEFINE, + }, + &ast.KeyValueExpr{ + Key: &ast.BasicLit{ + Kind: token.STRING, + Value: "\"from\"", + }, + Value: pathIdent, }, } + for _, property := range properties { - var rhs ast.Expr - rhs = iriToIdent(property.Identifier) + ident := iriToIdent(property.Identifier) + if ident.Name == "from" { + continue + } + var value ast.Expr + value = iriToIdent(property.Identifier) t := propertyToType[property.Identifier] if t == pathTypeIdent { - rhs = &ast.SelectorExpr{ + value = &ast.SelectorExpr{ Sel: ast.NewIdent("steps"), - X: rhs, + X: value, } } - stmtList = append(stmtList, &ast.AssignStmt{ - Lhs: []ast.Expr{ - &ast.IndexExpr{ - Index: &ast.BasicLit{ - Kind: token.STRING, - Value: "\"" + string(property.Identifier) + "\"", - }, - X: stepIdent, - }, - }, - Rhs: []ast.Expr{ - rhs, + elts = append(elts, &ast.KeyValueExpr{ + Key: &ast.BasicLit{ + Kind: token.STRING, + Value: "\"" + string(property.Identifier) + "\"", }, - Tok: token.ASSIGN, + Value: value, }) } - stmtList = append(stmtList, &ast.ReturnStmt{ - Results: []ast.Expr{ - &ast.CompositeLit{ - Type: pathTypeIdent, - Elts: []ast.Expr{ - &ast.KeyValueExpr{ - Key: ast.NewIdent("steps"), - Value: &ast.CallExpr{ - Fun: ast.NewIdent("append"), - Args: []ast.Expr{ - &ast.SelectorExpr{ - Sel: ast.NewIdent("steps"), - X: pathIdent, - }, - stepIdent, - }, - }, - }, - }, - }, - }, - }) decls = append(decls, &ast.FuncDecl{ Name: iriToIdent(iri), @@ -221,7 +196,16 @@ func main() { }, }, Body: &ast.BlockStmt{ - List: stmtList, + List: []ast.Stmt{ + &ast.ReturnStmt{ + Results: []ast.Expr{ + &ast.CompositeLit{ + Type: pathTypeIdent, + Elts: elts, + }, + }, + }, + }, }, }) } @@ -236,11 +220,11 @@ func main() { src := ` package client -type step map[string]interface{} +import ( + "github.com/cayleygraph/quad" +) -type Path struct { - steps []step -} +type Path map[string]interface{} ` file, err := parser.ParseFile(fset, "", src, 0) From 96f0a1c1dbd5d237be74d793a46f25e640f39429 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 16:50:56 +0200 Subject: [PATCH 16/27] Share more string values --- query/linkedql/client/generate_client.go | 25 +++++++++++------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/query/linkedql/client/generate_client.go b/query/linkedql/client/generate_client.go index 8beb84f8d..b9d702711 100644 --- a/query/linkedql/client/generate_client.go +++ b/query/linkedql/client/generate_client.go @@ -17,6 +17,7 @@ import ( "github.com/cayleygraph/cayley/owl" "github.com/cayleygraph/quad" "github.com/cayleygraph/quad/jsonld" + "github.com/cayleygraph/quad/voc/rdfs" ) const schemaFile = "linkedql.json" @@ -51,6 +52,11 @@ var quadValueType = &ast.SelectorExpr{ X: ast.NewIdent("quad"), } +var pathStepIRI = quad.IRI("http://cayley.io/linkedql#PathStep") +var xsdString = quad.IRI("http://www.w3.org/2001/XMLSchema#string") +var rdfsResource = quad.IRI(rdfs.Resource).Full() +var stringIdent = ast.NewIdent("string") + func propertyToValueType(class *owl.Class, property *owl.Property) (ast.Expr, error) { _range, err := property.Range() if err != nil { @@ -69,11 +75,11 @@ func propertyToValueType(class *owl.Class, property *owl.Property) (ast.Expr, er isPTR = true } var t ast.Expr - if _range == quad.IRI("http://www.w3.org/2001/XMLSchema#string") { - t = ast.NewIdent("string") - } else if _range == quad.IRI("http://cayley.io/linkedql#PathStep") { + if _range == xsdString { + t = stringIdent + } else if _range == pathStepIRI { t = pathTypeIdent - } else if _range == quad.IRI("http://www.w3.org/2000/01/rdf-schema#Resource") { + } else if _range == rdfsResource { t = quadValueType } else { return nil, fmt.Errorf("Unexpected range %v", _range) @@ -98,7 +104,7 @@ func main() { qs, err := loadSchema() ctx := context.TODO() - stepClass, err := owl.GetClass(ctx, qs, quad.IRI("http://cayley.io/linkedql#PathStep")) + stepClass, err := owl.GetClass(ctx, qs, pathStepIRI) if err != nil { panic(err) @@ -113,7 +119,6 @@ func main() { panic(fmt.Errorf("Unexpected class identifier %v of type %T", stepSubClass.Identifier, stepSubClass.Identifier)) } properties := stepSubClass.Properties() - propertyToType := make(map[quad.IRI]ast.Expr) var paramsList []*ast.Field for _, property := range properties { @@ -121,7 +126,6 @@ func main() { if err != nil { panic(err) } - propertyToType[property.Identifier] = _type ident := iriToIdent(property.Identifier) if ident.Name == "from" { continue @@ -158,13 +162,6 @@ func main() { } var value ast.Expr value = iriToIdent(property.Identifier) - t := propertyToType[property.Identifier] - if t == pathTypeIdent { - value = &ast.SelectorExpr{ - Sel: ast.NewIdent("steps"), - X: value, - } - } elts = append(elts, &ast.KeyValueExpr{ Key: &ast.BasicLit{ Kind: token.STRING, From 3b0d87321fdee44e23b4e0fd3be4dd3c7721aeab Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 16:59:15 +0200 Subject: [PATCH 17/27] Change behaviour if doesn't have from --- query/linkedql/client/generate_client.go | 30 ++++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/query/linkedql/client/generate_client.go b/query/linkedql/client/generate_client.go index b9d702711..babd16ac4 100644 --- a/query/linkedql/client/generate_client.go +++ b/query/linkedql/client/generate_client.go @@ -110,6 +110,7 @@ func main() { panic(err) } + hasFrom := false stepSubClasses := stepClass.SubClasses() var decls []ast.Decl @@ -128,6 +129,7 @@ func main() { } ident := iriToIdent(property.Identifier) if ident.Name == "from" { + hasFrom = true continue } paramsList = append(paramsList, &ast.Field{ @@ -146,13 +148,15 @@ func main() { Value: "\"" + string(iri) + "\"", }, }, - &ast.KeyValueExpr{ + } + if hasFrom { + elts = append(elts, &ast.KeyValueExpr{ Key: &ast.BasicLit{ Kind: token.STRING, Value: "\"from\"", }, Value: pathIdent, - }, + }) } for _, property := range properties { @@ -171,6 +175,19 @@ func main() { }) } + var recv *ast.FieldList + + if hasFrom { + recv = &ast.FieldList{ + List: []*ast.Field{ + &ast.Field{ + Names: []*ast.Ident{pathIdent}, + Type: pathTypeIdent, + }, + }, + } + } + decls = append(decls, &ast.FuncDecl{ Name: iriToIdent(iri), Type: &ast.FuncType{ @@ -184,14 +201,7 @@ func main() { }, }, }, - Recv: &ast.FieldList{ - List: []*ast.Field{ - &ast.Field{ - Names: []*ast.Ident{pathIdent}, - Type: pathTypeIdent, - }, - }, - }, + Recv: recv, Body: &ast.BlockStmt{ List: []ast.Stmt{ &ast.ReturnStmt{ From 56d3cdc5d543a6838311df79f75205dbe5723042 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 17:10:08 +0200 Subject: [PATCH 18/27] Correct hasFrom --- query/linkedql/client/generate_client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/query/linkedql/client/generate_client.go b/query/linkedql/client/generate_client.go index babd16ac4..e016ff091 100644 --- a/query/linkedql/client/generate_client.go +++ b/query/linkedql/client/generate_client.go @@ -110,11 +110,11 @@ func main() { panic(err) } - hasFrom := false stepSubClasses := stepClass.SubClasses() var decls []ast.Decl for _, stepSubClass := range stepSubClasses { + hasFrom := false iri, ok := stepSubClass.Identifier.(quad.IRI) if !ok { panic(fmt.Errorf("Unexpected class identifier %v of type %T", stepSubClass.Identifier, stepSubClass.Identifier)) From 44d4f23531f1214611dbf12cd6d916fa126b6c04 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 17:26:11 +0200 Subject: [PATCH 19/27] Add generate_client to gogen, remove gizmo codegen --- gogen.go | 2 +- query/linkedql/client/generate_client.go | 18 +++- query/linkedql/client/path.go | 107 +++++++++++++++++++++++ 3 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 query/linkedql/client/path.go diff --git a/gogen.go b/gogen.go index c48953715..7a752acdb 100644 --- a/gogen.go +++ b/gogen.go @@ -1,3 +1,3 @@ package cayley -//go:generate go run ./cmd/docgen/docgen.go -i ./docs/GizmoAPI.md.in -o ./docs/GizmoAPI.md +//go:generate go run ./query/linkedql/client/generate_client.go diff --git a/query/linkedql/client/generate_client.go b/query/linkedql/client/generate_client.go index e016ff091..795a62020 100644 --- a/query/linkedql/client/generate_client.go +++ b/query/linkedql/client/generate_client.go @@ -1,7 +1,7 @@ package main import ( - "bytes" + "bufio" "context" "encoding/json" "fmt" @@ -241,11 +241,21 @@ type Path map[string]interface{} file.Decls = append(file.Decls, decls...) - var buf bytes.Buffer - err = format.Node(&buf, fset, file) + f, err := os.Create("query/linkedql/client/path.go") + + if err != nil { + panic(err) + } + + w := bufio.NewWriter(f) + + err = format.Node(w, fset, file) + if err != nil { panic(err) } - fmt.Println(buf.String()) + w.Flush() + + f.Close() } diff --git a/query/linkedql/client/path.go b/query/linkedql/client/path.go new file mode 100644 index 000000000..41762f4ca --- /dev/null +++ b/query/linkedql/client/path.go @@ -0,0 +1,107 @@ +package client + +import ( + "github.com/cayleygraph/quad" +) + +type Path map[string]interface{} + +func (p Path) As(name string) Path { + return Path{"@type": "http://cayley.io/linkedql#As", "from": p, "http://cayley.io/linkedql#name": name} +} +func (p Path) Back(name string) Path { + return Path{"@type": "http://cayley.io/linkedql#Back", "from": p, "http://cayley.io/linkedql#name": name} +} +func (p Path) Count() Path { + return Path{"@type": "http://cayley.io/linkedql#Count", "from": p} +} +func (p Path) Difference(steps []Path) Path { + return Path{"@type": "http://cayley.io/linkedql#Difference", "from": p, "http://cayley.io/linkedql#steps": steps} +} +func (p Path) Filter() Path { + return Path{"@type": "http://cayley.io/linkedql#Filter", "from": p} +} +func (p Path) Follow(followed Path) Path { + return Path{"@type": "http://cayley.io/linkedql#Follow", "from": p, "http://cayley.io/linkedql#followed": followed} +} +func (p Path) FollowReverse(followed Path) Path { + return Path{"@type": "http://cayley.io/linkedql#FollowReverse", "from": p, "http://cayley.io/linkedql#followed": followed} +} +func (p Path) Has(property Path, values []quad.Value) Path { + return Path{"@type": "http://cayley.io/linkedql#Has", "from": p, "http://cayley.io/linkedql#property": property, "http://cayley.io/linkedql#values": values} +} +func (p Path) HasReverse(property Path, values []quad.Value) Path { + return Path{"@type": "http://cayley.io/linkedql#HasReverse", "from": p, "http://cayley.io/linkedql#property": property, "http://cayley.io/linkedql#values": values} +} +func (p Path) In(properties Path) Path { + return Path{"@type": "http://cayley.io/linkedql#In", "from": p, "http://cayley.io/linkedql#properties": properties} +} +func (p Path) Intersect(steps []Path) Path { + return Path{"@type": "http://cayley.io/linkedql#Intersect", "from": p, "http://cayley.io/linkedql#steps": steps} +} +func (p Path) Is(values []quad.Value) Path { + return Path{"@type": "http://cayley.io/linkedql#Is", "from": p, "http://cayley.io/linkedql#values": values} +} +func (p Path) Labels() Path { + return Path{"@type": "http://cayley.io/linkedql#Labels", "from": p} +} +func (p Path) Limit() Path { + return Path{"@type": "http://cayley.io/linkedql#Limit", "from": p} +} +func (p Path) Order() Path { + return Path{"@type": "http://cayley.io/linkedql#Order", "from": p} +} +func (p Path) Out(properties Path) Path { + return Path{"@type": "http://cayley.io/linkedql#Out", "from": p, "http://cayley.io/linkedql#properties": properties} +} +func Placeholder() Path { + return Path{"@type": "http://cayley.io/linkedql#Placeholder"} +} +func (p Path) Properties(names []string) Path { + return Path{"@type": "http://cayley.io/linkedql#Properties", "from": p, "http://cayley.io/linkedql#names": names} +} +func (p Path) PropertyNames() Path { + return Path{"@type": "http://cayley.io/linkedql#PropertyNames", "from": p} +} +func (p Path) PropertyNamesAs(tag string) Path { + return Path{"@type": "http://cayley.io/linkedql#PropertyNamesAs", "from": p, "http://cayley.io/linkedql#tag": tag} +} +func (p Path) ReverseProperties(names []string) Path { + return Path{"@type": "http://cayley.io/linkedql#ReverseProperties", "from": p, "http://cayley.io/linkedql#names": names} +} +func (p Path) ReversePropertyNames() Path { + return Path{"@type": "http://cayley.io/linkedql#ReversePropertyNames", "from": p} +} +func (p Path) ReversePropertyNamesAs(tag string) Path { + return Path{"@type": "http://cayley.io/linkedql#ReversePropertyNamesAs", "from": p, "http://cayley.io/linkedql#tag": tag} +} +func (p Path) Select(tags []string) Path { + return Path{"@type": "http://cayley.io/linkedql#Select", "from": p, "http://cayley.io/linkedql#tags": tags} +} +func (p Path) SelectFirst(tags []string) Path { + return Path{"@type": "http://cayley.io/linkedql#SelectFirst", "from": p, "http://cayley.io/linkedql#tags": tags} +} +func (p Path) Skip() Path { + return Path{"@type": "http://cayley.io/linkedql#Skip", "from": p} +} +func (p Path) Union(steps []Path) Path { + return Path{"@type": "http://cayley.io/linkedql#Union", "from": p, "http://cayley.io/linkedql#steps": steps} +} +func (p Path) Unique() Path { + return Path{"@type": "http://cayley.io/linkedql#Unique", "from": p} +} +func (p Path) Value() Path { + return Path{"@type": "http://cayley.io/linkedql#Value", "from": p} +} +func Vertex(values []quad.Value) Path { + return Path{"@type": "http://cayley.io/linkedql#Vertex", "http://cayley.io/linkedql#values": values} +} +func (p Path) View(properties Path) Path { + return Path{"@type": "http://cayley.io/linkedql#View", "from": p, "http://cayley.io/linkedql#properties": properties} +} +func (p Path) ViewBoth(properties Path) Path { + return Path{"@type": "http://cayley.io/linkedql#ViewBoth", "from": p, "http://cayley.io/linkedql#properties": properties} +} +func (p Path) ViewReverse(properties Path) Path { + return Path{"@type": "http://cayley.io/linkedql#ViewReverse", "from": p, "http://cayley.io/linkedql#properties": properties} +} From 5c8cf507f2ae81c8f4ef166ee791c284e25af56c Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Sat, 7 Dec 2019 17:29:28 +0200 Subject: [PATCH 20/27] Rename path.go to client.go --- query/linkedql/client/{path.go => client.go} | 0 query/linkedql/client/generate_client.go | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename query/linkedql/client/{path.go => client.go} (100%) diff --git a/query/linkedql/client/path.go b/query/linkedql/client/client.go similarity index 100% rename from query/linkedql/client/path.go rename to query/linkedql/client/client.go diff --git a/query/linkedql/client/generate_client.go b/query/linkedql/client/generate_client.go index 795a62020..4e58802b4 100644 --- a/query/linkedql/client/generate_client.go +++ b/query/linkedql/client/generate_client.go @@ -241,7 +241,7 @@ type Path map[string]interface{} file.Decls = append(file.Decls, decls...) - f, err := os.Create("query/linkedql/client/path.go") + f, err := os.Create("query/linkedql/client/client.go") if err != nil { panic(err) From 8c7b5ed017e8d0ab4508628aca5566ddd5e54568 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Wed, 11 Dec 2019 19:04:39 +0200 Subject: [PATCH 21/27] Move code generation script --- .../generate_linkedql_client/generate_linkedql_client.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename query/linkedql/client/generate_client.go => cmd/generate_linkedql_client/generate_linkedql_client.go (100%) diff --git a/query/linkedql/client/generate_client.go b/cmd/generate_linkedql_client/generate_linkedql_client.go similarity index 100% rename from query/linkedql/client/generate_client.go rename to cmd/generate_linkedql_client/generate_linkedql_client.go From 10820991ef93429901c5ce7292fb908c934fcd4c Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Wed, 11 Dec 2019 21:43:29 +0200 Subject: [PATCH 22/27] Update path in gogen.go --- gogen.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gogen.go b/gogen.go index 7a752acdb..76bb7bb8b 100644 --- a/gogen.go +++ b/gogen.go @@ -1,3 +1,3 @@ package cayley -//go:generate go run ./query/linkedql/client/generate_client.go +//go:generate go run ./cmd/generate_linkedql_client/generate_linkedql_client.go From d6122b58ad897712ad33875cd2fe1c252bc701e1 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Fri, 13 Dec 2019 12:11:54 +0200 Subject: [PATCH 23/27] Refactor code to be more navigatable and panic only on main --- .../generate_linkedql_client.go | 313 ++++++++++-------- 1 file changed, 173 insertions(+), 140 deletions(-) diff --git a/cmd/generate_linkedql_client/generate_linkedql_client.go b/cmd/generate_linkedql_client/generate_linkedql_client.go index 4e58802b4..1bc75ee6d 100644 --- a/cmd/generate_linkedql_client/generate_linkedql_client.go +++ b/cmd/generate_linkedql_client/generate_linkedql_client.go @@ -21,7 +21,54 @@ import ( ) const schemaFile = "linkedql.json" +const outputFilePath = "query/linkedql/client/client.go" +var pathStepIRI = quad.IRI("http://cayley.io/linkedql#PathStep") + +func main() { + ctx := context.TODO() + qs, err := loadSchema() + + if err != nil { + panic(err) + } + + stepClass, err := owl.GetClass(ctx, qs, pathStepIRI) + + if err != nil { + panic(err) + } + + stepSubClasses := stepClass.SubClasses() + var decls []ast.Decl + + for _, stepSubClass := range stepSubClasses { + stepSubClassDecls, err := stepSubClassToDecls(stepSubClass) + if err != nil { + panic(err) + } + decls = append(decls, stepSubClassDecls...) + } + + // Create a FileSet for node. Since the node does not come + // from a real source file, fset will be empty. + fset := token.NewFileSet() + file, err := getFile(fset) + + if err != nil { + panic(err) + } + + file.Decls = append(file.Decls, decls...) + + err = writeFile(fset, file, outputFilePath) + + if err != nil { + panic(err) + } +} + +// loadSchema loads the schema file into an in-memory store func loadSchema() (graph.QuadStore, error) { jsonFile, err := os.Open(schemaFile) if err != nil { @@ -43,8 +90,117 @@ func loadSchema() (graph.QuadStore, error) { return qs, nil } -func iriToIdent(iri quad.IRI) *ast.Ident { - return ast.NewIdent(string(iri)[26:]) +var xsdString = quad.IRI("http://www.w3.org/2001/XMLSchema#string") +var rdfsResource = quad.IRI(rdfs.Resource).Full() +var stringIdent = ast.NewIdent("string") + +var pathTypeIdent = ast.NewIdent("Path") +var pathIdent = ast.NewIdent("p") + +func stepSubClassToDecls(stepSubClass *owl.Class) ([]ast.Decl, error) { + var decls []ast.Decl + hasFrom := false + iri, ok := stepSubClass.Identifier.(quad.IRI) + if !ok { + return nil, fmt.Errorf("Unexpected class identifier %v of type %T", stepSubClass.Identifier, stepSubClass.Identifier) + } + properties := stepSubClass.Properties() + + var paramsList []*ast.Field + for _, property := range properties { + _type, err := propertyToValueType(stepSubClass, property) + if err != nil { + return nil, err + } + ident := iriToIdent(property.Identifier) + if ident.Name == "from" { + hasFrom = true + continue + } + paramsList = append(paramsList, &ast.Field{ + Names: []*ast.Ident{ident}, + Type: _type, + }) + } + elts := []ast.Expr{ + &ast.KeyValueExpr{ + Key: &ast.BasicLit{ + Kind: token.STRING, + Value: "\"@type\"", + }, + Value: &ast.BasicLit{ + Kind: token.STRING, + Value: "\"" + string(iri) + "\"", + }, + }, + } + if hasFrom { + elts = append(elts, &ast.KeyValueExpr{ + Key: &ast.BasicLit{ + Kind: token.STRING, + Value: "\"from\"", + }, + Value: pathIdent, + }) + } + + for _, property := range properties { + ident := iriToIdent(property.Identifier) + if ident.Name == "from" { + continue + } + var value ast.Expr + value = iriToIdent(property.Identifier) + elts = append(elts, &ast.KeyValueExpr{ + Key: &ast.BasicLit{ + Kind: token.STRING, + Value: "\"" + string(property.Identifier) + "\"", + }, + Value: value, + }) + } + + var recv *ast.FieldList + + if hasFrom { + recv = &ast.FieldList{ + List: []*ast.Field{ + &ast.Field{ + Names: []*ast.Ident{pathIdent}, + Type: pathTypeIdent, + }, + }, + } + } + + decls = append(decls, &ast.FuncDecl{ + Name: iriToIdent(iri), + Type: &ast.FuncType{ + Params: &ast.FieldList{List: paramsList}, + Results: &ast.FieldList{ + List: []*ast.Field{ + &ast.Field{ + Names: nil, + Type: pathTypeIdent, + }, + }, + }, + }, + Recv: recv, + Body: &ast.BlockStmt{ + List: []ast.Stmt{ + &ast.ReturnStmt{ + Results: []ast.Expr{ + &ast.CompositeLit{ + Type: pathTypeIdent, + Elts: elts, + }, + }, + }, + }, + }, + }) + return decls, nil } var quadValueType = &ast.SelectorExpr{ @@ -52,11 +208,6 @@ var quadValueType = &ast.SelectorExpr{ X: ast.NewIdent("quad"), } -var pathStepIRI = quad.IRI("http://cayley.io/linkedql#PathStep") -var xsdString = quad.IRI("http://www.w3.org/2001/XMLSchema#string") -var rdfsResource = quad.IRI(rdfs.Resource).Full() -var stringIdent = ast.NewIdent("string") - func propertyToValueType(class *owl.Class, property *owl.Property) (ast.Expr, error) { _range, err := property.Range() if err != nil { @@ -97,133 +248,7 @@ func propertyToValueType(class *owl.Class, property *owl.Property) (ast.Expr, er return t, nil } -var pathTypeIdent = ast.NewIdent("Path") -var pathIdent = ast.NewIdent("p") - -func main() { - qs, err := loadSchema() - - ctx := context.TODO() - stepClass, err := owl.GetClass(ctx, qs, pathStepIRI) - - if err != nil { - panic(err) - } - - stepSubClasses := stepClass.SubClasses() - var decls []ast.Decl - - for _, stepSubClass := range stepSubClasses { - hasFrom := false - iri, ok := stepSubClass.Identifier.(quad.IRI) - if !ok { - panic(fmt.Errorf("Unexpected class identifier %v of type %T", stepSubClass.Identifier, stepSubClass.Identifier)) - } - properties := stepSubClass.Properties() - - var paramsList []*ast.Field - for _, property := range properties { - _type, err := propertyToValueType(stepSubClass, property) - if err != nil { - panic(err) - } - ident := iriToIdent(property.Identifier) - if ident.Name == "from" { - hasFrom = true - continue - } - paramsList = append(paramsList, &ast.Field{ - Names: []*ast.Ident{ident}, - Type: _type, - }) - } - elts := []ast.Expr{ - &ast.KeyValueExpr{ - Key: &ast.BasicLit{ - Kind: token.STRING, - Value: "\"@type\"", - }, - Value: &ast.BasicLit{ - Kind: token.STRING, - Value: "\"" + string(iri) + "\"", - }, - }, - } - if hasFrom { - elts = append(elts, &ast.KeyValueExpr{ - Key: &ast.BasicLit{ - Kind: token.STRING, - Value: "\"from\"", - }, - Value: pathIdent, - }) - } - - for _, property := range properties { - ident := iriToIdent(property.Identifier) - if ident.Name == "from" { - continue - } - var value ast.Expr - value = iriToIdent(property.Identifier) - elts = append(elts, &ast.KeyValueExpr{ - Key: &ast.BasicLit{ - Kind: token.STRING, - Value: "\"" + string(property.Identifier) + "\"", - }, - Value: value, - }) - } - - var recv *ast.FieldList - - if hasFrom { - recv = &ast.FieldList{ - List: []*ast.Field{ - &ast.Field{ - Names: []*ast.Ident{pathIdent}, - Type: pathTypeIdent, - }, - }, - } - } - - decls = append(decls, &ast.FuncDecl{ - Name: iriToIdent(iri), - Type: &ast.FuncType{ - Params: &ast.FieldList{List: paramsList}, - Results: &ast.FieldList{ - List: []*ast.Field{ - &ast.Field{ - Names: nil, - Type: pathTypeIdent, - }, - }, - }, - }, - Recv: recv, - Body: &ast.BlockStmt{ - List: []ast.Stmt{ - &ast.ReturnStmt{ - Results: []ast.Expr{ - &ast.CompositeLit{ - Type: pathTypeIdent, - Elts: elts, - }, - }, - }, - }, - }, - }) - } - - if err != nil { - panic(err) - } - - // Create a FileSet for node. Since the node does not come - // from a real source file, fset will be empty. - fset := token.NewFileSet() +func getFile(fset *token.FileSet) (*ast.File, error) { src := ` package client @@ -236,15 +261,18 @@ type Path map[string]interface{} file, err := parser.ParseFile(fset, "", src, 0) if err != nil { - panic(err) + return nil, err } - file.Decls = append(file.Decls, decls...) + return file, nil +} - f, err := os.Create("query/linkedql/client/client.go") +// writeFile writes given file of given fset to given path +func writeFile(fset *token.FileSet, file *ast.File, path string) error { + f, err := os.Create(path) if err != nil { - panic(err) + return err } w := bufio.NewWriter(f) @@ -252,10 +280,15 @@ type Path map[string]interface{} err = format.Node(w, fset, file) if err != nil { - panic(err) + return err } w.Flush() - f.Close() + + return nil +} + +func iriToIdent(iri quad.IRI) *ast.Ident { + return ast.NewIdent(string(iri)[26:]) } From ef622ab9af2890f117105fea1d02f79f63a5070a Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Fri, 13 Dec 2019 12:28:52 +0200 Subject: [PATCH 24/27] Generate comments --- .../generate_linkedql_client.go | 21 +++++- owl/owl.go | 21 ++++++ query/linkedql/client/client.go | 65 +++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) diff --git a/cmd/generate_linkedql_client/generate_linkedql_client.go b/cmd/generate_linkedql_client/generate_linkedql_client.go index 1bc75ee6d..b0caac6cc 100644 --- a/cmd/generate_linkedql_client/generate_linkedql_client.go +++ b/cmd/generate_linkedql_client/generate_linkedql_client.go @@ -173,8 +173,23 @@ func stepSubClassToDecls(stepSubClass *owl.Class) ([]ast.Decl, error) { } } + comment, err := stepSubClass.Comment() + + var doc *ast.CommentGroup + + if err == nil { + doc = &ast.CommentGroup{ + List: []*ast.Comment{ + { + Text: "// " + iriToStringIdent(iri) + " " + comment, + }, + }, + } + } + decls = append(decls, &ast.FuncDecl{ Name: iriToIdent(iri), + Doc: doc, Type: &ast.FuncType{ Params: &ast.FieldList{List: paramsList}, Results: &ast.FieldList{ @@ -289,6 +304,10 @@ func writeFile(fset *token.FileSet, file *ast.File, path string) error { return nil } +func iriToStringIdent(iri quad.IRI) string { + return string(iri)[26:] +} + func iriToIdent(iri quad.IRI) *ast.Ident { - return ast.NewIdent(string(iri)[26:]) + return ast.NewIdent(iriToStringIdent(iri)) } diff --git a/owl/owl.go b/owl/owl.go index 5d28bf42f..ec2a25367 100644 --- a/owl/owl.go +++ b/owl/owl.go @@ -72,6 +72,27 @@ func (c *Class) ParentClasses() []*Class { return classes } +var rdfsComment = quad.IRI("rdfs:comment").Full() + +// Comment returns classs's comment +func (c *Class) Comment() (string, error) { + it := c.path().Out(rdfsComment).BuildIterator(c.ctx).Iterate() + for it.Next(c.ctx) { + ref := it.Result() + value := c.qs.NameOf(ref) + stringValue, ok := value.(quad.String) + if ok { + return string(stringValue), nil + } + typedStringValue, ok := value.(quad.TypedString) + if ok { + return string(typedStringValue.Value), nil + } + + } + return "", fmt.Errorf("No comment exist for %v", c.Identifier) +} + func parentClassesPath(c *Class) *path.Path { return c.path().Out(quad.IRI(rdfs.SubClassOf).Full()) } diff --git a/query/linkedql/client/client.go b/query/linkedql/client/client.go index 41762f4ca..4bcdba0cd 100644 --- a/query/linkedql/client/client.go +++ b/query/linkedql/client/client.go @@ -6,102 +6,167 @@ import ( type Path map[string]interface{} +// As As assigns the resolved values of the from step to a given name. The name can be used with the Select and Documents steps to retreive the values or to return to the values in further steps with the Back step. It resolves to the values of the from step. func (p Path) As(name string) Path { return Path{"@type": "http://cayley.io/linkedql#As", "from": p, "http://cayley.io/linkedql#name": name} } + +// Back Back resolves to the values of the previous the step or the values assigned to name in a former step. func (p Path) Back(name string) Path { return Path{"@type": "http://cayley.io/linkedql#Back", "from": p, "http://cayley.io/linkedql#name": name} } + +// Count Count resolves to the number of the resolved values of the from step func (p Path) Count() Path { return Path{"@type": "http://cayley.io/linkedql#Count", "from": p} } + +// Difference Difference resolves to all the values resolved by the from step different then the values resolved by the provided steps. Caution: it might be slow to execute. func (p Path) Difference(steps []Path) Path { return Path{"@type": "http://cayley.io/linkedql#Difference", "from": p, "http://cayley.io/linkedql#steps": steps} } + +// Filter Apply constraints to a set of nodes. Can be used to filter values by range or match strings. func (p Path) Filter() Path { return Path{"@type": "http://cayley.io/linkedql#Filter", "from": p} } + +// Follow The way to use a path prepared with Morphism. Applies the path chain on the morphism object to the current path. Starts as if at the g.M() and follows through the morphism path. func (p Path) Follow(followed Path) Path { return Path{"@type": "http://cayley.io/linkedql#Follow", "from": p, "http://cayley.io/linkedql#followed": followed} } + +// FollowReverse The same as follow but follows the chain in the reverse direction. Flips View and ViewReverse where appropriate, the net result being a virtual predicate followed in the reverse direction. Starts at the end of the morphism and follows it backwards (with appropriate flipped directions) to the g.M() location. func (p Path) FollowReverse(followed Path) Path { return Path{"@type": "http://cayley.io/linkedql#FollowReverse", "from": p, "http://cayley.io/linkedql#followed": followed} } + +// Has Filter all paths which are, at this point, on the subject for the given predicate and object, but do not follow the path, merely filter the possible paths. Usually useful for starting with all nodes, or limiting to a subset depending on some predicate/value pair. func (p Path) Has(property Path, values []quad.Value) Path { return Path{"@type": "http://cayley.io/linkedql#Has", "from": p, "http://cayley.io/linkedql#property": property, "http://cayley.io/linkedql#values": values} } + +// HasReverse The same as Has, but sets constraint in reverse direction. func (p Path) HasReverse(property Path, values []quad.Value) Path { return Path{"@type": "http://cayley.io/linkedql#HasReverse", "from": p, "http://cayley.io/linkedql#property": property, "http://cayley.io/linkedql#values": values} } + +// In Alias for ViewReverse func (p Path) In(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#In", "from": p, "http://cayley.io/linkedql#properties": properties} } + +// Intersect Intersect resolves to all the same values resolved by the from step and the provided steps. func (p Path) Intersect(steps []Path) Path { return Path{"@type": "http://cayley.io/linkedql#Intersect", "from": p, "http://cayley.io/linkedql#steps": steps} } + +// Is Is resolves to all the values resolved by the from step which are included in provided values. func (p Path) Is(values []quad.Value) Path { return Path{"@type": "http://cayley.io/linkedql#Is", "from": p, "http://cayley.io/linkedql#values": values} } + +// Labels Get the list of inbound and outbound quad labels func (p Path) Labels() Path { return Path{"@type": "http://cayley.io/linkedql#Labels", "from": p} } + +// Limit Limit a number of nodes for current path. func (p Path) Limit() Path { return Path{"@type": "http://cayley.io/linkedql#Limit", "from": p} } + +// Order Order sorts the results in ascending order according to the current entity / value func (p Path) Order() Path { return Path{"@type": "http://cayley.io/linkedql#Order", "from": p} } + +// Out Alias for View func (p Path) Out(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#Out", "from": p, "http://cayley.io/linkedql#properties": properties} } + +// Placeholder Placeholder is like Vertex but resolves to the values in the context it is placed in. It should only be used where a PathStep is expected and can't be resolved on its own. func Placeholder() Path { return Path{"@type": "http://cayley.io/linkedql#Placeholder"} } + +// Properties Adds tags for all properties of the current entity func (p Path) Properties(names []string) Path { return Path{"@type": "http://cayley.io/linkedql#Properties", "from": p, "http://cayley.io/linkedql#names": names} } + +// PropertyNames Get the list of predicates that are pointing out from a node. func (p Path) PropertyNames() Path { return Path{"@type": "http://cayley.io/linkedql#PropertyNames", "from": p} } + +// PropertyNamesAs Tag the list of predicates that are pointing out from a node. func (p Path) PropertyNamesAs(tag string) Path { return Path{"@type": "http://cayley.io/linkedql#PropertyNamesAs", "from": p, "http://cayley.io/linkedql#tag": tag} } + +// ReverseProperties Gets all the properties the current entity / value is referenced at func (p Path) ReverseProperties(names []string) Path { return Path{"@type": "http://cayley.io/linkedql#ReverseProperties", "from": p, "http://cayley.io/linkedql#names": names} } + +// ReversePropertyNames Get the list of predicates that are pointing in to a node. func (p Path) ReversePropertyNames() Path { return Path{"@type": "http://cayley.io/linkedql#ReversePropertyNames", "from": p} } + +// ReversePropertyNamesAs Tag the list of predicates that are pointing in to a node. func (p Path) ReversePropertyNamesAs(tag string) Path { return Path{"@type": "http://cayley.io/linkedql#ReversePropertyNamesAs", "from": p, "http://cayley.io/linkedql#tag": tag} } + +// Select Select returns flat records of tags matched in the query func (p Path) Select(tags []string) Path { return Path{"@type": "http://cayley.io/linkedql#Select", "from": p, "http://cayley.io/linkedql#tags": tags} } + +// SelectFirst Like Select but only returns the first result func (p Path) SelectFirst(tags []string) Path { return Path{"@type": "http://cayley.io/linkedql#SelectFirst", "from": p, "http://cayley.io/linkedql#tags": tags} } + +// Skip Skip a number of nodes for current path. func (p Path) Skip() Path { return Path{"@type": "http://cayley.io/linkedql#Skip", "from": p} } + +// Union Return the combined paths of the two queries. Notice that it's per-path, not per-node. Once again, if multiple paths reach the same destination, they might have had different ways of getting there (and different tags). func (p Path) Union(steps []Path) Path { return Path{"@type": "http://cayley.io/linkedql#Union", "from": p, "http://cayley.io/linkedql#steps": steps} } + +// Unique Remove duplicate values from the path. func (p Path) Unique() Path { return Path{"@type": "http://cayley.io/linkedql#Unique", "from": p} } + +// Value Value returns a single value matched in the query func (p Path) Value() Path { return Path{"@type": "http://cayley.io/linkedql#Value", "from": p} } + +// Vertex Vertex resolves to all the existing objects and primitive values in the graph. If provided with values resolves to a sublist of all the existing values in the graph. func Vertex(values []quad.Value) Path { return Path{"@type": "http://cayley.io/linkedql#Vertex", "http://cayley.io/linkedql#values": values} } + +// View View resolves to the values of the given property or properties in via of the current objects. If via is a path it's resolved values will be used as properties. func (p Path) View(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#View", "from": p, "http://cayley.io/linkedql#properties": properties} } + +// ViewBoth ViewBoth is like View but resolves to both the object values and references to the values of the given properties in via. It is the equivalent for the Union of View and ViewReverse of the same property. func (p Path) ViewBoth(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#ViewBoth", "from": p, "http://cayley.io/linkedql#properties": properties} } + +// ViewReverse The inverse of View. Starting with the nodes in `path` on the object, follow the quads with predicates defined by `predicatePath` to their subjects. func (p Path) ViewReverse(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#ViewReverse", "from": p, "http://cayley.io/linkedql#properties": properties} } From 13579de052a7ec397c7810ac30fbad4a032b324e Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Fri, 13 Dec 2019 12:40:30 +0200 Subject: [PATCH 25/27] linkedql: Add comment to path methods --- linkedql.json | 2118 ++++++++++++++++--------------- query/linkedql/client/client.go | 60 +- 2 files changed, 1094 insertions(+), 1084 deletions(-) diff --git a/linkedql.json b/linkedql.json index bfc4f8d8c..db07f5113 100644 --- a/linkedql.json +++ b/linkedql.json @@ -1,1056 +1,1066 @@ { - "@context": { - "rdf": { "@id": "http://www.w3.org/1999/02/22-rdf-syntax-ns#" }, - "rdfs": { "@id": "http://www.w3.org/2000/01/rdf-schema#" }, - "owl": { "@id": "http://www.w3.org/2002/07/owl#" }, - "xsd": { "@id": "http://www.w3.org/2001/XMLSchema#" }, - "linkedql": { "@id": "http://cayley.io/linkedql#" } - }, - "@graph": [ - { - "@id": "linkedql:Limit", - "@type": "rdfs:Class", - "rdfs:comment": "Limit a number of nodes for current path.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n8440732519379756303", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n3712322762825274014", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:limit" - } - } - ] - }, - { - "@id": "linkedql:Value", - "@type": "rdfs:Class", - "rdfs:comment": "Value returns a single value matched in the query", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n4579355384285360119", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:Intersect", - "@type": "rdfs:Class", - "rdfs:comment": "Intersect resolves to all the same values resolved by the from step and the provided steps.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n4514190024430663212", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:ReversePropertyNames", - "@type": "rdfs:Class", - "rdfs:comment": "Get the list of predicates that are pointing in to a node.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n8660593491344506672", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:Labels", - "@type": "rdfs:Class", - "rdfs:comment": "Get the list of inbound and outbound quad labels", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n3966336922519947481", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:Order", - "@type": "rdfs:Class", - "rdfs:comment": "Order sorts the results in ascending order according to the current entity / value", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n6687051227661129038", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:SelectFirst", - "@type": "rdfs:Class", - "rdfs:comment": "Like Select but only returns the first result", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n8213583569693444697", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:Out", - "@type": "rdfs:Class", - "rdfs:comment": "Alias for View", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n1219656053828715988", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n2330159957297390889", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:properties" - } - } - ] - }, - { - "@id": "linkedql:In", - "@type": "rdfs:Class", - "rdfs:comment": "Alias for ViewReverse", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n888163984235468022", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n6694906304984451453", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:properties" - } - } - ] - }, - { - "@id": "linkedql:Has", - "@type": "rdfs:Class", - "rdfs:comment": "Filter all paths which are, at this point, on the subject for the given predicate and object, but do not follow the path, merely filter the possible paths. Usually useful for starting with all nodes, or limiting to a subset depending on some predicate/value pair.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n175100899574574219", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n1044889261799882442", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:property" - } - } - ] - }, - { - "@id": "linkedql:PropertyNamesAs", - "@type": "rdfs:Class", - "rdfs:comment": "Tag the list of predicates that are pointing out from a node.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n292297794499813908", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n6225281244837245777", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:tag" - } - } - ] - }, - { - "@id": "linkedql:Skip", - "@type": "rdfs:Class", - "rdfs:comment": "Skip a number of nodes for current path.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n130022202379099635", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n6588229958767122733", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:offset" - } - } - ] - }, - { - "@id": "linkedql:Vertex", - "@type": "rdfs:Class", - "rdfs:comment": "Vertex resolves to all the existing objects and primitive values in the graph. If provided with values resolves to a sublist of all the existing values in the graph.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - } - ] - }, - { - "@id": "linkedql:As", - "@type": "rdfs:Class", - "rdfs:comment": "As assigns the resolved values of the from step to a given name. The name can be used with the Select and Documents steps to retreive the values or to return to the values in further steps with the Back step. It resolves to the values of the from step.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n6798046550741287208", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n286452450666657184", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:name" - } - } - ] - }, - { - "@id": "linkedql:FollowReverse", - "@type": "rdfs:Class", - "rdfs:comment": "The same as follow but follows the chain in the reverse direction. Flips View and ViewReverse where appropriate, the net result being a virtual predicate followed in the reverse direction. Starts at the end of the morphism and follows it backwards (with appropriate flipped directions) to the g.M() location.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n421149569477813134", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n8713908741985514185", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:followed" - } - } - ] - }, - { - "@id": "linkedql:Back", - "@type": "rdfs:Class", - "rdfs:comment": "Back resolves to the values of the previous the step or the values assigned to name in a former step.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n6224931844063977691", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n7828451043486737760", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:name" - } - } - ] - }, - { - "@id": "linkedql:ViewBoth", - "@type": "rdfs:Class", - "rdfs:comment": "ViewBoth is like View but resolves to both the object values and references to the values of the given properties in via. It is the equivalent for the Union of View and ViewReverse of the same property.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n5094381124248830937", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n3925447844365248023", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:properties" - } - } - ] - }, - { - "@id": "linkedql:Unique", - "@type": "rdfs:Class", - "rdfs:comment": "Remove duplicate values from the path.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n5542740196010578693", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:Count", - "@type": "rdfs:Class", - "rdfs:comment": "Count resolves to the number of the resolved values of the from step", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n3865310955534739904", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:ViewReverse", - "@type": "rdfs:Class", - "rdfs:comment": "The inverse of View. Starting with the nodes in `path` on the object, follow the quads with predicates defined by `predicatePath` to their subjects.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n5018575002663944481", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n4550818690762018934", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:properties" - } - } - ] - }, - { - "@id": "linkedql:Properties", - "@type": "rdfs:Class", - "rdfs:comment": "Adds tags for all properties of the current entity", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n2729739665710486886", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:HasReverse", - "@type": "rdfs:Class", - "rdfs:comment": "The same as Has, but sets constraint in reverse direction.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n7199307538045442194", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n1649650420342137981", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:property" - } - } - ] - }, - { - "@id": "linkedql:ReversePropertyNamesAs", - "@type": "rdfs:Class", - "rdfs:comment": "Tag the list of predicates that are pointing in to a node.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n824169249890386973", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n912081101491472970", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:tag" - } - } - ] - }, - { - "@id": "linkedql:Union", - "@type": "rdfs:Class", - "rdfs:comment": "Return the combined paths of the two queries. Notice that it's per-path, not per-node. Once again, if multiple paths reach the same destination, they might have had different ways of getting there (and different tags).", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n8251106634341539663", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:Placeholder", - "@type": "rdfs:Class", - "rdfs:comment": "Placeholder is like Vertex but resolves to the values in the context it is placed in. It should only be used where a PathStep is expected and can't be resolved on its own.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - } - ] - }, - { - "@id": "linkedql:View", - "@type": "rdfs:Class", - "rdfs:comment": "View resolves to the values of the given property or properties in via of the current objects. If via is a path it's resolved values will be used as properties.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n5414025948682150736", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n337958186940316772", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:properties" - } - } - ] - }, - { - "@id": "linkedql:Difference", - "@type": "rdfs:Class", - "rdfs:comment": "Difference resolves to all the values resolved by the from step different then the values resolved by the provided steps. Caution: it might be slow to execute.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n2352625201874167266", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:Select", - "@type": "rdfs:Class", - "rdfs:comment": "Select returns flat records of tags matched in the query", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n7185668025961658720", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:Is", - "@type": "rdfs:Class", - "rdfs:comment": "Is resolves to all the values resolved by the from step which are included in provided values.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n7434626777184219064", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:Filter", - "@type": "rdfs:Class", - "rdfs:comment": "Apply constraints to a set of nodes. Can be used to filter values by range or match strings.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n308561566335026255", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n7752481218121017300", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:filter" - } - } - ] - }, - { - "@id": "linkedql:Follow", - "@type": "rdfs:Class", - "rdfs:comment": "The way to use a path prepared with Morphism. Applies the path chain on the morphism object to the current path. Starts as if at the g.M() and follows through the morphism path.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n5924982697949066515", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - }, - { - "@id": "_:n3698252949431811663", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:followed" - } - } - ] - }, - { - "@id": "linkedql:PropertyNames", - "@type": "rdfs:Class", - "rdfs:comment": "Get the list of predicates that are pointing out from a node.", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n2100531796371300813", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:ReverseProperties", - "@type": "rdfs:Class", - "rdfs:comment": "Gets all the properties the current entity / value is referenced at", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" - }, - { - "@id": "_:n4543797063415686792", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:names", - "@type": "owl:ObjectProperty", - "rdfs:domain": { - "@id": "_:n2009243660815281193", - "@type": "owl:Class", - "owl:unionOf": { - "@list": [ - { - "@id": "linkedql:Properties" - }, - { - "@id": "linkedql:ReverseProperties" - } - ] - } - }, - "rdfs:range": { - "@id": "xsd:string" - } - }, - { - "@id": "linkedql:from", - "@type": "owl:ObjectProperty", - "rdfs:domain": { - "@id": "_:n1898025205901327062", - "@type": "owl:Class", - "owl:unionOf": { - "@list": [ - { - "@id": "linkedql:HasReverse" - }, - { - "@id": "linkedql:Labels" - }, - { - "@id": "linkedql:Order" - }, - { - "@id": "linkedql:Skip" - }, - { - "@id": "linkedql:ViewBoth" - }, - { - "@id": "linkedql:Count" - }, - { - "@id": "linkedql:Properties" - }, - { - "@id": "linkedql:PropertyNamesAs" - }, - { - "@id": "linkedql:As" - }, - { - "@id": "linkedql:Union" - }, - { - "@id": "linkedql:Is" - }, - { - "@id": "linkedql:ReverseProperties" - }, - { - "@id": "linkedql:Out" - }, - { - "@id": "linkedql:ReversePropertyNamesAs" - }, - { - "@id": "linkedql:View" - }, - { - "@id": "linkedql:Limit" - }, - { - "@id": "linkedql:SelectFirst" - }, - { - "@id": "linkedql:Unique" - }, - { - "@id": "linkedql:Value" - }, - { - "@id": "linkedql:Back" - }, - { - "@id": "linkedql:Select" - }, - { - "@id": "linkedql:Follow" - }, - { - "@id": "linkedql:ReversePropertyNames" - }, - { - "@id": "linkedql:FollowReverse" - }, - { - "@id": "linkedql:Difference" - }, - { - "@id": "linkedql:Intersect" - }, - { - "@id": "linkedql:ViewReverse" - }, - { - "@id": "linkedql:Filter" - }, - { - "@id": "linkedql:PropertyNames" - }, - { - "@id": "linkedql:In" - }, - { - "@id": "linkedql:Has" - } - ] - } - }, - "rdfs:range": { - "@id": "linkedql:PathStep" - } - }, - { - "@id": "linkedql:tags", - "@type": "owl:ObjectProperty", - "rdfs:domain": { - "@id": "_:n5703457665831349039", - "@type": "owl:Class", - "owl:unionOf": { - "@list": [ - { - "@id": "linkedql:SelectFirst" - }, - { - "@id": "linkedql:Select" - } - ] - } - }, - "rdfs:range": { - "@id": "xsd:string" - } - }, - { - "@id": "linkedql:offset", - "@type": "owl:DatatypeProperty", - "rdfs:domain": "linkedql:Skip", - "rdfs:range": { - "@id": "xsd:int" - } - }, - { - "@id": "linkedql:name", - "@type": "owl:DatatypeProperty", - "rdfs:domain": { - "@id": "_:n441910633043105813", - "@type": "owl:Class", - "owl:unionOf": { - "@list": [ - { - "@id": "linkedql:As" - }, - { - "@id": "linkedql:Back" - } - ] - } - }, - "rdfs:range": { - "@id": "xsd:string" - } - }, - { - "@id": "linkedql:followed", - "@type": "owl:ObjectProperty", - "rdfs:domain": { - "@id": "_:n5918147121052823382", - "@type": "owl:Class", - "owl:unionOf": { - "@list": [ - { - "@id": "linkedql:Follow" - }, - { - "@id": "linkedql:FollowReverse" - } - ] - } - }, - "rdfs:range": { - "@id": "linkedql:PathStep" - } - }, - { - "@id": "linkedql:tag", - "@type": "owl:DatatypeProperty", - "rdfs:domain": { - "@id": "_:n2861998284995186465", - "@type": "owl:Class", - "owl:unionOf": { - "@list": [ - { - "@id": "linkedql:PropertyNamesAs" - }, - { - "@id": "linkedql:ReversePropertyNamesAs" - } - ] - } - }, - "rdfs:range": { - "@id": "xsd:string" - } - }, - { - "@id": "linkedql:filter", - "@type": "owl:ObjectProperty", - "rdfs:domain": "linkedql:Filter", - "rdfs:range": { - "@id": "linkedql:Operator" - } - }, - { - "@id": "linkedql:limit", - "@type": "owl:DatatypeProperty", - "rdfs:domain": "linkedql:Limit", - "rdfs:range": { - "@id": "xsd:int" - } - }, - { - "@id": "linkedql:steps", - "@type": "owl:ObjectProperty", - "rdfs:domain": { - "@id": "_:n1702138994867097388", - "@type": "owl:Class", - "owl:unionOf": { - "@list": [ - { - "@id": "linkedql:Intersect" - }, - { - "@id": "linkedql:Union" - }, - { - "@id": "linkedql:Difference" - } - ] - } - }, - "rdfs:range": { - "@id": "linkedql:PathStep" - } - }, - { - "@id": "linkedql:properties", - "@type": "owl:ObjectProperty", - "rdfs:domain": { - "@id": "_:n716290370629566278", - "@type": "owl:Class", - "owl:unionOf": { - "@list": [ - { - "@id": "linkedql:Out" - }, - { - "@id": "linkedql:In" - }, - { - "@id": "linkedql:ViewBoth" - }, - { - "@id": "linkedql:ViewReverse" - }, - { - "@id": "linkedql:View" - } - ] - } - }, - "rdfs:range": { - "@id": "linkedql:PathStep" - } - }, - { - "@id": "linkedql:property", - "@type": "owl:ObjectProperty", - "rdfs:domain": { - "@id": "_:n2774302972298001908", - "@type": "owl:Class", - "owl:unionOf": { - "@list": [ - { - "@id": "linkedql:Has" - }, - { - "@id": "linkedql:HasReverse" - } - ] - } - }, - "rdfs:range": { - "@id": "linkedql:PathStep" - } - }, - { - "@id": "linkedql:values", - "@type": "owl:ObjectProperty", - "rdfs:domain": { - "@id": "_:n993961146967673695", - "@type": "owl:Class", - "owl:unionOf": { - "@list": [ - { - "@id": "linkedql:Has" - }, - { - "@id": "linkedql:Vertex" - }, - { - "@id": "linkedql:HasReverse" - }, - { - "@id": "linkedql:Is" - } - ] - } - }, - "rdfs:range": { - "@id": "rdfs:Resource" - } - } - ] + "@context": { + "linkedql": { + "@id": "http://cayley.io/linkedql#" + }, + "owl": { + "@id": "http://www.w3.org/2002/07/owl#" + }, + "rdf": { + "@id": "http://www.w3.org/1999/02/22-rdf-syntax-ns#" + }, + "rdfs": { + "@id": "http://www.w3.org/2000/01/rdf-schema#" + }, + "xsd": { + "@id": "http://www.w3.org/2001/XMLSchema#" + } + }, + "@graph": [ + { + "@id": "linkedql:Back", + "@type": "rdfs:Class", + "rdfs:comment": "resolves to the values of the previous the step or the values assigned to name in a former step.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n7908088290697276681", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n5997096025876839690", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:name" + } + } + ] + }, + { + "@id": "linkedql:As", + "@type": "rdfs:Class", + "rdfs:comment": "assigns the resolved values of the from step to a given name. The name can be used with the Select and Documents steps to retreive the values or to return to the values in further steps with the Back step. It resolves to the values of the from step.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n7988485489972284209", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n7567688478636418594", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:name" + } + } + ] + }, + { + "@id": "linkedql:Vertex", + "@type": "rdfs:Class", + "rdfs:comment": "resolves to all the existing objects and primitive values in the graph. If provided with values resolves to a sublist of all the existing values in the graph.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + } + ] + }, + { + "@id": "linkedql:ReversePropertyNamesAs", + "@type": "rdfs:Class", + "rdfs:comment": "tags the list of predicates that are pointing in to a node.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n8383648757660417451", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n6926458250230044772", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:tag" + } + } + ] + }, + { + "@id": "linkedql:Value", + "@type": "rdfs:Class", + "rdfs:comment": "Value returns a single value matched in the query", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n1841094452838461572", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Follow", + "@type": "rdfs:Class", + "rdfs:comment": "is the way to use a path prepared with Morphism. Applies the path chain on the morphism object to the current path. Starts as if at the g.M() and follows through the morphism path.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n2005093628341939828", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n5104241301475361160", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:followed" + } + } + ] + }, + { + "@id": "linkedql:FollowReverse", + "@type": "rdfs:Class", + "rdfs:comment": "is the same as follow but follows the chain in the reverse direction. Flips View and ViewReverse where appropriate, the net result being a virtual predicate followed in the reverse direction. Starts at the end of the morphism and follows it backwards (with appropriate flipped directions) to the g.M() location.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n4584588397207050072", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n4166975175965651772", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:followed" + } + } + ] + }, + { + "@id": "linkedql:In", + "@type": "rdfs:Class", + "rdfs:comment": "aliases for ViewReverse", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n1870897588368680998", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n3607726901418144227", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:properties" + } + } + ] + }, + { + "@id": "linkedql:ReversePropertyNames", + "@type": "rdfs:Class", + "rdfs:comment": "gets the list of predicates that are pointing in to a node.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n3903726778461453772", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Labels", + "@type": "rdfs:Class", + "rdfs:comment": "gets the list of inbound and outbound quad labels", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n2891927322902708841", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Properties", + "@type": "rdfs:Class", + "rdfs:comment": "adds tags for all properties of the current entity", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n6424233792414955944", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:PropertyNamesAs", + "@type": "rdfs:Class", + "rdfs:comment": "tags the list of predicates that are pointing out from a node.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n4418208634829485365", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n201410601521517206", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:tag" + } + } + ] + }, + { + "@id": "linkedql:Difference", + "@type": "rdfs:Class", + "rdfs:comment": "resolves to all the values resolved by the from step different then the values resolved by the provided steps. Caution: it might be slow to execute.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n3223642664820787682", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Has", + "@type": "rdfs:Class", + "rdfs:comment": "filters all paths which are, at this point, on the subject for the given predicate and object, but do not follow the path, merely filter the possible paths. Usually useful for starting with all nodes, or limiting to a subset depending on some predicate/value pair.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n2349392202041882821", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n13257026593940279", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:property" + } + } + ] + }, + { + "@id": "linkedql:HasReverse", + "@type": "rdfs:Class", + "rdfs:comment": "is the same as Has, but sets constraint in reverse direction.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n9128900241535060479", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n2741547127402511673", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:property" + } + } + ] + }, + { + "@id": "linkedql:ViewBoth", + "@type": "rdfs:Class", + "rdfs:comment": "is like View but resolves to both the object values and references to the values of the given properties in via. It is the equivalent for the Union of View and ViewReverse of the same property.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n8502434772150270123", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n5585646283882161042", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:properties" + } + } + ] + }, + { + "@id": "linkedql:Is", + "@type": "rdfs:Class", + "rdfs:comment": "resolves to all the values resolved by the from step which are included in provided values.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n3090803183809953074", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Limit", + "@type": "rdfs:Class", + "rdfs:comment": "limits a number of nodes for current path.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n853618359657221356", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n3741714749040882736", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:limit" + } + } + ] + }, + { + "@id": "linkedql:ReverseProperties", + "@type": "rdfs:Class", + "rdfs:comment": "gets all the properties the current entity / value is referenced at", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n4533390537095304805", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Select", + "@type": "rdfs:Class", + "rdfs:comment": "Select returns flat records of tags matched in the query", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n9181657233381629788", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:View", + "@type": "rdfs:Class", + "rdfs:comment": "resolves to the values of the given property or properties in via of the current objects. If via is a path it's resolved values will be used as properties.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n5824746053480877069", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n6461519520038761833", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:properties" + } + } + ] + }, + { + "@id": "linkedql:Out", + "@type": "rdfs:Class", + "rdfs:comment": "aliases for View", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n8047248095020601737", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n5222948747445626408", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:properties" + } + } + ] + }, + { + "@id": "linkedql:Placeholder", + "@type": "rdfs:Class", + "rdfs:comment": "is like Vertex but resolves to the values in the context it is placed in. It should only be used where a PathStep is expected and can't be resolved on its own.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + } + ] + }, + { + "@id": "linkedql:Count", + "@type": "rdfs:Class", + "rdfs:comment": "resolves to the number of the resolved values of the from step", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n8390472748902891963", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Filter", + "@type": "rdfs:Class", + "rdfs:comment": "applies constraints to a set of nodes. Can be used to filter values by range or match strings.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n1646447114406524394", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n8967834957155453826", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:filter" + } + } + ] + }, + { + "@id": "linkedql:Skip", + "@type": "rdfs:Class", + "rdfs:comment": "skips a number of nodes for current path.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n4098750636493779506", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n1621454338437066833", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:offset" + } + } + ] + }, + { + "@id": "linkedql:Union", + "@type": "rdfs:Class", + "rdfs:comment": "returns the combined paths of the two queries. Notice that it's per-path, not per-node. Once again, if multiple paths reach the same destination, they might have had different ways of getting there (and different tags).", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n1227112490286966331", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Unique", + "@type": "rdfs:Class", + "rdfs:comment": "removes duplicate values from the path.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n6547757674992010008", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Order", + "@type": "rdfs:Class", + "rdfs:comment": "sorts the results in ascending order according to the current entity / value", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n4036254078241711198", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:SelectFirst", + "@type": "rdfs:Class", + "rdfs:comment": "Like Select but only returns the first result", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n1197969629924875303", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:ViewReverse", + "@type": "rdfs:Class", + "rdfs:comment": "is the inverse of View. Starting with the nodes in `path` on the object, follow the quads with predicates defined by `predicatePath` to their subjects.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n6251537544036519808", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + }, + { + "@id": "_:n1051213466635448344", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:properties" + } + } + ] + }, + { + "@id": "linkedql:PropertyNames", + "@type": "rdfs:Class", + "rdfs:comment": "gets the list of predicates that are pointing out from a node.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n3269172395352052471", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:Intersect", + "@type": "rdfs:Class", + "rdfs:comment": "resolves to all the same values resolved by the from step and the provided steps.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "_:n2823818453963121638", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:values", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n161473765488462789", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:HasReverse" + }, + { + "@id": "linkedql:Is" + }, + { + "@id": "linkedql:Vertex" + }, + { + "@id": "linkedql:Has" + } + ] + } + }, + "rdfs:range": { + "@id": "rdfs:Resource" + } + }, + { + "@id": "linkedql:tag", + "@type": "owl:DatatypeProperty", + "rdfs:domain": { + "@id": "_:n8920519548104281153", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:ReversePropertyNamesAs" + }, + { + "@id": "linkedql:PropertyNamesAs" + } + ] + } + }, + "rdfs:range": { + "@id": "xsd:string" + } + }, + { + "@id": "linkedql:properties", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n3206185309683448698", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:ViewReverse" + }, + { + "@id": "linkedql:In" + }, + { + "@id": "linkedql:ViewBoth" + }, + { + "@id": "linkedql:View" + }, + { + "@id": "linkedql:Out" + } + ] + } + }, + "rdfs:range": { + "@id": "linkedql:PathStep" + } + }, + { + "@id": "linkedql:names", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n8548896802306168646", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:Properties" + }, + { + "@id": "linkedql:ReverseProperties" + } + ] + } + }, + "rdfs:range": { + "@id": "xsd:string" + } + }, + { + "@id": "linkedql:property", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n551031445573634888", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:Has" + }, + { + "@id": "linkedql:HasReverse" + } + ] + } + }, + "rdfs:range": { + "@id": "linkedql:PathStep" + } + }, + { + "@id": "linkedql:tags", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n4101380889439320733", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:SelectFirst" + }, + { + "@id": "linkedql:Select" + } + ] + } + }, + "rdfs:range": { + "@id": "xsd:string" + } + }, + { + "@id": "linkedql:filter", + "@type": "owl:ObjectProperty", + "rdfs:domain": "linkedql:Filter", + "rdfs:range": { + "@id": "linkedql:Operator" + } + }, + { + "@id": "linkedql:name", + "@type": "owl:DatatypeProperty", + "rdfs:domain": { + "@id": "_:n4255376591434887535", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:Back" + }, + { + "@id": "linkedql:As" + } + ] + } + }, + "rdfs:range": { + "@id": "xsd:string" + } + }, + { + "@id": "linkedql:followed", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n5693611581576660543", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:Follow" + }, + { + "@id": "linkedql:FollowReverse" + } + ] + } + }, + "rdfs:range": { + "@id": "linkedql:PathStep" + } + }, + { + "@id": "linkedql:steps", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n4411805662897003741", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:Difference" + }, + { + "@id": "linkedql:Union" + }, + { + "@id": "linkedql:Intersect" + } + ] + } + }, + "rdfs:range": { + "@id": "linkedql:PathStep" + } + }, + { + "@id": "linkedql:limit", + "@type": "owl:DatatypeProperty", + "rdfs:domain": "linkedql:Limit", + "rdfs:range": { + "@id": "xsd:int" + } + }, + { + "@id": "linkedql:offset", + "@type": "owl:DatatypeProperty", + "rdfs:domain": "linkedql:Skip", + "rdfs:range": { + "@id": "xsd:int" + } + }, + { + "@id": "linkedql:from", + "@type": "owl:ObjectProperty", + "rdfs:domain": { + "@id": "_:n7112012358991747784", + "@type": "owl:Class", + "owl:unionOf": { + "@list": [ + { + "@id": "linkedql:ReversePropertyNames" + }, + { + "@id": "linkedql:Has" + }, + { + "@id": "linkedql:Count" + }, + { + "@id": "linkedql:Filter" + }, + { + "@id": "linkedql:ViewReverse" + }, + { + "@id": "linkedql:Follow" + }, + { + "@id": "linkedql:HasReverse" + }, + { + "@id": "linkedql:Is" + }, + { + "@id": "linkedql:ReverseProperties" + }, + { + "@id": "linkedql:Select" + }, + { + "@id": "linkedql:View" + }, + { + "@id": "linkedql:Unique" + }, + { + "@id": "linkedql:As" + }, + { + "@id": "linkedql:In" + }, + { + "@id": "linkedql:Limit" + }, + { + "@id": "linkedql:PropertyNames" + }, + { + "@id": "linkedql:Back" + }, + { + "@id": "linkedql:ReversePropertyNamesAs" + }, + { + "@id": "linkedql:Order" + }, + { + "@id": "linkedql:Value" + }, + { + "@id": "linkedql:PropertyNamesAs" + }, + { + "@id": "linkedql:Difference" + }, + { + "@id": "linkedql:ViewBoth" + }, + { + "@id": "linkedql:Skip" + }, + { + "@id": "linkedql:SelectFirst" + }, + { + "@id": "linkedql:Union" + }, + { + "@id": "linkedql:Intersect" + }, + { + "@id": "linkedql:Labels" + }, + { + "@id": "linkedql:FollowReverse" + }, + { + "@id": "linkedql:Properties" + }, + { + "@id": "linkedql:Out" + } + ] + } + }, + "rdfs:range": { + "@id": "linkedql:PathStep" + } + } + ] } diff --git a/query/linkedql/client/client.go b/query/linkedql/client/client.go index 4bcdba0cd..70a68244b 100644 --- a/query/linkedql/client/client.go +++ b/query/linkedql/client/client.go @@ -6,117 +6,117 @@ import ( type Path map[string]interface{} -// As As assigns the resolved values of the from step to a given name. The name can be used with the Select and Documents steps to retreive the values or to return to the values in further steps with the Back step. It resolves to the values of the from step. +// As assigns the resolved values of the from step to a given name. The name can be used with the Select and Documents steps to retreive the values or to return to the values in further steps with the Back step. It resolves to the values of the from step. func (p Path) As(name string) Path { return Path{"@type": "http://cayley.io/linkedql#As", "from": p, "http://cayley.io/linkedql#name": name} } -// Back Back resolves to the values of the previous the step or the values assigned to name in a former step. +// Back resolves to the values of the previous the step or the values assigned to name in a former step. func (p Path) Back(name string) Path { return Path{"@type": "http://cayley.io/linkedql#Back", "from": p, "http://cayley.io/linkedql#name": name} } -// Count Count resolves to the number of the resolved values of the from step +// Count resolves to the number of the resolved values of the from step func (p Path) Count() Path { return Path{"@type": "http://cayley.io/linkedql#Count", "from": p} } -// Difference Difference resolves to all the values resolved by the from step different then the values resolved by the provided steps. Caution: it might be slow to execute. +// Difference resolves to all the values resolved by the from step different then the values resolved by the provided steps. Caution: it might be slow to execute. func (p Path) Difference(steps []Path) Path { return Path{"@type": "http://cayley.io/linkedql#Difference", "from": p, "http://cayley.io/linkedql#steps": steps} } -// Filter Apply constraints to a set of nodes. Can be used to filter values by range or match strings. +// Filter applies constraints to a set of nodes. Can be used to filter values by range or match strings. func (p Path) Filter() Path { return Path{"@type": "http://cayley.io/linkedql#Filter", "from": p} } -// Follow The way to use a path prepared with Morphism. Applies the path chain on the morphism object to the current path. Starts as if at the g.M() and follows through the morphism path. +// Follow is the way to use a path prepared with Morphism. Applies the path chain on the morphism object to the current path. Starts as if at the g.M() and follows through the morphism path. func (p Path) Follow(followed Path) Path { return Path{"@type": "http://cayley.io/linkedql#Follow", "from": p, "http://cayley.io/linkedql#followed": followed} } -// FollowReverse The same as follow but follows the chain in the reverse direction. Flips View and ViewReverse where appropriate, the net result being a virtual predicate followed in the reverse direction. Starts at the end of the morphism and follows it backwards (with appropriate flipped directions) to the g.M() location. +// FollowReverse is the same as follow but follows the chain in the reverse direction. Flips View and ViewReverse where appropriate, the net result being a virtual predicate followed in the reverse direction. Starts at the end of the morphism and follows it backwards (with appropriate flipped directions) to the g.M() location. func (p Path) FollowReverse(followed Path) Path { return Path{"@type": "http://cayley.io/linkedql#FollowReverse", "from": p, "http://cayley.io/linkedql#followed": followed} } -// Has Filter all paths which are, at this point, on the subject for the given predicate and object, but do not follow the path, merely filter the possible paths. Usually useful for starting with all nodes, or limiting to a subset depending on some predicate/value pair. +// Has filters all paths which are, at this point, on the subject for the given predicate and object, but do not follow the path, merely filter the possible paths. Usually useful for starting with all nodes, or limiting to a subset depending on some predicate/value pair. func (p Path) Has(property Path, values []quad.Value) Path { return Path{"@type": "http://cayley.io/linkedql#Has", "from": p, "http://cayley.io/linkedql#property": property, "http://cayley.io/linkedql#values": values} } -// HasReverse The same as Has, but sets constraint in reverse direction. +// HasReverse is the same as Has, but sets constraint in reverse direction. func (p Path) HasReverse(property Path, values []quad.Value) Path { return Path{"@type": "http://cayley.io/linkedql#HasReverse", "from": p, "http://cayley.io/linkedql#property": property, "http://cayley.io/linkedql#values": values} } -// In Alias for ViewReverse +// In aliases for ViewReverse func (p Path) In(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#In", "from": p, "http://cayley.io/linkedql#properties": properties} } -// Intersect Intersect resolves to all the same values resolved by the from step and the provided steps. +// Intersect resolves to all the same values resolved by the from step and the provided steps. func (p Path) Intersect(steps []Path) Path { return Path{"@type": "http://cayley.io/linkedql#Intersect", "from": p, "http://cayley.io/linkedql#steps": steps} } -// Is Is resolves to all the values resolved by the from step which are included in provided values. +// Is resolves to all the values resolved by the from step which are included in provided values. func (p Path) Is(values []quad.Value) Path { return Path{"@type": "http://cayley.io/linkedql#Is", "from": p, "http://cayley.io/linkedql#values": values} } -// Labels Get the list of inbound and outbound quad labels +// Labels gets the list of inbound and outbound quad labels func (p Path) Labels() Path { return Path{"@type": "http://cayley.io/linkedql#Labels", "from": p} } -// Limit Limit a number of nodes for current path. +// Limit limits a number of nodes for current path. func (p Path) Limit() Path { return Path{"@type": "http://cayley.io/linkedql#Limit", "from": p} } -// Order Order sorts the results in ascending order according to the current entity / value +// Order sorts the results in ascending order according to the current entity / value func (p Path) Order() Path { return Path{"@type": "http://cayley.io/linkedql#Order", "from": p} } -// Out Alias for View +// Out aliases for View func (p Path) Out(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#Out", "from": p, "http://cayley.io/linkedql#properties": properties} } -// Placeholder Placeholder is like Vertex but resolves to the values in the context it is placed in. It should only be used where a PathStep is expected and can't be resolved on its own. +// Placeholder is like Vertex but resolves to the values in the context it is placed in. It should only be used where a PathStep is expected and can't be resolved on its own. func Placeholder() Path { return Path{"@type": "http://cayley.io/linkedql#Placeholder"} } -// Properties Adds tags for all properties of the current entity +// Properties adds tags for all properties of the current entity func (p Path) Properties(names []string) Path { return Path{"@type": "http://cayley.io/linkedql#Properties", "from": p, "http://cayley.io/linkedql#names": names} } -// PropertyNames Get the list of predicates that are pointing out from a node. +// PropertyNames gets the list of predicates that are pointing out from a node. func (p Path) PropertyNames() Path { return Path{"@type": "http://cayley.io/linkedql#PropertyNames", "from": p} } -// PropertyNamesAs Tag the list of predicates that are pointing out from a node. +// PropertyNamesAs tags the list of predicates that are pointing out from a node. func (p Path) PropertyNamesAs(tag string) Path { return Path{"@type": "http://cayley.io/linkedql#PropertyNamesAs", "from": p, "http://cayley.io/linkedql#tag": tag} } -// ReverseProperties Gets all the properties the current entity / value is referenced at +// ReverseProperties gets all the properties the current entity / value is referenced at func (p Path) ReverseProperties(names []string) Path { return Path{"@type": "http://cayley.io/linkedql#ReverseProperties", "from": p, "http://cayley.io/linkedql#names": names} } -// ReversePropertyNames Get the list of predicates that are pointing in to a node. +// ReversePropertyNames gets the list of predicates that are pointing in to a node. func (p Path) ReversePropertyNames() Path { return Path{"@type": "http://cayley.io/linkedql#ReversePropertyNames", "from": p} } -// ReversePropertyNamesAs Tag the list of predicates that are pointing in to a node. +// ReversePropertyNamesAs tags the list of predicates that are pointing in to a node. func (p Path) ReversePropertyNamesAs(tag string) Path { return Path{"@type": "http://cayley.io/linkedql#ReversePropertyNamesAs", "from": p, "http://cayley.io/linkedql#tag": tag} } @@ -131,17 +131,17 @@ func (p Path) SelectFirst(tags []string) Path { return Path{"@type": "http://cayley.io/linkedql#SelectFirst", "from": p, "http://cayley.io/linkedql#tags": tags} } -// Skip Skip a number of nodes for current path. +// Skip skips a number of nodes for current path. func (p Path) Skip() Path { return Path{"@type": "http://cayley.io/linkedql#Skip", "from": p} } -// Union Return the combined paths of the two queries. Notice that it's per-path, not per-node. Once again, if multiple paths reach the same destination, they might have had different ways of getting there (and different tags). +// Union returns the combined paths of the two queries. Notice that it's per-path, not per-node. Once again, if multiple paths reach the same destination, they might have had different ways of getting there (and different tags). func (p Path) Union(steps []Path) Path { return Path{"@type": "http://cayley.io/linkedql#Union", "from": p, "http://cayley.io/linkedql#steps": steps} } -// Unique Remove duplicate values from the path. +// Unique removes duplicate values from the path. func (p Path) Unique() Path { return Path{"@type": "http://cayley.io/linkedql#Unique", "from": p} } @@ -151,22 +151,22 @@ func (p Path) Value() Path { return Path{"@type": "http://cayley.io/linkedql#Value", "from": p} } -// Vertex Vertex resolves to all the existing objects and primitive values in the graph. If provided with values resolves to a sublist of all the existing values in the graph. +// Vertex resolves to all the existing objects and primitive values in the graph. If provided with values resolves to a sublist of all the existing values in the graph. func Vertex(values []quad.Value) Path { return Path{"@type": "http://cayley.io/linkedql#Vertex", "http://cayley.io/linkedql#values": values} } -// View View resolves to the values of the given property or properties in via of the current objects. If via is a path it's resolved values will be used as properties. +// View resolves to the values of the given property or properties in via of the current objects. If via is a path it's resolved values will be used as properties. func (p Path) View(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#View", "from": p, "http://cayley.io/linkedql#properties": properties} } -// ViewBoth ViewBoth is like View but resolves to both the object values and references to the values of the given properties in via. It is the equivalent for the Union of View and ViewReverse of the same property. +// ViewBoth is like View but resolves to both the object values and references to the values of the given properties in via. It is the equivalent for the Union of View and ViewReverse of the same property. func (p Path) ViewBoth(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#ViewBoth", "from": p, "http://cayley.io/linkedql#properties": properties} } -// ViewReverse The inverse of View. Starting with the nodes in `path` on the object, follow the quads with predicates defined by `predicatePath` to their subjects. +// ViewReverse is the inverse of View. Starting with the nodes in `path` on the object, follow the quads with predicates defined by `predicatePath` to their subjects. func (p Path) ViewReverse(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#ViewReverse", "from": p, "http://cayley.io/linkedql#properties": properties} } From abd548c2a0f0c5b5ceb75e2cf2dba3ccdbeeef15 Mon Sep 17 00:00:00 2001 From: Iddan Aaronsohn Date: Fri, 13 Dec 2019 13:29:13 +0200 Subject: [PATCH 26/27] linkedql: Correct type handling in client --- .../generate_linkedql_client.go | 7 +- internal/linkedql/schema/schema.go | 19 +- linkedql.json | 747 ++++++++++-------- owl/owl.go | 2 +- query/linkedql/client/client.go | 12 +- 5 files changed, 457 insertions(+), 330 deletions(-) diff --git a/cmd/generate_linkedql_client/generate_linkedql_client.go b/cmd/generate_linkedql_client/generate_linkedql_client.go index b0caac6cc..59079bc18 100644 --- a/cmd/generate_linkedql_client/generate_linkedql_client.go +++ b/cmd/generate_linkedql_client/generate_linkedql_client.go @@ -23,7 +23,9 @@ import ( const schemaFile = "linkedql.json" const outputFilePath = "query/linkedql/client/client.go" +var stepIRI = quad.IRI("http://cayley.io/linkedql#Step") var pathStepIRI = quad.IRI("http://cayley.io/linkedql#PathStep") +var iteratorStepIRI = quad.IRI("http://cayley.io/linkedql#IteratorStep") func main() { ctx := context.TODO() @@ -33,7 +35,7 @@ func main() { panic(err) } - stepClass, err := owl.GetClass(ctx, qs, pathStepIRI) + stepClass, err := owl.GetClass(ctx, qs, stepIRI) if err != nil { panic(err) @@ -43,6 +45,9 @@ func main() { var decls []ast.Decl for _, stepSubClass := range stepSubClasses { + if stepSubClass.Identifier == pathStepIRI || stepSubClass.Identifier == iteratorStepIRI { + continue + } stepSubClassDecls, err := stepSubClassToDecls(stepSubClass) if err != nil { panic(err) diff --git a/internal/linkedql/schema/schema.go b/internal/linkedql/schema/schema.go index b7868ebe1..c12e9c0a6 100644 --- a/internal/linkedql/schema/schema.go +++ b/internal/linkedql/schema/schema.go @@ -250,6 +250,23 @@ func (g *generator) Generate() []byte { Range: rng, }) } + graph := []interface{}{ + map[string]string{ + "@id": "linkedql:Step", + "@type": "owl:Class", + }, + map[string]interface{}{ + "@id": "linkedql:PathStep", + "@type": "owl:Class", + "rdfs:subClassOf": map[string]string{"@id": "linkedql:Step"}, + }, + map[string]interface{}{ + "@id": "linkedql:IteratorStep", + "@type": "owl:Class", + "rdfs:subClassOf": map[string]string{"@id": "linkedql:Step"}, + }, + } + graph = append(graph, g.out...) data, err := json.Marshal(map[string]interface{}{ "@context": map[string]interface{}{ "rdf": map[string]string{"@id": "http://www.w3.org/1999/02/22-rdf-syntax-ns#"}, @@ -258,7 +275,7 @@ func (g *generator) Generate() []byte { "xsd": map[string]string{"@id": "http://www.w3.org/2001/XMLSchema#"}, "linkedql": map[string]string{"@id": "http://cayley.io/linkedql#"}, }, - "@graph": g.out, + "@graph": graph, }) if err != nil { panic(err) diff --git a/linkedql.json b/linkedql.json index db07f5113..74a4cd838 100644 --- a/linkedql.json +++ b/linkedql.json @@ -18,41 +18,57 @@ }, "@graph": [ { - "@id": "linkedql:Back", + "@id": "linkedql:Step", + "@type": "owl:Class" + }, + { + "@id": "linkedql:PathStep", + "@type": "owl:Class", + "rdfs:subClassOf": { + "@id": "linkedql:Step" + } + }, + { + "@id": "linkedql:IteratorStep", + "@type": "owl:Class", + "rdfs:subClassOf": { + "@id": "linkedql:Step" + } + }, + { + "@id": "linkedql:Is", "@type": "rdfs:Class", - "rdfs:comment": "resolves to the values of the previous the step or the values assigned to name in a former step.", + "rdfs:comment": "resolves to all the values resolved by the from step which are included in provided values.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n7908088290697276681", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } + "@id": "linkedql:IteratorStep" }, { - "@id": "_:n5997096025876839690", + "@id": "_:n3613043289672097141", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:name" + "@id": "linkedql:from" } } ] }, { - "@id": "linkedql:As", + "@id": "linkedql:FollowReverse", "@type": "rdfs:Class", - "rdfs:comment": "assigns the resolved values of the from step to a given name. The name can be used with the Select and Documents steps to retreive the values or to return to the values in further steps with the Back step. It resolves to the values of the from step.", + "rdfs:comment": "is the same as follow but follows the chain in the reverse direction. Flips View and ViewReverse where appropriate, the net result being a virtual predicate followed in the reverse direction. Starts at the end of the morphism and follows it backwards (with appropriate flipped directions) to the g.M() location.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n7988485489972284209", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n9083091194127967913", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -60,105 +76,114 @@ } }, { - "@id": "_:n7567688478636418594", + "@id": "_:n8063055307955585418", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:name" + "@id": "linkedql:followed" } } ] }, { - "@id": "linkedql:Vertex", + "@id": "linkedql:Labels", "@type": "rdfs:Class", - "rdfs:comment": "resolves to all the existing objects and primitive values in the graph. If provided with values resolves to a sublist of all the existing values in the graph.", + "rdfs:comment": "gets the list of inbound and outbound quad labels", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" + }, + { + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n8459855700265692209", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } } ] }, { - "@id": "linkedql:ReversePropertyNamesAs", + "@id": "linkedql:Unique", "@type": "rdfs:Class", - "rdfs:comment": "tags the list of predicates that are pointing in to a node.", + "rdfs:comment": "removes duplicate values from the path.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n8383648757660417451", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } + "@id": "linkedql:IteratorStep" }, { - "@id": "_:n6926458250230044772", + "@id": "_:n2710973548941612352", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:tag" + "@id": "linkedql:from" } } ] }, { - "@id": "linkedql:Value", + "@id": "linkedql:Vertex", "@type": "rdfs:Class", - "rdfs:comment": "Value returns a single value matched in the query", + "rdfs:comment": "resolves to all the existing objects and primitive values in the graph. If provided with values resolves to a sublist of all the existing values in the graph.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n1841094452838461572", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } + "@id": "linkedql:IteratorStep" } ] }, { - "@id": "linkedql:Follow", + "@id": "linkedql:Placeholder", "@type": "rdfs:Class", - "rdfs:comment": "is the way to use a path prepared with Morphism. Applies the path chain on the morphism object to the current path. Starts as if at the g.M() and follows through the morphism path.", + "rdfs:comment": "is like Vertex but resolves to the values in the context it is placed in. It should only be used where a PathStep is expected and can't be resolved on its own.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + } + ] + }, + { + "@id": "linkedql:Count", + "@type": "rdfs:Class", + "rdfs:comment": "resolves to the number of the resolved values of the from step", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n2005093628341939828", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } + "@id": "linkedql:IteratorStep" }, { - "@id": "_:n5104241301475361160", + "@id": "_:n3236938820904012665", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:followed" + "@id": "linkedql:from" } } ] }, { - "@id": "linkedql:FollowReverse", + "@id": "linkedql:Skip", "@type": "rdfs:Class", - "rdfs:comment": "is the same as follow but follows the chain in the reverse direction. Flips View and ViewReverse where appropriate, the net result being a virtual predicate followed in the reverse direction. Starts at the end of the morphism and follows it backwards (with appropriate flipped directions) to the g.M() location.", + "rdfs:comment": "skips a number of nodes for current path.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n4584588397207050072", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n8331721404640161545", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -166,25 +191,28 @@ } }, { - "@id": "_:n4166975175965651772", + "@id": "_:n5928433611785803765", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:followed" + "@id": "linkedql:offset" } } ] }, { - "@id": "linkedql:In", + "@id": "linkedql:Back", "@type": "rdfs:Class", - "rdfs:comment": "aliases for ViewReverse", + "rdfs:comment": "resolves to the values of the previous the step or the values assigned to name in a former step.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n1870897588368680998", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n7318884210772532587", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -192,25 +220,28 @@ } }, { - "@id": "_:n3607726901418144227", + "@id": "_:n5159571487667235037", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:properties" + "@id": "linkedql:name" } } ] }, { - "@id": "linkedql:ReversePropertyNames", + "@id": "linkedql:Properties", "@type": "rdfs:Class", - "rdfs:comment": "gets the list of predicates that are pointing in to a node.", + "rdfs:comment": "adds tags for all properties of the current entity", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n3903726778461453772", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n9018236344034770769", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -220,15 +251,18 @@ ] }, { - "@id": "linkedql:Labels", + "@id": "linkedql:PropertyNames", "@type": "rdfs:Class", - "rdfs:comment": "gets the list of inbound and outbound quad labels", + "rdfs:comment": "gets the list of predicates that are pointing out from a node.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n2891927322902708841", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n4445626993086337411", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -238,20 +272,31 @@ ] }, { - "@id": "linkedql:Properties", + "@id": "linkedql:ReversePropertyNamesAs", "@type": "rdfs:Class", - "rdfs:comment": "adds tags for all properties of the current entity", + "rdfs:comment": "tags the list of predicates that are pointing in to a node.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n6424233792414955944", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n8112324779916985026", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { "@id": "linkedql:from" } + }, + { + "@id": "_:n5338493051676230997", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:tag" + } } ] }, @@ -264,7 +309,10 @@ "@id": "linkedql:PathStep" }, { - "@id": "_:n4418208634829485365", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n5768812609992315503", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -272,7 +320,7 @@ } }, { - "@id": "_:n201410601521517206", + "@id": "_:n8287472848602919900", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -282,15 +330,18 @@ ] }, { - "@id": "linkedql:Difference", + "@id": "linkedql:ReverseProperties", "@type": "rdfs:Class", - "rdfs:comment": "resolves to all the values resolved by the from step different then the values resolved by the provided steps. Caution: it might be slow to execute.", + "rdfs:comment": "gets all the properties the current entity / value is referenced at", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n3223642664820787682", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n443301574217807823", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -300,27 +351,37 @@ ] }, { - "@id": "linkedql:Has", + "@id": "linkedql:Select", "@type": "rdfs:Class", - "rdfs:comment": "filters all paths which are, at this point, on the subject for the given predicate and object, but do not follow the path, merely filter the possible paths. Usually useful for starting with all nodes, or limiting to a subset depending on some predicate/value pair.", + "rdfs:comment": "Select returns flat records of tags matched in the query", "rdfs:subClassOf": [ { - "@id": "linkedql:PathStep" + "@id": "linkedql:IteratorStep" }, { - "@id": "_:n2349392202041882821", + "@id": "_:n8116377088366467444", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { "@id": "linkedql:from" } + } + ] + }, + { + "@id": "linkedql:Value", + "@type": "rdfs:Class", + "rdfs:comment": "Value returns a single value matched in the query", + "rdfs:subClassOf": [ + { + "@id": "linkedql:IteratorStep" }, { - "@id": "_:n13257026593940279", + "@id": "_:n1211474119861900589", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:property" + "@id": "linkedql:from" } } ] @@ -334,7 +395,10 @@ "@id": "linkedql:PathStep" }, { - "@id": "_:n9128900241535060479", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n793190407192836422", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -342,7 +406,7 @@ } }, { - "@id": "_:n2741547127402511673", + "@id": "_:n7208921910592501003", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -352,15 +416,18 @@ ] }, { - "@id": "linkedql:ViewBoth", + "@id": "linkedql:In", "@type": "rdfs:Class", - "rdfs:comment": "is like View but resolves to both the object values and references to the values of the given properties in via. It is the equivalent for the Union of View and ViewReverse of the same property.", + "rdfs:comment": "aliases for ViewReverse", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n8502434772150270123", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n8239793418546475073", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -368,7 +435,7 @@ } }, { - "@id": "_:n5585646283882161042", + "@id": "_:n4982870279148793564", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -378,15 +445,18 @@ ] }, { - "@id": "linkedql:Is", + "@id": "linkedql:Order", "@type": "rdfs:Class", - "rdfs:comment": "resolves to all the values resolved by the from step which are included in provided values.", + "rdfs:comment": "sorts the results in ascending order according to the current entity / value", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n3090803183809953074", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n4658869256845579334", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -396,15 +466,39 @@ ] }, { - "@id": "linkedql:Limit", + "@id": "linkedql:ReversePropertyNames", "@type": "rdfs:Class", - "rdfs:comment": "limits a number of nodes for current path.", + "rdfs:comment": "gets the list of predicates that are pointing in to a node.", + "rdfs:subClassOf": [ + { + "@id": "linkedql:PathStep" + }, + { + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n2234785206717184905", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:from" + } + } + ] + }, + { + "@id": "linkedql:ViewBoth", + "@type": "rdfs:Class", + "rdfs:comment": "is like View but resolves to both the object values and references to the values of the given properties in via. It is the equivalent for the Union of View and ViewReverse of the same property.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n853618359657221356", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n1375394481257745149", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -412,25 +506,28 @@ } }, { - "@id": "_:n3741714749040882736", + "@id": "_:n8456254640763031822", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:limit" + "@id": "linkedql:properties" } } ] }, { - "@id": "linkedql:ReverseProperties", + "@id": "linkedql:Difference", "@type": "rdfs:Class", - "rdfs:comment": "gets all the properties the current entity / value is referenced at", + "rdfs:comment": "resolves to all the values resolved by the from step different then the values resolved by the provided steps. Caution: it might be slow to execute.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n4533390537095304805", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n3325168672420575460", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -440,15 +537,15 @@ ] }, { - "@id": "linkedql:Select", + "@id": "linkedql:SelectFirst", "@type": "rdfs:Class", - "rdfs:comment": "Select returns flat records of tags matched in the query", + "rdfs:comment": "Like Select but only returns the first result", "rdfs:subClassOf": [ { - "@id": "linkedql:PathStep" + "@id": "linkedql:IteratorStep" }, { - "@id": "_:n9181657233381629788", + "@id": "_:n3390240884242909143", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -458,15 +555,18 @@ ] }, { - "@id": "linkedql:View", + "@id": "linkedql:As", "@type": "rdfs:Class", - "rdfs:comment": "resolves to the values of the given property or properties in via of the current objects. If via is a path it's resolved values will be used as properties.", + "rdfs:comment": "assigns the resolved values of the from step to a given name. The name can be used with the Select and Documents steps to retrieve the values or to return to the values in further steps with the Back step. It resolves to the values of the from step.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n5824746053480877069", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n2526633157694802657", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -474,25 +574,28 @@ } }, { - "@id": "_:n6461519520038761833", + "@id": "_:n3429357401325124988", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:properties" + "@id": "linkedql:name" } } ] }, { - "@id": "linkedql:Out", + "@id": "linkedql:Filter", "@type": "rdfs:Class", - "rdfs:comment": "aliases for View", + "rdfs:comment": "applies constraints to a set of nodes. Can be used to filter values by range or match strings.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n8047248095020601737", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n4690243504327224094", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -500,53 +603,57 @@ } }, { - "@id": "_:n5222948747445626408", + "@id": "_:n739931276592480213", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:properties" + "@id": "linkedql:filter" } } ] }, { - "@id": "linkedql:Placeholder", + "@id": "linkedql:Has", "@type": "rdfs:Class", - "rdfs:comment": "is like Vertex but resolves to the values in the context it is placed in. It should only be used where a PathStep is expected and can't be resolved on its own.", + "rdfs:comment": "filters all paths which are, at this point, on the subject for the given predicate and object, but do not follow the path, merely filter the possible paths. Usually useful for starting with all nodes, or limiting to a subset depending on some predicate/value pair.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" - } - ] - }, - { - "@id": "linkedql:Count", - "@type": "rdfs:Class", - "rdfs:comment": "resolves to the number of the resolved values of the from step", - "rdfs:subClassOf": [ + }, { - "@id": "linkedql:PathStep" + "@id": "linkedql:IteratorStep" }, { - "@id": "_:n8390472748902891963", + "@id": "_:n4325294036727421714", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { "@id": "linkedql:from" } + }, + { + "@id": "_:n632449057788695932", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:property" + } } ] }, { - "@id": "linkedql:Filter", + "@id": "linkedql:ViewReverse", "@type": "rdfs:Class", - "rdfs:comment": "applies constraints to a set of nodes. Can be used to filter values by range or match strings.", + "rdfs:comment": "is the inverse of View. Starting with the nodes in `path` on the object, follow the quads with predicates defined by `predicatePath` to their subjects.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n1646447114406524394", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n1202338489403740068", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -554,25 +661,28 @@ } }, { - "@id": "_:n8967834957155453826", + "@id": "_:n8462290765396416742", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:filter" + "@id": "linkedql:properties" } } ] }, { - "@id": "linkedql:Skip", + "@id": "linkedql:Limit", "@type": "rdfs:Class", - "rdfs:comment": "skips a number of nodes for current path.", + "rdfs:comment": "limits a number of nodes for current path.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n4098750636493779506", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n8154336094443820555", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -580,11 +690,11 @@ } }, { - "@id": "_:n1621454338437066833", + "@id": "_:n1095931710072978339", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:offset" + "@id": "linkedql:limit" } } ] @@ -598,7 +708,10 @@ "@id": "linkedql:PathStep" }, { - "@id": "_:n1227112490286966331", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n7940960461887459839", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -608,69 +721,47 @@ ] }, { - "@id": "linkedql:Unique", + "@id": "linkedql:View", "@type": "rdfs:Class", - "rdfs:comment": "removes duplicate values from the path.", + "rdfs:comment": "resolves to the values of the given property or properties in via of the current objects. If via is a path it's resolved values will be used as properties.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n6547757674992010008", - "@type": "owl:Restriction", - "owl:cardinality": 1, - "owl:onProperty": { - "@id": "linkedql:from" - } - } - ] - }, - { - "@id": "linkedql:Order", - "@type": "rdfs:Class", - "rdfs:comment": "sorts the results in ascending order according to the current entity / value", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" + "@id": "linkedql:IteratorStep" }, { - "@id": "_:n4036254078241711198", + "@id": "_:n6177289074236883404", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { "@id": "linkedql:from" } - } - ] - }, - { - "@id": "linkedql:SelectFirst", - "@type": "rdfs:Class", - "rdfs:comment": "Like Select but only returns the first result", - "rdfs:subClassOf": [ - { - "@id": "linkedql:PathStep" }, { - "@id": "_:n1197969629924875303", + "@id": "_:n4127567549237631394", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { - "@id": "linkedql:from" + "@id": "linkedql:properties" } } ] }, { - "@id": "linkedql:ViewReverse", + "@id": "linkedql:Out", "@type": "rdfs:Class", - "rdfs:comment": "is the inverse of View. Starting with the nodes in `path` on the object, follow the quads with predicates defined by `predicatePath` to their subjects.", + "rdfs:comment": "aliases for View", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n6251537544036519808", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n301236345131105742", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -678,7 +769,7 @@ } }, { - "@id": "_:n1051213466635448344", + "@id": "_:n8700954704201023894", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -688,15 +779,18 @@ ] }, { - "@id": "linkedql:PropertyNames", + "@id": "linkedql:Intersect", "@type": "rdfs:Class", - "rdfs:comment": "gets the list of predicates that are pointing out from a node.", + "rdfs:comment": "resolves to all the same values resolved by the from step and the provided steps.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n3269172395352052471", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n6461582695449891350", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { @@ -706,20 +800,31 @@ ] }, { - "@id": "linkedql:Intersect", + "@id": "linkedql:Follow", "@type": "rdfs:Class", - "rdfs:comment": "resolves to all the same values resolved by the from step and the provided steps.", + "rdfs:comment": "is the way to use a path prepared with Morphism. Applies the path chain on the morphism object to the current path. Starts as if at the g.M() and follows through the morphism path.", "rdfs:subClassOf": [ { "@id": "linkedql:PathStep" }, { - "@id": "_:n2823818453963121638", + "@id": "linkedql:IteratorStep" + }, + { + "@id": "_:n3939936992220835105", "@type": "owl:Restriction", "owl:cardinality": 1, "owl:onProperty": { "@id": "linkedql:from" } + }, + { + "@id": "_:n8565384274678116400", + "@type": "owl:Restriction", + "owl:cardinality": 1, + "owl:onProperty": { + "@id": "linkedql:followed" + } } ] }, @@ -727,19 +832,19 @@ "@id": "linkedql:values", "@type": "owl:ObjectProperty", "rdfs:domain": { - "@id": "_:n161473765488462789", + "@id": "_:n3487211217454711567", "@type": "owl:Class", "owl:unionOf": { "@list": [ - { - "@id": "linkedql:HasReverse" - }, { "@id": "linkedql:Is" }, { "@id": "linkedql:Vertex" }, + { + "@id": "linkedql:HasReverse" + }, { "@id": "linkedql:Has" } @@ -750,11 +855,19 @@ "@id": "rdfs:Resource" } }, + { + "@id": "linkedql:offset", + "@type": "owl:DatatypeProperty", + "rdfs:domain": "linkedql:Skip", + "rdfs:range": { + "@id": "xsd:int" + } + }, { "@id": "linkedql:tag", "@type": "owl:DatatypeProperty", "rdfs:domain": { - "@id": "_:n8920519548104281153", + "@id": "_:n6718853691878301872", "@type": "owl:Class", "owl:unionOf": { "@list": [ @@ -772,69 +885,166 @@ } }, { - "@id": "linkedql:properties", + "@id": "linkedql:tags", "@type": "owl:ObjectProperty", "rdfs:domain": { - "@id": "_:n3206185309683448698", + "@id": "_:n2724656406774357364", "@type": "owl:Class", "owl:unionOf": { "@list": [ { - "@id": "linkedql:ViewReverse" - }, - { - "@id": "linkedql:In" - }, - { - "@id": "linkedql:ViewBoth" - }, - { - "@id": "linkedql:View" + "@id": "linkedql:Select" }, { - "@id": "linkedql:Out" + "@id": "linkedql:SelectFirst" } ] } }, "rdfs:range": { - "@id": "linkedql:PathStep" + "@id": "xsd:string" } }, { - "@id": "linkedql:names", + "@id": "linkedql:steps", "@type": "owl:ObjectProperty", "rdfs:domain": { - "@id": "_:n8548896802306168646", + "@id": "_:n7733331238921588911", "@type": "owl:Class", "owl:unionOf": { "@list": [ { - "@id": "linkedql:Properties" + "@id": "linkedql:Difference" }, { - "@id": "linkedql:ReverseProperties" + "@id": "linkedql:Union" + }, + { + "@id": "linkedql:Intersect" } ] } }, "rdfs:range": { - "@id": "xsd:string" + "@id": "linkedql:PathStep" } }, { - "@id": "linkedql:property", + "@id": "linkedql:filter", + "@type": "owl:ObjectProperty", + "rdfs:domain": "linkedql:Filter", + "rdfs:range": { + "@id": "linkedql:Operator" + } + }, + { + "@id": "linkedql:limit", + "@type": "owl:DatatypeProperty", + "rdfs:domain": "linkedql:Limit", + "rdfs:range": { + "@id": "xsd:int" + } + }, + { + "@id": "linkedql:from", "@type": "owl:ObjectProperty", "rdfs:domain": { - "@id": "_:n551031445573634888", + "@id": "_:n6836387890704961384", "@type": "owl:Class", "owl:unionOf": { "@list": [ { - "@id": "linkedql:Has" + "@id": "linkedql:ReversePropertyNamesAs" + }, + { + "@id": "linkedql:Value" }, { "@id": "linkedql:HasReverse" + }, + { + "@id": "linkedql:Has" + }, + { + "@id": "linkedql:View" + }, + { + "@id": "linkedql:Unique" + }, + { + "@id": "linkedql:Count" + }, + { + "@id": "linkedql:Properties" + }, + { + "@id": "linkedql:ReverseProperties" + }, + { + "@id": "linkedql:ReversePropertyNames" + }, + { + "@id": "linkedql:Filter" + }, + { + "@id": "linkedql:ViewReverse" + }, + { + "@id": "linkedql:In" + }, + { + "@id": "linkedql:Difference" + }, + { + "@id": "linkedql:Out" + }, + { + "@id": "linkedql:FollowReverse" + }, + { + "@id": "linkedql:Labels" + }, + { + "@id": "linkedql:PropertyNames" + }, + { + "@id": "linkedql:Order" + }, + { + "@id": "linkedql:As" + }, + { + "@id": "linkedql:Union" + }, + { + "@id": "linkedql:Back" + }, + { + "@id": "linkedql:PropertyNamesAs" + }, + { + "@id": "linkedql:Intersect" + }, + { + "@id": "linkedql:Is" + }, + { + "@id": "linkedql:Skip" + }, + { + "@id": "linkedql:Select" + }, + { + "@id": "linkedql:ViewBoth" + }, + { + "@id": "linkedql:SelectFirst" + }, + { + "@id": "linkedql:Limit" + }, + { + "@id": "linkedql:Follow" } ] } @@ -844,39 +1054,31 @@ } }, { - "@id": "linkedql:tags", + "@id": "linkedql:followed", "@type": "owl:ObjectProperty", "rdfs:domain": { - "@id": "_:n4101380889439320733", + "@id": "_:n1351742506042781062", "@type": "owl:Class", "owl:unionOf": { "@list": [ { - "@id": "linkedql:SelectFirst" + "@id": "linkedql:FollowReverse" }, { - "@id": "linkedql:Select" + "@id": "linkedql:Follow" } ] } }, "rdfs:range": { - "@id": "xsd:string" - } - }, - { - "@id": "linkedql:filter", - "@type": "owl:ObjectProperty", - "rdfs:domain": "linkedql:Filter", - "rdfs:range": { - "@id": "linkedql:Operator" + "@id": "linkedql:PathStep" } }, { "@id": "linkedql:name", "@type": "owl:DatatypeProperty", "rdfs:domain": { - "@id": "_:n4255376591434887535", + "@id": "_:n7858581684545641474", "@type": "owl:Class", "owl:unionOf": { "@list": [ @@ -894,42 +1096,39 @@ } }, { - "@id": "linkedql:followed", + "@id": "linkedql:names", "@type": "owl:ObjectProperty", "rdfs:domain": { - "@id": "_:n5693611581576660543", + "@id": "_:n9117289071709940667", "@type": "owl:Class", "owl:unionOf": { "@list": [ { - "@id": "linkedql:Follow" + "@id": "linkedql:Properties" }, { - "@id": "linkedql:FollowReverse" + "@id": "linkedql:ReverseProperties" } ] } }, "rdfs:range": { - "@id": "linkedql:PathStep" + "@id": "xsd:string" } }, { - "@id": "linkedql:steps", + "@id": "linkedql:property", "@type": "owl:ObjectProperty", "rdfs:domain": { - "@id": "_:n4411805662897003741", + "@id": "_:n722017989461747795", "@type": "owl:Class", "owl:unionOf": { "@list": [ { - "@id": "linkedql:Difference" - }, - { - "@id": "linkedql:Union" + "@id": "linkedql:HasReverse" }, { - "@id": "linkedql:Intersect" + "@id": "linkedql:Has" } ] } @@ -939,118 +1138,24 @@ } }, { - "@id": "linkedql:limit", - "@type": "owl:DatatypeProperty", - "rdfs:domain": "linkedql:Limit", - "rdfs:range": { - "@id": "xsd:int" - } - }, - { - "@id": "linkedql:offset", - "@type": "owl:DatatypeProperty", - "rdfs:domain": "linkedql:Skip", - "rdfs:range": { - "@id": "xsd:int" - } - }, - { - "@id": "linkedql:from", + "@id": "linkedql:properties", "@type": "owl:ObjectProperty", "rdfs:domain": { - "@id": "_:n7112012358991747784", + "@id": "_:n5924667912709065573", "@type": "owl:Class", "owl:unionOf": { "@list": [ - { - "@id": "linkedql:ReversePropertyNames" - }, - { - "@id": "linkedql:Has" - }, - { - "@id": "linkedql:Count" - }, - { - "@id": "linkedql:Filter" - }, - { - "@id": "linkedql:ViewReverse" - }, - { - "@id": "linkedql:Follow" - }, - { - "@id": "linkedql:HasReverse" - }, - { - "@id": "linkedql:Is" - }, - { - "@id": "linkedql:ReverseProperties" - }, - { - "@id": "linkedql:Select" - }, - { - "@id": "linkedql:View" - }, - { - "@id": "linkedql:Unique" - }, - { - "@id": "linkedql:As" - }, { "@id": "linkedql:In" }, - { - "@id": "linkedql:Limit" - }, - { - "@id": "linkedql:PropertyNames" - }, - { - "@id": "linkedql:Back" - }, - { - "@id": "linkedql:ReversePropertyNamesAs" - }, - { - "@id": "linkedql:Order" - }, - { - "@id": "linkedql:Value" - }, - { - "@id": "linkedql:PropertyNamesAs" - }, - { - "@id": "linkedql:Difference" - }, { "@id": "linkedql:ViewBoth" }, { - "@id": "linkedql:Skip" - }, - { - "@id": "linkedql:SelectFirst" - }, - { - "@id": "linkedql:Union" - }, - { - "@id": "linkedql:Intersect" - }, - { - "@id": "linkedql:Labels" - }, - { - "@id": "linkedql:FollowReverse" + "@id": "linkedql:ViewReverse" }, { - "@id": "linkedql:Properties" + "@id": "linkedql:View" }, { "@id": "linkedql:Out" diff --git a/owl/owl.go b/owl/owl.go index ec2a25367..d9eaf6e0f 100644 --- a/owl/owl.go +++ b/owl/owl.go @@ -165,7 +165,7 @@ var subClassOf = quad.IRI(rdfs.SubClassOf).Full() // SubClasses returns all the classes defined as sub classes of the class func (c *Class) SubClasses() []*Class { - p := c.path().In(subClassOf) + p := c.path().FollowRecursive(path.StartMorphism().In(subClassOf), 0, nil) it := p.BuildIterator(c.ctx).Iterate() var subClasses []*Class for it.Next(c.ctx) { diff --git a/query/linkedql/client/client.go b/query/linkedql/client/client.go index 70a68244b..c491eef72 100644 --- a/query/linkedql/client/client.go +++ b/query/linkedql/client/client.go @@ -6,7 +6,7 @@ import ( type Path map[string]interface{} -// As assigns the resolved values of the from step to a given name. The name can be used with the Select and Documents steps to retreive the values or to return to the values in further steps with the Back step. It resolves to the values of the from step. +// As assigns the resolved values of the from step to a given name. The name can be used with the Select and Documents steps to retrieve the values or to return to the values in further steps with the Back step. It resolves to the values of the from step. func (p Path) As(name string) Path { return Path{"@type": "http://cayley.io/linkedql#As", "from": p, "http://cayley.io/linkedql#name": name} } @@ -86,11 +86,6 @@ func (p Path) Out(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#Out", "from": p, "http://cayley.io/linkedql#properties": properties} } -// Placeholder is like Vertex but resolves to the values in the context it is placed in. It should only be used where a PathStep is expected and can't be resolved on its own. -func Placeholder() Path { - return Path{"@type": "http://cayley.io/linkedql#Placeholder"} -} - // Properties adds tags for all properties of the current entity func (p Path) Properties(names []string) Path { return Path{"@type": "http://cayley.io/linkedql#Properties", "from": p, "http://cayley.io/linkedql#names": names} @@ -170,3 +165,8 @@ func (p Path) ViewBoth(properties Path) Path { func (p Path) ViewReverse(properties Path) Path { return Path{"@type": "http://cayley.io/linkedql#ViewReverse", "from": p, "http://cayley.io/linkedql#properties": properties} } + +// Placeholder is like Vertex but resolves to the values in the context it is placed in. It should only be used where a PathStep is expected and can't be resolved on its own. +func Placeholder() Path { + return Path{"@type": "http://cayley.io/linkedql#Placeholder"} +} From 78ac6a24c6911ba683383ef4d6345892ce7bcbf4 Mon Sep 17 00:00:00 2001 From: Denys Smirnov Date: Sun, 15 Dec 2019 16:51:21 +0200 Subject: [PATCH 27/27] owl: use constants from a new voc package --- go.mod | 2 +- go.sum | 2 ++ owl/owl.go | 11 +++++---- owl/owl_test.go | 65 ++++++++++++++++++++++++++----------------------- owl/voc.go | 21 ---------------- 5 files changed, 43 insertions(+), 58 deletions(-) delete mode 100644 owl/voc.go diff --git a/go.mod b/go.mod index b3a5a890f..afe62631d 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.12 require ( github.com/badgerodon/peg v0.0.0-20130729175151-9e5f7f4d07ca - github.com/cayleygraph/quad v1.1.0 + github.com/cayleygraph/quad v1.2.0 github.com/cockroachdb/apd v1.1.0 // indirect github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect github.com/coreos/bbolt v1.3.3 // indirect diff --git a/go.sum b/go.sum index a9f06dc1b..75426f589 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,8 @@ github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/cayleygraph/quad v1.1.0 h1:w1nXAmn+nz07+qlw89dke9LwWkYpeX+OcvfTvGQRBpM= github.com/cayleygraph/quad v1.1.0/go.mod h1:maWODEekEhrO0mdc9h5n/oP7cH1h/OTgqQ2qWbuI9M4= +github.com/cayleygraph/quad v1.2.0 h1:vqf+71ZINP3eSbtaEzpey0HTr9p4M2xHdmVCda8D7+Q= +github.com/cayleygraph/quad v1.2.0/go.mod h1:maWODEekEhrO0mdc9h5n/oP7cH1h/OTgqQ2qWbuI9M4= github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= diff --git a/owl/owl.go b/owl/owl.go index d9eaf6e0f..6af8ab28d 100644 --- a/owl/owl.go +++ b/owl/owl.go @@ -9,6 +9,7 @@ import ( "github.com/cayleygraph/cayley/graph/iterator" "github.com/cayleygraph/cayley/query/path" "github.com/cayleygraph/quad" + "github.com/cayleygraph/quad/voc/owl" "github.com/cayleygraph/quad/voc/rdf" "github.com/cayleygraph/quad/voc/rdfs" ) @@ -47,7 +48,7 @@ var domain = quad.IRI(rdfs.Domain).Full() // Properties return all the properties a class instance may have func (c *Class) Properties() []*Property { // TODO(@iddan): check for super classes properties - p := c.path().Or(listContainignPath(c.qs, c.Identifier).In(quad.IRI(UnionOf))). + p := c.path().Or(listContainignPath(c.qs, c.Identifier).In(quad.IRI(owl.UnionOf))). In(domain) it := p.BuildIterator(c.ctx).Iterate() var properties []*Property @@ -99,12 +100,12 @@ func parentClassesPath(c *Class) *path.Path { func restrictionsPath(c *Class) *path.Path { return parentClassesPath(c). - Has(quad.IRI(rdf.Type).Full(), quad.IRI(Restriction)) + Has(quad.IRI(rdf.Type).Full(), quad.IRI(owl.Restriction)) } func allPropertyRestrictionsPath(c *Class, property *Property) *path.Path { return restrictionsPath(c). - Has(quad.IRI(OnProperty), property.Identifier) + Has(quad.IRI(owl.OnProperty), property.Identifier) } func propertyRestrictionPath(c *Class, property *Property, restrictionProperty quad.IRI) *path.Path { @@ -140,7 +141,7 @@ func intFromScanner(ctx context.Context, it iterator.Scanner, qs graph.QuadStore // CardinalityOf returns the defined exact cardinality for the property for the class // If exact cardinality is not defined for the class returns an error func (c *Class) CardinalityOf(property *Property) (int64, error) { - p := propertyRestrictionPath(c, property, quad.IRI(Cardinality)) + p := propertyRestrictionPath(c, property, quad.IRI(owl.Cardinality)) it := p.BuildIterator(c.ctx).Iterate() cardinality, err := intFromScanner(c.ctx, it, c.qs) if err != nil { @@ -152,7 +153,7 @@ func (c *Class) CardinalityOf(property *Property) (int64, error) { // MaxCardinalityOf returns the defined max cardinality for the property for the class // If max cardinality is not defined for the class returns an error func (c *Class) MaxCardinalityOf(property *Property) (int64, error) { - p := propertyRestrictionPath(c, property, quad.IRI(MaxCardinality)) + p := propertyRestrictionPath(c, property, quad.IRI(owl.MaxCardinality)) it := p.BuildIterator(c.ctx).Iterate() cardinality, err := intFromScanner(c.ctx, it, c.qs) if err != nil { diff --git a/owl/owl_test.go b/owl/owl_test.go index 815b145ea..c1d3481bc 100644 --- a/owl/owl_test.go +++ b/owl/owl_test.go @@ -8,21 +8,24 @@ import ( "github.com/cayleygraph/cayley/graph/memstore" "github.com/cayleygraph/cayley/query/path" "github.com/cayleygraph/quad" + "github.com/cayleygraph/quad/voc/owl" "github.com/cayleygraph/quad/voc/rdf" "github.com/cayleygraph/quad/voc/rdfs" "github.com/stretchr/testify/require" ) -var fooID = quad.IRI("ex:Foo").Full() -var barID = quad.IRI("ex:Bar").Full() -var garID = quad.IRI("ex:Gar").Full() -var bazID = quad.IRI("ex:baz").Full() -var fooBarGarUnion = quad.RandomBlankNode() -var fooBazCardinalityRestriction = quad.RandomBlankNode() -var barBazMaxCardinalityRestriction = quad.RandomBlankNode() -var exampleGraph = quad.IRI("ex:graph") +var ( + fooID = quad.IRI("ex:Foo").Full() + barID = quad.IRI("ex:Bar").Full() + garID = quad.IRI("ex:Gar").Full() + bazID = quad.IRI("ex:baz").Full() + fooBarGarUnion = quad.RandomBlankNode() + fooBazCardinalityRestriction = quad.RandomBlankNode() + barBazMaxCardinalityRestriction = quad.RandomBlankNode() + exampleGraph = quad.IRI("ex:graph") +) var fooClassQuads = []quad.Quad{ - quad.Quad{ + { Subject: fooID, Predicate: quad.IRI(rdf.Type).Full(), Object: quad.IRI(rdfs.Class).Full(), @@ -30,20 +33,20 @@ var fooClassQuads = []quad.Quad{ }, } var bazPropertyQuads = []quad.Quad{ - quad.Quad{ + { Subject: barID, Predicate: quad.IRI(rdfs.SubClassOf).Full(), Object: fooID, Label: exampleGraph, }, - quad.Quad{ + { Subject: bazID, Predicate: quad.IRI(rdfs.Domain).Full(), Object: fooID, Label: exampleGraph, }, - quad.Quad{ + { Subject: bazID, Predicate: quad.IRI(rdfs.Range).Full(), Object: barID, @@ -51,25 +54,25 @@ var bazPropertyQuads = []quad.Quad{ }, } var fooBazCardinalityRestrictionQuads = []quad.Quad{ - quad.Quad{ + { Subject: fooBazCardinalityRestriction, Predicate: quad.IRI(rdf.Type).Full(), - Object: quad.IRI(Restriction), + Object: quad.IRI(owl.Restriction), Label: exampleGraph, }, - quad.Quad{ + { Subject: fooBazCardinalityRestriction, - Predicate: quad.IRI(OnProperty), + Predicate: quad.IRI(owl.OnProperty), Object: bazID, Label: exampleGraph, }, - quad.Quad{ + { Subject: fooBazCardinalityRestriction, - Predicate: quad.IRI(Cardinality), + Predicate: quad.IRI(owl.Cardinality), Object: quad.Int(1), Label: exampleGraph, }, - quad.Quad{ + { Subject: fooID, Predicate: quad.IRI(rdfs.SubClassOf).Full(), Object: fooBazCardinalityRestriction, @@ -77,25 +80,25 @@ var fooBazCardinalityRestrictionQuads = []quad.Quad{ }, } var barBazCardinalityRestrictionQuad = []quad.Quad{ - quad.Quad{ + { Subject: barBazMaxCardinalityRestriction, Predicate: quad.IRI(rdf.Type).Full(), - Object: quad.IRI(Restriction), + Object: quad.IRI(owl.Restriction), Label: exampleGraph, }, - quad.Quad{ + { Subject: barBazMaxCardinalityRestriction, - Predicate: quad.IRI(OnProperty), + Predicate: quad.IRI(owl.OnProperty), Object: bazID, Label: exampleGraph, }, - quad.Quad{ + { Subject: barBazMaxCardinalityRestriction, - Predicate: quad.IRI(MaxCardinality), + Predicate: quad.IRI(owl.MaxCardinality), Object: quad.Int(1), Label: exampleGraph, }, - quad.Quad{ + { Subject: barID, Predicate: quad.IRI(rdfs.SubClassOf).Full(), Object: barBazMaxCardinalityRestriction, @@ -146,7 +149,7 @@ func getUnionQuads() []quad.Quad { unionQuads = append(unionQuads, membersQuads...) unionQuads = append(unionQuads, quad.Quad{ Subject: fooBarGarUnion, - Predicate: quad.IRI(UnionOf), + Predicate: quad.IRI(owl.UnionOf), Object: membersList, Label: exampleGraph, }) @@ -165,22 +168,22 @@ func getTestSet() []quad.Quad { func TestListContainingPath(t *testing.T) { ctx := context.TODO() qs := memstore.New(getTestSet()...) - p := listContainignPath(qs, fooID).In(quad.IRI(UnionOf)) + p := listContainignPath(qs, fooID).In(quad.IRI(owl.UnionOf)) values := collectPath(ctx, qs, p) require.Equal(t, []quad.Value{ fooBarGarUnion, }, values) - p = listContainignPath(qs, barID).In(quad.IRI(UnionOf)) + p = listContainignPath(qs, barID).In(quad.IRI(owl.UnionOf)) values = collectPath(ctx, qs, p) require.Equal(t, []quad.Value{ fooBarGarUnion, }, values) - p = listContainignPath(qs, garID).In(quad.IRI(UnionOf)) + p = listContainignPath(qs, garID).In(quad.IRI(owl.UnionOf)) values = collectPath(ctx, qs, p) require.Equal(t, []quad.Value{ fooBarGarUnion, }, values) - p = listContainignPath(qs, bazID).In(quad.IRI(UnionOf)) + p = listContainignPath(qs, bazID).In(quad.IRI(owl.UnionOf)) values = collectPath(ctx, qs, p) require.Equal(t, []quad.Value(nil), values) } diff --git a/owl/voc.go b/owl/voc.go deleted file mode 100644 index 7af2655ff..000000000 --- a/owl/voc.go +++ /dev/null @@ -1,21 +0,0 @@ -// Package owl contains constants of the Web Ontology Language (OWL) -package owl - -import "github.com/cayleygraph/quad/voc" - -func init() { - voc.RegisterPrefix(Prefix, NS) -} - -const ( - NS = `http://www.w3.org/2002/07/owl#` - Prefix = `owl:` -) - -const ( - UnionOf = NS + "unionOf" - Restriction = NS + "Restriction" - OnProperty = NS + "onProperty" - Cardinality = NS + "cardinality" - MaxCardinality = NS + "maxCardinality" -)