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?
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 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 > >>> > >> > >