If-Then-Else in Ruta - nlp

is there something like if then else in Ruta available? I'd like to do something like:
if there's at least one term from catA, then label the document with "one"
else if there's at least one term from catB, then label the document with "two"
else label the document with "three".
All the best
Philipp

There is no language structure for if-then-else in UIMA Ruta (2.7.0).
You need to duplicate some parts of the rule in order to model the else part, e.g., something like the following:
Document{CONTAINS(CatA) -> One};
Document{-CONTAINS(CatA), CONTAINS(CatB) -> Two};
Document{-CONTAINS(CatA), -CONTAINS(CatB) -> Three};
You could also check if the previous rule has matched and depend on that.
How the rule should actually look like depends mainly on the type system and how you want to model the information (features?).
DISCLAIMER: I am a developer of UIMA Ruta

I think you are asking about If-else-if in Ruta. This is possible using "ONLYFIRST"
PACKAGE uima.ruta.example;
DECLARE CatA,CatB,CatC;
"CatA"->CatA;
"CatB"->CatB;
"CatC"->CatC;
DECLARE one,two,three;
ONLYFIRST Document{}{
Document{CONTAINS(CatA) -> one};
Document{CONTAINS(CatB) -> two};
Document{CONTAINS(CatC) -> three};
}

Related

How can I emphasize an impex macro if it is part of a string?

How can I emphasize an impex macro if it is part of a string?
We can do something like this:
$prefix=alpha
$contentCatalog=$prefixContentCatalog
... and $contentCatalog will return "alphaContentCatalog".
Can I make the macro more explicit with something like:
$contentCatalog={$prefix}ContentCatalog
... so that I can immediately see that the macro is $prefix? Is there a syntax for this? (NOTE: The curly brace is just an example. This syntax/symbol doesn't exist for this purpose)
Another example: If I have something like below, it becomes confusing:
$prefix=electronics
$contentCatalog=$prefixContentCatalog
$contentCatalogFolderName=$contentCatalogFolder
But it can be easier to understand if it can be written as:
$prefix=electronics
$contentCatalog={$prefix}ContentCatalog
$contentCatalogFolderName={$contentCatalog}Folder
Hhmmm, unfortunately I don't think there is anything for this. I only see some workarounds like special naming for macro variables:
$_prefix_=electronics
$_contentCatalog_=$_prefix_ContentCatalog
$contentCatalogFolderName=$_contentCatalog_Folder
there is an alternate way to customize the micro via injecting property in local.properties and using ConfigPropertyImportProcessor.
UPDATE GenericItem[processor = de.hybris.platform.commerceservices.impex.impl.ConfigPropertyImportProcessor]; pk[unique = true]
$contentCatalog = $config-ly.br.content.catalog
$contentCV = catalogVersion(CatalogVersion.catalog(Catalog.id[default = $contentCatalog]), CatalogVersion.version[default = Staged])[default = $contentCatalog:Staged]
and entries should be added in local.properties.
ly.br.content.catalog=TestContentCatalog
Note:This is useful when we have multi-country.

Updating a single field in a record with Haskell #

I need to update one field of a very large default record.
As the default may change I don't want to rebuild the entire record manually.
Now I have come across the following way of doing this, but I am not sure how it works:
unaggregate :: MyResult -> MyResult
unaggregate calc#MyResult{..} = calc{ the_defaults = the_override
`mappend` the_defaults }
where
the_override = create ("aggregation" := False)
I have tried searching for 'Haskell # operator' in Google but it does not return immediately useful information.
I saw somewhere calc#MyResult{..} does pattern matching on variables but I don't see what variable calc does for the MyResult record...
Also I have looked up mappend (and Monoids) and I am not sure how these work either...
Thank you for any help
The # symbol is called an "as-pattern". In the example above, you can use calc to mean the whole record. Usually you'd use it like this: calc#(MyResult someResult) -- so you can have both the whole thing and the pieces that you're matching. You can do the same thing with lists (myList#(myHead:myTail)) or tuples (myTuple#(myFst, mySnd). It's pretty handy!
MyResult{..} uses RecordWildcards. Which is a neat extension! BUT RecordWildcards doesn't help you update just one field of a record.
You can do this instead: calc { theFieldYouWantToUpdate = somethingNew }.

UIMA Ruta Create Label over multiple Fields

