I was playing around with variable assignments in Ruta when I stumbled across this script with a result I don't really understand:
DECLARE testType (Annotation ann, BOOLEAN bool1, BOOLEAN bool2);
ANNOTATION a1, a2;
BOOLEAN b1,b2;
d:Document{-> a1=d};
Document{-> b1 = a1==a2};
Document{-> b2 = a1!=a2};
"demo"{->CREATE(testType, "bool1"=b1, "bool2"=b2, "ann"=a2)};
I used the Ruta Workbench 2.8.0 with Eclipse 2019-09 to interpret a simple text file which includes the word "demo". Since I couldn't find any specifics on the VariableAssignmentExpresssion in the Ruta Guide and no exception was throw I expect this to be valid Ruta code. The output is shown in this screenshot of the Annotation Browser. As you can see, both boolean features are false and the "ann" feature is not present at all. What I've expected instead is
bool2 to be true,
ann to be null (and listed as such).
Can someone point me to what I'm missing here? Or is this a bug?
Related
I am creating rules using Ruta as implemented in CLAMP ( https://clamp.uth.edu/ ). As one of the steps, I would like to identify all sentences that contain Temperature annotations.
So I would like to be able to specify attribute values for the annotation in CONTAINS function like this:
Sentence{CONTAINS(ClampNameEntityUIMA{"semanticTag", "Temperature"})
-> CREATE( ClampNameEntityUIMA , "semanticTag" = "TemperatureSentence")};
The statement that works is:
Sentence{CONTAINS(ClampNameEntityUIMA)
-> CREATE( ClampNameEntityUIMA , "semanticTag" = "TemperatureSentence")};
but that marks all sentences regardless of the contained annotation's feature value.
CLAMP does not allow creating types on the fly so I cannot declare a new type as a placeholder for annotations that meet conditions. So I have to use only the existing type - ClampNameEntityUIMA - and I can only check the feature values to differentiate the annotation classes.
Is there a way to include additional conditions in CONTAINS function? Or can I manipulate annotations without having to declare a new type?
The CONTAINS condition does not support what you need. If more complex condition are required as in your example, you need to switch to inlined rules as condition. A rule like the following could solve your problem:
Sentence{-> CREATE(ClampNameEntityUIMA, "semanticTag" = "TemperatureSentence")}
<- {e:ClampNameEntityUIMA{e.semanticTag == "Temperature"};};
DISCLAIMER: I am a developer of UIMA Ruta
I've run into a problem using Set.contains in F# running inside Unity.
(Unity does not officially support F#, but they do support including .DLLs as Plugins to provide externally-compiled code which Scripts can access. This project includes the FSharp.Core.DLL inside Unity and works well. This is the first gotcha I've run into using this approach.)
The problem is that the built-in F# structural equality support seems to fail when running under Unity under certain conditions. The identical code succeeds when run as a console application, outside Unity.
I have a sample project on github which contains a Visual Studio solution with all the pieces necessary to demonstrate the inconsistency: https://github.com/anticrisis/fsharp-unity-test
It's quite simple: when a Set is built containing a struct type, either an F# 4.1 [<Struct>] record, or an old style struct/vals/end type, Set.contains returns true when it shouldn't:
[<Struct>]
type V3 = {x: int; y: int; z: int}
let testSet0 = Set.empty<V3>
let testSet1 = testSet0.Add({x = 123; y = 123; z = 123})
// fails under Unity
if testSet1.Contains {x = 0; y = 0; z = 1}
then "FAIL test: testSet1"
else "SUCCESS test: testSet1"
This Contains call should obviously return false, and it does outside of Unity. However, it returns true when run inside Unity.
Luckily, there are two main workarounds available: avoid Set.contains and use Set.exists instead. Or, use a tuple instead of a struct. Both approaches seem to avoid whatever inconsistency causes F# to fail within Unity.
The repository includes a bit more information in the README and more tests to demonstrate this problem.
This unexpected behavior is caused by a bug in the Windows version of 64-bit Mono: https://github.com/mono/mono/issues/7177.
For a workaround, consider implementing [<CustomComparison; CustomEquality>] on any [<Struct>] types you define.
What I would like to achive is an Xtext grammar which is able to distinguish between negative numerics of type int and float.
As I faced the same term problems as eclipse community, I followed their recommendation, to write both as datatype rules:
SignedInteger returns ecore::EIntegerObject:
'-'? INT;
SignedFloat returns ecore::EFloatObject:
'-'? INT* '.' INT+;
But the above will give me the following error (and finally i have the same problem by the leading minus sign):
Decision can match input such as "RULE_INT" using multiple alternatives: 1, 2
To solve this I could write both as terminal rules, but then the grammar will conflict in:
The following token definitions can never be matched because prior tokens
match the same input: RULE_INT
because both rules are hidden behinded the Xtext common terminals rule INT.
It seem like the solution for one of the problems would force a conflic with the other one. Any recommendations how to solve this?
Besides another question refering ecore datatypes: What return type would you recommend, whats the difference between EInt and EIntegerObject? (Is the second the wrapper class of the primitive type?)
I solved the problem by removing the with common terminals statement. And copied the rest (without the INT rule) i need into my own grammar. So there is no conflict any more.
But i guess that is not realy the root of the problem....
If anyone can explain what's going on here I would be very thankful.
(I hope that way does not bring later problems with it)
Let's say I maybe want to import a component based on some condition, let's say a boolean variable. I've tried this, but it gives me an error message. For instance, consider the following code:
model myNewModel
parameter Boolean use_Something;
myLibrary.myComponent component[if use_Something then 1 else 0];
// In other words (pseudo):
// if use_Something then 'Import The Component' else 'Do Nothing At All';
end myNewModel;
This is, intuitively, a safe statement, and as long as the boolean variable is true, it'll work as intended. For some units, for instance the fluidports of the Modelica Standard Library, it also works with the [0] size. But as soon as I turn the variable to false, I encounter errors regarding the fact that many components are not compatible with "zero size". I've had this problem, for instance, with the MassFlowSources in the Modelica Standard Library. Is there a smooth/elegant way to work around this? Thanks in advance!
You can use conditional components in Modelica.
model myNewModel
parameter Boolean use_Something;
myLibrary.myComponent component if use_Something;
end myNewModel;
This component may then only be used in connect-statements. If the condition is false, these connections are ignored by the tool.
Using Enterprise Architect (version 7.5), I'm trying to refine the code generation for C#. To make an attribute with an initial value that is a string generate properly, the only way I've been successful is with the code below. Does anyone know if a simpler way to do this? It currently seems a little bloated.
%if attType=="string" and attInitial!=""%
= "
%elseIf attInitial!=""%
=
%endIf%
%attInitial ? value%
%if attType=="string" and attInitial!=""%
"
%endIf%
%if attInitial!=""%
=
%attInitial%
%endIf%
EA's attInitial corresponds to Property.default in UML.
default : String [0..1]
A string that is evaluated to give a default value for the attribute when an object of the owning class is instantiated. -- UML 2.2 infrastructure 10.2.5, emphasis added
So according to UML, if the type of the property is string, then the value attInitial should be an expression which evaluates to a string, not the content of a string literal.
If you do want it to be a non-UML-complient extension string literal value, you have to write something a bit more complicated that what you have done above to handle escaping.