How to match specific tokens in UIMA Ruta? - uima

DECLARE A,B;
DECLARE Annotation C(Annotation firstA, Annotation secondA,...);
"token1|token2|...|tokenn" -> A;
"token3|token4" -> B;
A A B {->MARK(C,1,3)};
I did with GATHER
(A COMMA A B) {-> GATHER(C,1,4,"firstA"=1,"secondA" = 3,"B"=4)};
But how about in case of unknown sequence of A type? as below, how can it be possible to store all A in features? The number of features are also unknown. In plan java, we declare String array and can add element, but in Ruta seems to be no as such process.
(A (COMMA A)+ B) {-PARTOF(C) -> GATHER(C,beginPosition,endPosition,"firstA"=1,"secondA" = 3,"thirdA"=?,so on)};

Annotations in UIMA refer to the complete span, from the begin offset to the end offset. So, if you want to specify something with two elements, then a simple annotation is not sufficient. You cannot create an annotation of the type C that covers the first A and the B but not the second A.
However, you can store the important information in feature values. How to implement it depends on various things.
If there are always exactly two annotation you want to remember, then add two features to type C and assign the feature values in the given rule, e.g., by CREATE(C,1,3,"first" = A, "second" = B ).
You can also use different actions like GATHER, or use one FSArray feature in order to store the annotations.
A complete example with a FSArray:
DECLARE A, B;
DECLARE Annotation C (FSArray as, B b);
"A" -> A;
"B" -> B;
(A (COMMA A)+ B){-PARTOF(C) -> CREATE(C, "as" = A, "b" = B)};
If applied on a text like "A, A, A B", the last rule creates one annotation of type C that stores three A annotations in the feature "as" and one B annotation in the feature "b"

Related

How to populate a relation with an axiom in event b

So, I have a Rodin event-b project and would like to define a known static relation. For examples sake, lets say I have a set {a,b,c} and would like to specify the relation constant which is equal to {(a,1),(a,2),(b,3)} in an context axiom. (May be multilined, but preferably single if feasable)
How would I go about this?
CONTEXT
example
SETS
list
CONSTANTS
a
b
c
relation
AXIOMS
axm1 : partition(list, {a}, {b}, {c})
axm2 : relation ∈ list↔1‥5
axm3 : ???
END
axm3: relation = {a↦1, a↦2, b↦3}

Exists condition in Drools

The context is employee shift rostering in OptaPlanner with Drools rules. Assume that I have some shifts and that I need to check if any of the shifts is in a list of pre-defined shifts to assign. The latter list of shifts to assign is, say, [S1,S2,S3]; I need to match the following condition (I use a colon as a "such that"):
exists s in [S1,S2,S3] : forall shift (shift != s)
How could I implement such a rule in Drools?
The following pattern will match if there is no Shift that is member of [S1, S2, S3].
not Shift( this memberOf [S1, S2, S3] )
Not sure if the list literal [S1, S2, S3] is Drools-compatible but I assume it's going to be something dynamic that will be inserted into working memory as a fact.
I think you need to represent the list of shifts to be assigned [S1, S2, S3] as a different type of fact (ShiftToAssign):
Shift { // planning entity
String id;
LocalDateTime: time;
Emploee employee;
}
ShiftToAssign { // planning fact
String id;
}
Then, instead of adding/removing elements to the pre-defined list of shifts to assign, you simply add them to #ProblemFactCollectionProperty. They will be automatically inserted into Drools working memory and so you'll be able to match your condition like this:
$s : ShiftToAssign // equivalent to: for each Si in [S1, S2, S3]
not Shift(id == $s.id) // equivalent to: there is no Shift whose id is member of the list

uima ruta create two annotations in one ruta rule