I am creating my own types which should consist of an label. The Label needs to include the whole matched String (for further processing)
For Exampel this would be my rule:
(W{REGEXP("myregex1")} W{REGEXP("myregex2")}) { -> CREATE(MyType, "label"=?)}
You can see the question mark behind the "label" part. Is it possible to transfer the matched string to that label?
This is normally done with something like the MATCHEDTEXT action and a STRING variable:
STRING mt;
(W{REGEXP("myregex1")} W{REGEXP("myregex2")}) { -> MATCHEDTEXT(mt), CREATE(MyType, "label"=mt)};
With UIMA Ruta 2.5.0 (upcoming release) you can also use the implicit coveredText feature of a local annotation variable (label):
m:(W{REGEXP("myregex1")} W{REGEXP("myregex2")}) { -> CREATE(MyType, "label"=m.ct)};
DISCLAIMER: I am a developer of UIMA Ruta

constructing data-type instances from CSV

I have CSV data (inherited - no choice here) which I need to use to create data type instances in Haskell. parsing CSV is no problem - tutorials and APIs abound.
Here's what 'show' generates for my simplified trimmed-down test-case:
JField {fname = "cardNo", ftype = "str"} (string representation)
I am able to do a read to convert this string into a JField data record. My CSV data is just the values of the fields, so the CSV row corresponding to JField above is:
cardNo, str
and I am reading these in as List of string ["cardNo", "str"]
So - it's easy enough to brute-force the exact format of "string representation" (but writing Java or python-style string-formatting in Haskell isn't my goal here).
I thought of doing something like this (the first List is static, and the second list would be read file CSV) :
let stp1 = zip ["fname = ", "ftype ="] ["cardNo", "str"]
resulting in
[("fname = ","cardNo"),("ftype =","str")]
and then concatenating the tuples - either explicitly with ++ or in some more clever way yet to be determined.
This is my first simple piece of code outside of tutorials, so I'd like to know if this seems a reasonably Haskellian way of doing this, or what clearly better ways there are to build just this piece:
fname = "cardNo", ftype = "str"
Not expecting solutions (this is not homework, it's a learning exercise), but rather critique or guidelines for better ways to do this. Brute-forcing it would be easy but would defeat my objective, which is to learn
I might be way off, but wouldn't a map be better here? I guess I'm assuming that you read the file in with each row as a [String] i.e.
field11, field12
field21, field22
etc.
You could write
map (\[x,y] -> JField {fname = x, ftype = y}) data
where data is your input. I think that would do it.
If you already have the value of the fname field (say, in the variable fn) and the value of the ftype field (in ft), just do JField {fname=fn, ftype=ft}. For non-String fields, just insert a read where appropriate.

weighted RDF predicate (owl:ObjectProperty)

in RDF a statement is represented with S,P and O; In OWL the owl:ObjectProperty represents the predicate logic.
(S) (P) (O)
I like dog
<owl:Class rdf:about="Person" />
<owl:NamedIndividual rdf:about="I">
<rdf:type rdf:resource="Person"/>
<like rdf:resource="Dog"/>
</owl:NamedIndividual>
<owl:Class rdf:about="Pet" />
<owl:NamedIndividual rdf:about="Dog">
<rdf:type rdf:resource="Pet"/>
</owl:NamedIndividual>
<owl:ObjectProperty rdf:about="like">
<rdfs:domain>
<owl:Restriction>
<owl:onProperty rdf:resource="like"/>
<owl:someValuesFrom rdf:resource="Person"/>
</owl:Restriction>
</rdfs:domain>
<rdfs:range>
<owl:Restriction>
<owl:onProperty rdf:resource="like"/>
<owl:someValuesFrom rdf:resource="Pet"/>
</owl:Restriction>
</rdfs:range>
</owl:ObjectProperty>
But how about to describe "the degree" I like dogs?
How can I give a property or value to a predicate?
One solution I got is to extend one (S,P,O) statement to 3 statements.
For example,
(S) (P) (O)
Person isSrcOf LikeRelation
Pet isTargetOf LikeRelation
LikeRelation hasValue [0~100]
It should work but obviously it will let ontology 3 times bigger :(
I appreciate any suggestion!
I wouldn't use RDF reification, not in this case and almost not in any case. RDF reification just makes the things always more complicated. As you commented it will inflate your ontology, but not just that, it'll also make your ontology very difficult for applying OWL reasoning.
I've dealt with the same scenario that you've presented and most of times I've ended up with the following design.
(S) (P) [ (P) (O) (P) (O)]
I like [ 'what I like' Dog , 'how much I like it' 'a lot']
Class: LikeLevel //it represents class of things a person likes with a degree factor.
ObjectProperty: likeObject
Domain: LikeLevel
Range: Pet //(or Thing)
ObjectProperty: likeScale
Domain: LikeLevel
Range: xsd:int //(or an enumeration class i.e: 'nothing', 'a bit', 'very much',...)
ObjectProperty: like
Domain: Person
Range: LikeLevel
If you want to represent some instance data with this model (in RDF/Turtle syntax):
:I :like [ a :LikeLevel;
:likeObject :dogs;
:likeScale 5.7] .
In this case I'm creating a blank node for the object LikeLevel but you could create a ground object as well, sometimes you might want/need to avoid bNodes. In that case:
:I :like :a0001 .
:a0001 a :LikeLevel;
:likeObject :dogs;
:likeScale 5.7.
This design can be consider a light case of reification, the main difference with RDF reification is that keeps the ontology design in the user's model.
Your suggestion is a valid one; it is called reification and is the standard way of representing properties inherent to a relationship between two items in an ontology or RDF graph, where statements are made in a pairwise manner between items - it is a limitation of the data model itself that makes reification necessary sometimes.
If you're worried that reification will inflate your ontology, you could try the following instead, but are generally less desirable and come with their own problems:
Create specific properties, such as somewhatLikes, doesntLike, loves; this may be suitable if you have a limited set of alternatives, and don't mind creating the extra properties. This becomes tedious and cumbersome (and I'd go so far as to suggest incorrect) if you intend to encode the 'degree of likeness' with an integer (or any wide range of alternatives) - following this approach, you'd have properties like likes0, likes1, ..., likes99, likes100. This method would also preclude querying, for example, all dogs that a person likes within a range of degree values, which is possible in SPARQL with the reification approach you've specified, but not with this approach.
Attach the likesDogs property to the Person instance, if the assertion can be made against the person onto all types/instances of Dog, and not individual instances. This will, of course, be dependent of what you're trying to capture here; if it's the latter, then this also won't be appropriate.
Good luck!
I think #msalvadores gets it wrong.
Let's forget about the dogs and likes. What we are really doing here is:
a x b
axb y c
axb z d
where axb is the identifier of the a x b statement, a, b, c, d are subjects or objects and x, y, z are predicates. What we need is binding the a, x, b resources to the axb statement somehow.
This is how reification does it:
axb subject a
axb predicate x
axb object b
which I think is very easy to understand.
Let's check what msalvadores does:
:I :like [ a :LikeLevel;
:likeObject :dogs;
:likeScale 5.7] .
we can easily translate this to axb terms
a x w
w type AxbSpecificObjectWrapper
w object b
w y c
which is just mimicking reification with low quality tools and more effort (you need a wrapper class and define an object property). The a x w statement does not makes sense to me; I like a like level, which objects are dogs???
But how about to describe "the degree" I like dogs?
There are 2 ways to do this as far as I can tell with my very limited RDF knowledge.
1.) use reification
stmt_1
a LikeStatement
subject I
predicate like
object dogs
how_much "very much"
2.) instantiate a predicate class
I like_1 dogs
like_1
a Like
how_much "very much"
It depends on your taste and your actual vocab which one you choose.
How can I give a property or value to a predicate?
I don't think you understand the difference between a predicate and a statement. A great example about it is available here: Simple example of reification in RDF
Tolkien wrote Lord of the rings
Wikipedia said that
The statement here:
that: [Tolkien, wrote, LotR]
If we are making statements about the statement, we write something like this:
[Wikipedia, said, that]
If we are making statements about the predicate then we write something like this:
[Wikipedia, said, wrote]
I think there is a big difference. Reification is about making statements about statements not about predicates...
A sentence from Jena's document just catch my eye.
...OWL Full allows ... state the following .... construction:
<owl:Class rdf:ID="DigitalCamera">
<rdf:type owl:ObjectProperty />
</owl:Class>
..
does OWL Full really allow an ObjectProperty be a Class as well?
If an ObjectProperty could be a Class, and could have individuals then I could describe a statement with
S_individual P_individual O_individual
and I could have further properties on P_individual. Is it right?
or am I missing some points?
since the following RDF is valid, a corresponding OWL should be achievable.
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j.0="http://somewhere/" >
<rdf:Description rdf:about="http://somewhere/Dog_my_dog">
<j.0:name>Lucky</j.0:name>
</rdf:Description>
<rdf:Description rdf:about="http://somewhere/like_dog">
<j.0:degree>80</j.0:degree>
</rdf:Description>
<rdf:Description rdf:about="http://somewhere/Cat_my_cat">
<j.0:name>Catty</j.0:name>
</rdf:Description>
<rdf:Description rdf:about="http://somewhere/like_cat">
<j.0:degree>86</j.0:degree>
</rdf:Description>
<rdf:Description rdf:about="http://somewhere/Person_I">
<j.0:name>Bob</j.0:name>
<j.0:like_dog rdf:resource="http://somewhere/Dog_my_dog"/>
<j.0:like_cat rdf:resource="http://somewhere/Cat_my_cat"/>
</rdf:Description>
</rdf:RDF>

Resources