How to translate a first-order logic sentence into a restriction in Protègè with string matching? - string-matching

I'm tring to build an ontology to infer some informations about a domain classification and a terminology, but I'm experiencing some conceptual difficulties.
Let me explain the problem. In Protègè 4.1 i created 6 subclasses of Thing: Concept, conceptTitle, ConceptSynonym (for the classification) and Term, TermTitle, TermSynonym (for the terminology). I also have created hasConceptTitle, hasConceptSynonym, hasTermTitle and hasTermSynonym object relationships (with some constrint) to say that every Concept has one (and only one) title, and may have some synonyms, and every Term has one (and only one) title and some synonyms. Both Concept and Term have another relationship isA, giving to the classification a DAG/tree structure, while the terminology has a lattice structure (in other words, a term may be a subclass of more than one term).
Here comes the problem: I would like to create a subclass of Concept, let's say "MappedConcept"), which should be the set of mapped concepts, that is the set of concepts which have the title equals to a term's title, or it has a synonym equals to a term's title or has a synonym that is equal to a synonym of a term.
In the first-order logic, this set may be expressed as:
∀x∃y( ∃z((hasConceptTitle(x,z) ∧ hasTermTitle(y,z)) ∨
∃z((hasConceptTitle(x,z) ∧ hasTermSynonym(y,z)) ∨
∃z((hasConceptSynonym(x,z) ∧ hasTermTitle(y,z)) ∨
∃z((hasConceptSynonym(x,z) ∧ hasTermSynonym(y,z)) )
How can I obtain this? Defining data properties for "ConceptTitle", "ConceptSynonym", "TermTitle" and "TermSynonym"? And how to describe the string matches?
Maybe those 4 classes should be just data properties of Concept and Term classes?
I read the practical guide of Matthew Horridge several times, but I can't the practical ideas I have on my mind into an ongology in Protègè.
Thanks in advance.

I'm afraid you cannot do this in OWL 2 DL nor in Protégé, which is an editor for OWL 2 DL, because, as far as I can tell, it seems necessary to introduce the inverse of a datatype property, which is forbidden in OWL 2 DL. However, it's possible in OWL Full, and some DL reasoners may even be able to deal with it. Here, in Turtle:
<MappedConcept> a owl:Class;
owl:equivalentTo [
a owl:Class;
owl:unionOf (
[
a owl:Restriction;
owl:onProperty <hasConceptTitle>;
owl:someValuesFrom [
a owl:Restriction;
owl:onProperty [ owl:inverseOf <hasTermTitle> ];
owl:someValuesFrom <Term>
]
] [
a owl:Restriction;
owl:onProperty <hasConceptTitle>;
owl:someValuesFrom [
a owl:Restriction;
owl:onProperty [ owl:inverseOf <hasTermSynonym> ];
owl:someValuesFrom <Term>
]
] [
a owl:Restriction;
owl:onProperty <hasConceptSynonym>;
owl:someValuesFrom [
a owl:Restriction;
owl:onProperty [ owl:inverseOf <hasTermSynonym> ];
owl:someValuesFrom <Term>
]
] [
a owl:Restriction;
owl:onProperty <hasConceptSynonym>;
owl:someValuesFrom [
a owl:Restriction;
owl:onProperty [ owl:inverseOf <hasTermTitle> ];
owl:someValuesFrom <Term>
]
]
)
] .
You can also do it without OWL, with a rule language for instance. The rules would look closer to how you would do it in programming languages. In SWRL:
hasConceptTitle(?x,?z), hasTermTitle(?y,?z) -> MappedConcept(?x)
hasConceptTitle(?x,?z), hasTermSynonym(?y,?z) -> MappedConcept(?x)
hasConceptSynonym(?x,?z), hasTermTitle(?y,?z) -> MappedConcept(?x)
hasConceptSynonym(?x,?z), hasTermSynonym(?y,?z) -> MappedConcept(?x)

Related

jq flatten list of objects into one object

I want to go from
[
{"key_skjdghkbs": "deep house"},
{"key_kjsskjbgs": "deadmau5"},
{"key_jhw98w4hl": "progressive house"},
{"key_sjkh348vg": "swedish house mafia"},
{"key_js3485jwh": "dubstep"},
{"key_jsg587jhs": "escape"}
]
to
{
"key_skjdghkbs": "deep house",
"key_kjsskjbgs": "deadmau5"
"key_jhw98w4hl": "progressive house",
"key_sjkh348vg": "swedish house mafia",
"key_js3485jwh": "dubstep",
"key_jsg587jhs": "escape"
}
Each object in the original list has exactly one key but the keys are unique.
I could do something like jq .[] .genre if the keys were the same but they're not.
jq's add function does exactly this
jq 'add'
Try this (assuming your file is named so72297039.json):
jq '[.[] | to_entries] | flatten | from_entries' < so72297039.json
(Edit: OP edited question, so here's relevant answer)
Since duplicate keys are not possible (see other answer) you can use to format like this:
{
"artist": [
"deadmau5",
"swedish house mafia"
],
"genre": [
"deep house",
"progressive house",
"dubstep"
],
"song": [
"escape"
]
}
with a jq call like this:
jq '
map(to_entries)
| flatten
| group_by(.key)
| map({key: first.key, value: map(.value)})
| from_entries
' input.json
If the keys artist, genre, song are known in advance an easier to understand expression can be used.

when searching for text, get paths in dotted notation

I'm pretty new to jq.
For the JSON at the bottom of this post, I can do
jq '[paths as $path | select(getpath($path) == "Standard Generalized Markup Language") | $path ]' json.json
and get
[
[
"glossary",
"GlossDiv",
"GlossList",
"GlossEntry",
"GlossTerm"
]
]
How can I modify that query so that I get the paths like this?
glossary.GlossDiv.GlossList.GlossEntry.GlossTerm
json.json
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
join the path array items using the dot as delimiter.
Following your approach using paths and getpath:
[
paths as $path
| select(getpath($path) == "Standard Generalized Markup Language")
| $path | join(".")
]
Demo
Using .., strings and path:
[
path(.. | select(strings == "Standard Generalized Markup Language"))
| join(".")
]
Demo
Using tostream:
[
tostream | select(.[1] == "Standard Generalized Markup Language")[0]
| join(".")
]
Demo
[
"glossary.GlossDiv.GlossList.GlossEntry.GlossTerm"
]
If you want a stream (instead of an array) of strings, omit the top-level brackets altogether.
I've written a Bash script call jqg that will flatten JSON files and filter the results producing valid JSON output; it does pretty much what you want in a generic fashion.
Running the script with your JSON and with "Standard Generalized Markup Language" as the search string yields the following:
$ jqg "Standard Generalized Markup Language" /tmp/json.json
{
"glossary.GlossDiv.GlossList.GlossEntry.GlossTerm": "Standard Generalized Markup Language"
}
You can opt to only give the path elements and not the value:
$ jqg -K "Standard Generalized Markup Language" /tmp/json.json
[
"glossary.GlossDiv.GlossList.GlossEntry.GlossTerm"
]
and if you want the path as a string and not as full JSON, you can do that, too:
$ jqg -r -K "Standard Generalized Markup Language" /tmp/json.json
glossary.GlossDiv.GlossList.GlossEntry.GlossTerm
Note: I am the author of jqg.

fish shell --- how to simulate or implement a hash table, associative array, or key-value store

I am migrating from ksh to fish. I am finding that I miss the ability to define an associative array, hash table, dictionary, or whatever you wish to call it. Some cases can be simulated as in
set dictionary$key $value
eval echo '$'dictionary$key
But this approach is heavily limited; for example, $key may contain only letters, numbers, and underscores.
I understand that the fish approach is to find an external command when one is available, but I am a little reluctant to store key-value information in the filesystem, even in /run/user/<uid>, because that limits me to "universal" scope.
How do fish programmers work around the lack of a key-value store? Is there some simple approach that I am just missing?
Here's an example of the sort of problem I would like to solve: I would like to modify the fish_prompt function so that certain directories print not using prompt_pwd but using special abbreviations. I could certainly do this with a switch command, but I would much rather have a universal dictionary so I can just look up a directory and see if it has an abbreviation. Then I could change the abbreviations using set instead of having to edit a function.
You can store the keys in one variable and values in the other, and then use something like
if set -l index (contains -i -- foo $keys) # `set` won't modify $status, so this succeeds if `contains` succeeds
echo $values[$index]
end
to retrieve the corresponding value.
Other possibilities include alternating between key and value in one variable, though iterating through this is a pain, especially when you try to do it only with builtins. Or you could use a separator character and store a key-value pair as one element, though this won't work for directories because variables cannot contain \0 (which is the only possible separator for paths).
Here is how I implemented the alternative solution mentioned by #faho
I'm using '__' as seperator.
function set_field --argument-names dict key value
set -g $dict'__'$key $value
end
function get_field --argument-names dict key
eval echo \$$dict'__'$key
end
If you wanted to use a single variable with paired key/values, it's possible but as #faho mentioned, it is more complicated. Here's how you could do it:
function dict_keys -d "Print keys from a key/value paired list"
for idx in (seq 1 2 (count $argv))
echo $argv[$idx]
end
end
function dict_values -d "Print values from a key/value paired list"
for idx in (seq 2 2 (count $argv))
echo $argv[$idx]
end
end
function dict_get -a key -d "Get the value associated with a key in a k/v paired list"
test (count $argv) -gt 2 || return 1
set -l keyseq (seq 2 2 (count $argv))
# we can't simply use `contains` because it won't distinguish keys from values
for idx in $keyseq
if test $key = $argv[$idx]
echo $argv[(math $idx + 1)]
return
end
end
return 1
end
Then you could use these functions like this:
$ set -l mydict \
yellow banana \
red cherry \
green grape \
blue berry
$ dict_keys $mydict
yellow
red
green
blue
$ dict_values $mydict
banana
cherry
grape
berry
$ dict_get blue $mydict
berry
$ dict_get purple $mydict || echo "not found"
not found
#faho's answer got me thinking about this and there are a few this I wanted to add.
At first I wrote a small set of fish functions (A sort of library, if you will) that dealt with serialization, you would call a dict function with a key name, an operation (get, set, add or del) and it would use global variables to keep track of keys and their values. Works fine for flat hashes/dicts/objects, but felt somewhat unsatisfactory.
Then I realized I could use something like jq to (de-)serialize JSON. That would also make it a lot easier to deal with nesting, plus that allows having different dicts which use the same name for a key without any issues. It also separates "dealing-with-environment-variables" and "dealing-with-dicts(/hashes/etc)", which seems like a good idea. I'll focus on jq here, but the same applies to yq or pretty much anything, the core point is: Serialize data before storing, de-serialize when reading, and use some tool to work with such data.
I then proceeded to rewrite my functions using jq. however I soon realized it was easier to just use jq without any functions. To summarize the workfolow, let's consider OP's scenario and imagine we want to use abbreviations for User folders, or even better, we wanna use icons for such folders. To do that, let's assume we use Nerdfonts and have their icons availabe. A quick search for folders on Nerdfont's cheat sheet show we only have folder icons for the home folder (f74b), downloads(f74c) and images(f74e), so I'll use Material Design Icon's "File document box" (f719) for documents, and Material Design Icon's "Video" (fa66) for Videos.
So our Codepoints are:
User folder: \uf74b
Downloads \uf74c
Images: \uf74e
Documents: \uf719
Videos: \ufa66
So our JSON is:
{"~":"\uf74b","downloads":"\uf74c","images":"\uf74e","documents":"\uf719","videos":"\ufa66"}
I kept it in a single line for a reason which will become obvious now. Let's visualize this using jq:
echo '{"~":"\uf74b","downloads":"\uf74c","images":"\uf74e","documents":"\uf719","videos":"\ufa66"}' | jq 
For completeness sake, here's how it looks with Nerdfonts installed:
Now let's store this as a variable:
set -g FOLDER_ICONS (echo '{"~":"\uf74b","downloads":"\uf74c","images":"\uf74e","documents":"\uf719","videos":"\ufa66"}' | jq -c)
jq -c interprets JSON and outputs JSON in a compact structure, i.e., a single line. Ideal for storing variables.
If you need to edit something you can use jq, lat's say you want to change the abbreviation for documents to "doc" instead of an icon. Just do:
set -g FOLDER_ICONS (echo $FOLDER_ICONS | jq -c '.["documents"]="doc"')
The echo part is for reading a variable, and the set -g is for updating the variable. So those can be ignored if you're not working with variables.
As for retrieving values, jq also does that, obviously. Let's say you want to get the abbreviation for the documents folder, you can simply do:
echo $FOLDER_ICONS | jq -r '.["documents"]'
It will return doc. If you leave out the -r it will return "doc", with quotes, since strings are quoted in JSON.
You can also remove keys pretty easily, i.e.:
set -g FOLDER_ICONS (echo $FOLDER_ICONS | jq -c 'del(."documents")')
will set the variable FOLDER_ICONS to the result of reading it and passing its contents to jq -c 'del(."documents")', which tels jq to delete the key "documents" and output a compact representation of the JSON, i.e. a single line.
Everything I tried worked perfectly fine with nested JSON objects, so it seems like a pretty good solution. It's just a matter of keeping the operations in mind:
reading .["key"]
writing .["key"]="value"
deleting del(."key")
jq also has many other nice features, I wanted to showcase a bit of them so I tried looking for stuff that might be nice to include here. One of the things I use jq for is dealing with wayland stuff, especially swaymsg -t get_tree, which I've just ran and, with a mere 4 workspaces with a single window in each, outputs a 706-line JSON from hell (Was 929 when I wrote this, 6 windows across 5 workspaces, later I closed 2 windows I was done with so I came back here and re-ran the command to share the lowest possible value).
To give a more complex example of how jq might be used, here's parsing the swaymsg -t get_tree:
swaymsg -t get_tree | jq -C '{"id": .id, "type": .type, "name": .name, "nodes": (.nodes | map(.nodes) | flatten | map({"id": .id, "type": .type, "name": .name, "nodes": (.nodes | map(.nodes) | flatten | map({"id": .id, "type": .type, "name": .name}))}))}'
This will give you a tree with only id, type, name and nodes, where nodes is an array of objects, each consisting of the id, type, name and nodes of the children, with the children nodes also being an array of objects, now consisting of only id, type and name. In my case, it returned:
{
"id": 1,
"type": "root",
"name": "root",
"nodes": [
{
"id": 2147483646,
"type": "workspace",
"name": "__i3_scratch",
"nodes": []
},
{
"id": 184,
"type": "workspace",
"name": "1",
"nodes": []
},
{
"id": 145,
"type": "workspace",
"name": "2",
"nodes": []
},
{
"id": 172,
"type": "workspace",
"name": "3",
"nodes": [
{
"id": 173,
"type": "con",
"name": "Untitled-4 - Code - OSS"
}
]
},
{
"id": 5,
"type": "workspace",
"name": "4",
"nodes": []
}
]
}
You can also easily make a flattened version of that with jq by slightly changing the command:
swaymsg -t get_tree | jq -C '[{"id": .id, "type": .type, "name": .name}, (.nodes | map(.nodes) | flatten | map([{"id": .id, "type": .type, "name": .name}, (.nodes | map(.nodes) | flatten | map({"id": .id, "type": .type, "name": .name}))]))] | flatten'
Now instead of having a key nodes, the child nodes are also in the parent's array, flattened, in my case:
[
{
"id": 1,
"type": "root",
"name": "root"
},
{
"id": 2147483646,
"type": "workspace",
"name": "__i3_scratch"
},
{
"id": 184,
"type": "workspace",
"name": "1"
},
{
"id": 145,
"type": "workspace",
"name": "2"
},
{
"id": 172,
"type": "workspace",
"name": "3"
},
{
"id": 173,
"type": "con",
"name": "Untitled-4 - Code - OSS"
},
{
"id": 5,
"type": "workspace",
"name": "4"
}
]
It's pretty nifty, not limited to environment variables, and solves pretty much every problem I can think of. The only con is verbosity, so it may be a good idea to write a few fish functions for dealing with that, but that's beyond the scope here, as I'm focusing on a general approach to (de-)serialization of key-value mappings (i.e., dicts, hashes, objects etc), which can be (also) used with environment variables. For reference, a good starting point if dealing with variables might be:
function dict
switch $argv[2]
case write
read data
set -xg $argv[1] "$data"
case read, '*'
echo $$argv[1]
end
end
This simply deals with reading and writing to a variable, the only reason it's worth sharing is, first, that it allows piping something to a variable, and second, that it sets a starting point to make something more complex, i.e. automatically piping the echoed value to jq, or adding an add operation or whatever.
There's also the option of writing a script to deal with that, instead of using jq. Ruby's Marshal and to_yaml seems like interesting options, since I like ruby, but each person has their own preferences. For Python, pickle, pyyaml and json seem worth mentioning.
It's worth mentioning I'm not affiliated to jq in any way, never contributed nor even posted anything on issues or whatever, I just use it, and as someone who used to write scripts whenever I had to deal with JSON or YAML, it was quite surprising when I realized how powerful it was.
I finally needed this for an application, and I'm not super comfortable with fish builtins, so here is an implementation in Lua: https://gist.github.com/nrnrnr/b302db5c59c600dd75c38d460423cc3d. This code uses the alternating key/value representation:
key1 value1 key2 value2 ...

Change the length of ContextPre and ContextPost in Quanteda KWIC

Is there a way to increase the number of words appearing before and after the keyword in Quanteda kwic function?
I've tried by changing the numeric value in:
options(width = 200)
but it didn't work.
#KenBenoit
options(width) affects the number of text columns displayed by the R interpreter. You want the window argument to kwic():
> kwic(data_corpus_inaugural, "war against")
contextPre keyword contextPost
[1857-Buchanan, 2933:2934] advantage of the fortune of [ war against ] a sister republic, we
[1901-McKinley, 2284:2285] . We are not waging [ war against ] the inhabitants of the Philippine
[1901-McKinley, 2299:2300] portion of them are making [ war against ] the United States. By
[1901-McKinley, 2413:2414] used when those who make [ war against ] us shall make it no
[1933-Roosevelt, 1851:1852] Executive power to wage a [ war against ] the emergency, as great
> kwic(data_corpus_inaugural, "war against", window=7)
contextPre keyword contextPost
[1857-Buchanan, 2933:2934] to take advantage of the fortune of [ war against ] a sister republic, we purchased these
[1901-McKinley, 2284:2285] be deceived. We are not waging [ war against ] the inhabitants of the Philippine Islands.
[1901-McKinley, 2299:2300] . A portion of them are making [ war against ] the United States. By far the
[1901-McKinley, 2413:2414] needed or used when those who make [ war against ] us shall make it no more.
[1933-Roosevelt, 1851:1852] - broad Executive power to wage a [ war against ] the emergency, as great as the

Virtuoso Dump graph

Hello I have a probably simple problem but I am not able to find it anywhere in docs.
I use this code in Virtuoso Interactive SQL:
SPARQL clear graph <http://product-open-data.org/temp>;
SPARQL clear graph <http://linked.opendata.cz/resource/dataset/product-open-data.org/2014-01-01>;
DB.DBA.TTLP ('
#prefix rr: <http://www.w3.org/ns/r2rml#> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
#prefix gr: <http://purl.org/goodrelations/v1#> .
#prefix s: <http://schema.org/> .
#prefix pod: <http://linked.opendata.cz/ontology/product-open-data.org#>
<#TriplesMapBrand>
a rr:TriplesMap;
rr:logicalTable [
rr:tableSchema "POD";
rr:tableOwner "DBA";
rr:tableName "BRAND"
];
rr:subjectMap
[
rr:template "http://linked.opendata.cz/resource/brand/{BSIN}";
rr:class gr:Brand;
rr:graph <http://linked.opendata.cz/resource/dataset/product-open-data.org/2014-01-01>
];
rr:predicateObjectMap [
rr:predicateMap [rr:constant pod:bsin];
rr:objectMap [rr:termType rr:Literal; rr:column "BSIN" ];
];
rr:predicateObjectMap [
rr:predicateMap [rr:constant gr:name];
rr:objectMap [rr:termType rr:Literal; rr:column "BRAND_NM" ];
];
rr:predicateObjectMap [
rr:predicateMap [rr:constant s:url];
rr:objectMap [rr:termType rr:IRI; rr:template "{BRAND_LINK}";];
];.
', 'http://product-open-data.org/temp', 'http://product-open-data.org/temp', 0);
exec ('sparql ' || DB.DBA.R2RML_MAKE_QM_FROM_G ('http://product-open-data.org/temp','http://linked.opendata.cz/resource/dataset/product-open-data.org/2014-01-01'));
SPARQL Select * from <http://linked.opendata.cz/resource/dataset/product-open-data.org/2014-01-01>
where {?s ?o ?p.} limit 1000000;
My problem is following: I want to get a TTL file with dump_one_graph procedure. But when I run the procedure like this in iSQL:
SQL> DB.DBA.dump_one_graph('http://linked.opendata.cz/resource/dataset/product-open-data.org/2014-01-01','../R2RML/pod_',1000000000);
the only thing I get is:
Dump of graph http://linked.opendata.cz/resource/dataset/product-open-data.org/2014-01-01, as of 2014-11-11 23:46:48.000004
So my question is: where are my triples stored and why is SPARQL SELECT returning a result set while dump_one_graph doesn't?
R2RML gets mapped to Virtuoso RDFViews which are not persisted to the Quad Store by default.
There is an option to make these material or persisted to the Quad Store.
Have a look at: r2rml. There should by an option 'Enable Data Syncs with Physical Quad Store' which should do the trick. Also have a look at the Generate RDB2RDF triggers option. I don't know exactly how this will look with turtle-syntax, but you can inspect the resulting commands by using the 'Prepare to Execute Button.
Hope this helps...

Resources