I'm writing ruta scirpts to capture sbp&dbp annotations from the text like "bp: 120/80mmHg". What I want to obtain are :
Sign: name="sbp", value=120, unit=mmHg
Sign: name="dbp", value=80, unit=mmHg
Anyone can indicate me how to do that? thanks
Doing this correctly and in the right way requires a lot of additional resources and analysis engines, e.g., concept mapping mabye against loinc, detecting arbitrary complex numeric values, detecting units and measurements, also in slash enums, normalization against si base units and so on.
Here's a simple Ruta script as a initial prototype (tested with 2.6.1):
DECLARE BloodPressure (DOUBLE systolic, DOUBLE diastolic, STRING unit);
DECLARE Unit, BloodPressureIndicator;
// mock annotations, replace with dictionary or unit parser
"mmHg" -> Unit;
"bp" -> BloodPressureIndicator;
DOUBLE d1, d2;
(BloodPressureIndicator COLON? NUM{PARSE(d1)} SPECIAL.ct=="/" NUM{PARSE(d2)} u:Unit)
{-> CREATE(BloodPressure, "systolic" = d1, "diastolic" = d2, "unit" = u.ct)};
and here an example creating two annotations of different types:
DECLARE BloodPressure (DOUBLE value, STRING unit);
DECLARE BloodPressure SBP, DBP;
DECLARE Unit, BloodPressureIndicator;
// mock annotations, replace with dictionary or unit parser
"mmHg" -> Unit;
"bp" -> BloodPressureIndicator;
DOUBLE d1, d2;
(BloodPressureIndicator COLON?
NUM{PARSE(d1) -> CREATE(SBP, "value" = d1, "unit" = u.ct)}
SPECIAL.ct=="/"
NUM{PARSE(d2) -> CREATE(DBP, "value" = d2, "unit" = u.ct)}
u:Unit);
DISCLAIMER: I am a developer of UIMA Ruta

Need to compare the feature of two annotations which having same index position-UIMA RUTA

I have two annotations named First and Second.In this I need to compare the feature of two annotations which having same index position.
First.csv:
Position1;0
Position2;1
Script:
DECLARE Second(INT secondpass);
"Position1"->Second;
WORDTABLE FirstList = 'First.csv';
DECLARE Annotation First(INT firstpass);
Document{->MARKTABLE(First, 2, FirstList,true,0,"",0, "firstpass" = 1 )};
DECLARE Text;
p1:First ANY*? p2:Second{p1.secondpass == p2.firstpass -> MARK(Text)};
p1:First # p2:Second{p1.secondpass == p2.firstpass -> MARK(Text)}; wont work because both annotations are in same positions.
Depending on how exactly the offsets need to be checked, something like the following would probably do:
p1:First{-> MARK(Text)}<-{p2:Second{p1.begin==p2.begin,p1.end==p2.end,p1.firstpass==p2.secondpass};};
or
p1:First{p1.firstpass == Second.secondpass -> MARK(Text)};
You can specify this also with a conjunct rule element (&), but I would recommend to avoid these if not really necessary.
DISCLAIMER: I am a developer of UIMA Ruta

prototype recursive $

I'm using prototype and have some divs with id p1 p2 p3...
In these divs I have some divs with id d1 d2 d3...
I would like to use $ to get the specified d element, in the specified p element.
If I'm given the values 3 and 4 I should be able to go $('p3').$('d4')
This syntax doesn't work of course.
There's an easy way to do this with jQuery so I'm assuming this exists in prototype
Unfortunately, prototype's $ function doesn't chain, as it returns an extended HTMLElement object and $ is a window method. However, you could use the $$ function along with a CSS selector to achieve this:
$$('#p3 #d4').first(); // Element with id 'd4' that's a descendant of an element with id 'p3'
While the $$ function returns an extended HTMLElement object just like $, it actually returns an array of them, as a CSS selector could potentially match multiple elements.
You can read about CSS selectors here.
Considering an id ("identifier") is (should be) unique, why not just use the most specific identifier you have -- the second one :
$('d4')
If your identifiers are not unique, they are not identifiers... And they shouldn't be used as the "id" attribute of your divs...
Actually, if you have something like this :
p1
d1
d2
p2
d1
d2
d3
p3
d1
Your "pX" can be id (they are unique), but your "dX" shouldn't be ids ; a solution might be to use the class to store the "dX" information.
A bit like this, I suppose :
id=p1
class=d1
class=d2
id=p2
class=d1
class=d2
class=d3
id=p3
class=d1
Then, you'll use the $$ function with a CSS-selector : if you want the element with a class="d2" inside the elemnt of id="p1", something like this might work :
$$('#p1 .d2');
ie :
p1 = element with id=p1
.d2 = element which has a class containing d2
Hope this is clear and helps...
This ought to work:
$('p3').select('#d4').first()
Then again, if all of your ids are unique, as they should be, why not just do this:
$('d4');
$('p3').select(new Selector('#d4'));