Hi,

Am 20.09.2016 um 21:51 schrieb Bonnie MacKellar:
> Hi,
>
> Just getting back to this since I was off at a conference. Thanks again for
> the details. This is realy helpful. I beleive that Ruta 2.5 is not yet out,
> right?

Yes, 2.5.0 is not yet release, but it will be soon, hopefully.

>
> As convenient as this rule seems
> "(?i).*(must be (?:receiving|undergoing|using) (.*) for) (.*)" ->
>         R3Dot1CurrentPurposeConstraint ("group1" = 2, "group2" = 3);
>
> I do need to be able to distinguish between group1 and group2 in a Java
> program that walks through the features. If they are both plain
> Annotations, I am assuming I would not be able to do that, so the first
> setup is probably still best.   Thanks for all your help

Just wanted to mention that you can distinguish between both since they
are in different features.

Best,

Peter

> Bonnie MacKellar
>
> On Thu, Sep 15, 2016 at 7:32 AM, Peter Klügl <peter.klu...@averbis.com>
> wrote:
>
>> Hi,
>>
>>
>> Am 14.09.2016 um 22:58 schrieb Bonnie MacKellar:
>>> OK, thanks.  I played around a little bit today with my own rules
>>>
>>> DECLARE Group1;
>>> DECLARE Group2;
>>> DECLARE R3Dot1CurrentPurposeConstraint(Annotation group1, Annotation
>>> group2);
>>>
>>> BLOCK(eachEC) EC{}{
>>>     "(?i).*(must be (?:receiving|undergoing|using) (.*) for) (.*)" ->
>>> R3Dot1CurrentPurposeConstraint,2=Group1, 3=Group2;
>>>     "(?i).*(ongoing (.*(?:therapy|treatment).*) for) (.*)" ->
>>> R3Dot1CurrentPurposeConstraint;
>>> }
>>>
>>> I want to end up with the text marked by Group1 to be the value for the
>>> group1 feature in R3Dot1CurrentPurposeConstraint (and likewise group2),
>> but
>>> I couldn't find a way to do it in my rules above, so I added this
>>>
>>> R3Dot1CurrentPurposeConstraint {->
>>> R3Dot1CurrentPurposeConstraint.group1=Group1,
>>> R3Dot1CurrentPurposeConstraint.group2=Group2};
>>>
>>> It appears to work on a small test case. Does that seem correct to you?
>> Is
>>> there a better way to do this, preferably right in the rules with the
>>> regular expressions?
>> Yes, this looks correct to me and it should do what you want, if there
>> is only exactly one annotation of each type (Group1 and Group2) within
>> the current R3Dot1CurrentPurposeConstraint annotation, or if only the
>> first one matters. And if the is no sequential dependency between Group1
>> and Group2, e.g., Group1 must occur before Group2. This should be the
>> case in your example.
>> I personally prefer labels more and more, especially because they become
>> even more powerful in ruta 2.5.0. Which is the best way to assign
>> features depends on the specific situation. The examples in my last mail
>> have all their advantages.
>>
>> I personally would write the rule this way (but this will work only in
>> 2.5.0):
>> c:R3Dot1CurrentPurposeConstraint{-> c.group1 = Group1, c.group2 = Group2};
>>
>> Here, the annotation R3Dot1CurrentPurposeConstraint in the action part
>> does not need to be resolved by the given type, but the annotation that
>> was matched by the type of the rule element is directly used. If there
>> are two R3Dot1CurrentPurposeConstraint annotations with the same
>> offsets, your rule would cause problems.
>>
>>
>> You can also assign the features directly in a simple regex rule, but
>> regex rules do not on given annotations at all but only on text. So if
>> you replace your rule with:
>>
>> "(?i).*(must be (?:receiving|undergoing|using) (.*) for) (.*)" ->
>>         R3Dot1CurrentPurposeConstraint ("group1" = 2, "group2" = 3),
>> 2=Group1, 3=Group2;
>>
>> the two features of the created R3Dot1CurrentPurposeConstraint
>> annotation will be filled with annotations. However, these annotations
>> are of type Annotation and not Group1 and Group2. If you do not care
>> about the actual type of the annotation, e.g., because you won't use
>> additional features. You can simple write
>>
>> "(?i).*(must be (?:receiving|undergoing|using) (.*) for) (.*)" ->
>>         R3Dot1CurrentPurposeConstraint ("group1" = 2, "group2" = 3);
>>
>> else you need an additional rule based on annotations like above.
>>
>>> Also, why did you declare your features as Annotation rather than
>> Employee
>>> and Employer?
>>> DECLARE EmplRelation (Annotation employee, Annotation employer);
>>>
>>> I imitated this, but to me  it would seem better to use
>>> DECLARE EmplRelation (Employee employee, Employer employer);
>>> I am sure there is a good reason for this, but I don't see it!
>> Nope, there was no good reason :-)
>>
>> It just did not matter for the example.
>>
>> When I explain these examples, I normally also explain the situation
>> when there are no Employer and Employee annotations but only Person
>> annotations. Then, only a subset of the rules will work, e.g., GATHER,
>> annotation variables, labels. In this case, I would not need to modify
>> the declare statement.
>>
>> Best,
>>
>> Peter
>>
>>
>>
>>> Thanks, this cleared up some amount of confusion
>>>
>>> Bonnie MacKellar
>>>
>>> On Wed, Sep 14, 2016 at 5:58 AM, Peter Klügl <peter.klu...@averbis.com>
>>> wrote:
>>>
>>>> Hi,
>>>>
>>>>
>>>> yes, the types need to be declared before. The DECLARE statements have
>>>> been omitted in the example.
>>>>
>>>>
>>>> Ruta 2.4.0 introduced annotation expressions. Before that, annotations
>>>> have only ben e referenced by type expressons. Ruta tries to guess which
>>>> annotation is meant by the given type expression using the context.
>>>>
>>>> So, if you "assign" a type to a feature that expects one annotation,
>>>> then the first annotation of that type within the matching window of the
>>>> rule element is selected. In that example, this is the first annotation
>>>> of the type Employee  within the currently matched sentence annotation.
>>>>
>>>> Here are some more (with declare, but without the Indicator annotation)
>>>> examples how to assign feature values for the trivial text "Peter works
>>>> for Frank.":
>>>>
>>>>
>>>> DECLARE Employer, Employee;
>>>> DECLARE EmplRelation (Annotation employee, Annotation employer);
>>>> "Peter"-> Employee;
>>>> "Frank"-> Employer;
>>>>
>>>> // CREATE
>>>> Document{-> CREATE(EmplRelation, "employee" = Employee, "employer" =
>>>> Employer)};
>>>>
>>>> // GATHER
>>>> Employee # Employer{-> GATHER(EmplRelation, 1, 3, "employee" = 1,
>>>> "employer" = 3)};
>>>>
>>>> // implicit actions
>>>> (Employee # Employer){-> EmplRelation,
>>>>     EmplRelation.employee = Employee,
>>>>     EmplRelation.employer = Employer};
>>>>
>>>> // annotation variables
>>>> ANNOTATION e1,e2;
>>>> (Employee{-> ASSIGN(e1, Employee)} # Employer{-> ASSIGN(e2, Employer)})
>>>>     {-> CREATE(EmplRelation, "employee" = e1, "employer" = e2)};
>>>>
>>>> // labels
>>>> (e1:Employee # e2:Employer)
>>>>     {-> CREATE(EmplRelation, "employee" = e1, "employer" = e2)};
>>>>
>>>> Best,
>>>>
>>>>
>>>> Peter
>>>>
>>>> Am 14.09.2016 um 01:20 schrieb Bonnie MacKellar:
>>>>> Hi,
>>>>>
>>>>> I need to create annotations with features, but I am struggling to
>>>>> understand the one example given in the manual
>>>>>
>>>>> DECLARE Annotation EmplRelation
>>>>>     (Employee employeeRef, Employer employerRef);
>>>>> Sentence{CONTAINS(EmploymentIndicator) -> CREATE(EmplRelation,
>>>>>     "employeeRef" = Employee, "employerRef" = Employer)};
>>>>>
>>>>> I understand that this declares an Annotation with two features, one of
>>>>> type Employee and one of type Employer. I am assuming these are
>>>> Annotations
>>>>> that have also been declared in the script? The second part really
>>>> baffles
>>>>> me. The way I am reading this, if a sentence contains an annotation of
>>>> type
>>>>> EmploymentIndicator, then create a EmplRelation annotation - and assign
>>>> the
>>>>> type Employer to feature employeeRef????  That makes no sense. It looks
>>>>> like this assigns a type to a feature. I would have assumed we would
>> want
>>>>> some text as the value, no? Could anyone explain this in more detail?
>>>>>
>>>>> thanks,
>>>>> Bonnie MacKellar
>>>>>
>>

Reply via email to