Drools retraction is causing rule not to fire - rules

I'm coming across some weird behavior in Drools 4.0.7, but maybe it's just cause I don't understand I how Drools works. Assume, there's a class "A" that has a property called "property".
As facts, I have the following list of A's:
A1, property = 123
A2, property = 345
A3, property = 123
I have two rules as follows:
rule "Rule 1 - Remove all A's that have property set to 123"
salience 1000
lock-on-active true
when
$listOfAs : ArrayList collect(A( property == "123" ))
then
for (Object a: $listOfAs ) {
retract (a)
}
end
rule "Rule 2 - Do stuff with remaining A's"
salience 900
lock-on-active true
when
$listOfAs : ArrayList collect(A())
then
...
end
My understanding is "Rule 1" will remove the facts of class A that have property to 123. When it gets to "Rule 2", shouldn't the "listOfAs" only have that one A that remains (i.e. the one where property is set to "345"). What I'm noticing is that "Rule 2" just doesn't execute at all even though I'm assuming there is still one "A" object that hasn't been retracted. If I comment out the "retract" it executes "Rule 2" fine.
Am I missing something about these rules work?
Thanks.
Justin

I suspect that the problem here is the use of 'lock-on-active'. Given that the first rule has activated, it prevents the other rule from also activating.
According to the docs lock-on-active is:
"A Boolean value. "true" inhibits additional activations of all rules with this flag set within the same ruleflow or agenda group."

Related

ForEach<Array<Unit>, Int, Text>: the ID 1 occurs multiple times within the collection, this will give undefined results

I'm making a HTTP request to a REST API I created which contains two tables in the DBMS, the main table is called Levels looks like this
Levels:
leve_id: 1
level: "Level 1"
I have a child table called Units that looks like this
Units:
primary_id: 1
unit: "Unit 1"
unit_id: 1 ,foreign key to level_id
I have inserted "unit 1" and "unit 2" to this table and they both have the unit_id: equal to 1 because I want them in Level 1.
Now, the problem is when I'm trying to use a forEach loop in swiftUI to show the units.
struct UnitView: View {
#StateObject var unitVm = UnitViewModel()
var body: some View {
List(unitVm.units, id:\.idUnit){ unit in
Text(unit.unit)
}
}
}
It gives me an error of "ID 1 occurs multiple times"
Which is understandable since the foreign keys aren't unique,
could anyone point me in the right direction to show multiple units with the same id in a particular level?
It's a bit unclear what data you're working with, exactly, in terms of the UnitViewModel, but I'm guessing that it's a direct translation of the Units table, ie with four fields corresponding to: primary_id, unit, unit_id, and level_id.
For the purposes of the swiftUI List, it just needs each item to be uniquely identifiable (eg when you say scrollTo(someItemID)), so you should just supply it the path to your primary_id (which I assume is unique for the whole table) and all should work well. It won't care about the duplicates in idUnit, at that point.

MDX error trying to compare one hierarchy level to another one

I have an MDX issue that I really don't understand with a 5 level hierarchy "SEGMENTATION" : AFFAIRE/NIVEAU 1/ NIVEAU 2/NIVEAU 3/NIVEAU 4
I want to compare "NIVEAU 1" sub-levels weight to "Niveau 1".
For instance, I want to know for each 'NIVEAU 3' members its contributions part for its "NIVEAU 1".
I've tried a bunch of things, but nothing works properly. I don't get the trick and is stucked to :
WITH MEMBER [Measures].[TEST] AS'
iif(ISEMPTY(([Segmentation].[Niveau1], [Measures].[Total])) OR ([Segmentation].[Niveau1],[Measures].[Total]) = 0
, NULL
,[Measures].[Total] / ([Segmentation].[Niveau1], [Measures].[Total])
)'
SELECT NON EMPTY { [Measures].[TEST],[Measures].[Total]} ON COLUMNS
, NON EMPTY { [Segmentation].[Niveau2]}
ON ROWS FROM ( SELECT ( { [Segmentation].[Niveau1].&[8589934592]&[1|DESC111] } ) ON COLUMNS FROM [CUBE]) // Only one "Niveau 1" focus
And I get :
<Niveau 2> TEST Total
SF - C... #Error 25143658
SF - M... #Error 1638913,5
ZZZ ... #Error 90468628
#Error : The EqualTo function expects a string or numeric expression for argument 1. A tuple set expression was used.
The expected result is :
<Niveau 2> TEST Total
SF - C... 21,44% 25143658
SF - M... 1,40% 1638913,5
ZZZ ... 77,16% 90468628
21,4% = 25143658/(25143658+1638913,5+90468628)
What's wrong with my MDX?
Is there a mistake among the dimension or hierarchy set up?
Tuples are written as comma separated lists of members. What you have is a dimension.
Try
[Segmentation].CurrentMember.Parent
Instead of
[Segmentation].[Niveau1]
On your measure definition.
[EDIT] As mentioned in a comment, the goal is a solution that works on all levels. The solution is to use
Ancestor( [Segmentation].CurrentMember, [Segmentation].[Niveau1] )
in the Tuple used in the custom measure definition.
Thanks to nsousa, I'm now using :
WITH MEMBER [Measures].[Total Niveau1] AS'
iif([Segmentation].CURRENTMEMBER.level.ordinal>=2
,(Ancestor([Segmentation].CurrentMember,[Segmentation].[Niveau1] ),[Measures].[Total])
,([Segmentation].CURRENTMEMBER, [Measures].[Total])
)
'
MEMBER [Measures].[TEST] AS'
DIVIDE([Measures].[Societe],[Measures].[Total Niveau1])
',FORMAT_STRING = 'Percent'
SELECT NON EMPTY { [Measures].[TEST],[Measures].[Societe],[Measures].[Total]} ON COLUMNS
, NON EMPTY { [Segmentation].[Niveau3]}
ON ROWS FROM [CUBE]

ArangoDB - How to find nodes not related to a specific one?

For clarity purpose, step names are used as identifiers
I have the following Directed Acyclic Graph (DAG):
What I'm trying to do is select a node, and find all the other nodes that are not connected directly to the selected one, only in an outbound direction.
For example: if I select "root step", my query should only return "test step 3", since it is the only one not connected directly to "root step".
However, if I select "test step 2", it should only return "test step 3", and not "test step", because "test step* is at the same level that "test step 2" is.
For now, here is how I do:
I store, in every "step", the list of parents it has as an array. (test step has ["root step"], etc.)
My query is as follows ( for test step 2 as an example ):
FOR v, e IN 0..10 OUTBOUND "steps/test step 2" steps_relations
FILTER e._from != "steps/test step 2"
FILTER e._to != "steps/test step 2"
FILTER v._id != "steps/test step 2"
FILTER ["root step"] NONE IN v.parents
RETURN {id: v._key, name: v.name }
For now it returns an empty result instead of the expected ("test step 3"). Any help is greatly appreciated
I have finally managed to fix this. Here is how I did it:
first, I added two fields to each one of my "steps" document:
root: equals true when it is the root of the tree (like "root step"). Otherwise it simply references the internal ID of the root step
depth: equals to 0 for the root step, but is incremented. When I add a step to another, the new step's depth equals (parent + 1) ONLY if the result is bigger than the one actually stored.
Once I have this, my query looks as follows:
Situation: I want to list all the steps that can be linked to "test step 2"
FOR step, relation IN 0..10 ANY "steps/root step" steps_relations
FILTER step.depth > 1 /* THE DEPTH OF test step 2 WICH IS 1 */
FILTER relation._from != "steps/test step 2"
RETURN item
This returns successfully "test step 3"
You should rather use the min attribute to suppress edges directly connected:
FOR v, e IN 2..10 OUTBOUND "steps/test step 2" steps_relations
RETURN {id: v._key, name: v.name }
this way you will only get paths longer than one edge-hop, and the vertices from 2 onwards.

QComboBox - Select no entry

I have a QComboBox on my ui and set the model like this:
QStringListModel* model = new QStringListModel;
QStringList stringlist;
stringlist << "Test1" << "Test2" << "Test3";
model->setStringList(stringlist);
ui->comboBox->setModel(model);
Now I want to change the current index to be none (so that I get a blank combo box).
I already tried setting the current index to -1 with ui->comboBox->setCurrentIndex(-1);, but that results to an index aout of range exeption in qlist:
ASSERT failure in QList<T>::operator[]: "index out of range", file F:/Qt/5.4/mingw491_32/include/QtCore/qlist.h, line 486
Regular (not editable) QComboBox don't allow a state where "no item" is selected. The selection has to be valid all the time.
You will have to add an empty string item in first position, and you may want to check this topic to make this dummy item not selectable: https://stackoverflow.com/a/7633081/3336423
Edit: Actually, it looks like it's perfectly possible to set the selection to -1 for any combobox (editable or not). So there is no need to add an empty item as proposed above.

I am having trouble adding elements to a referenced vector of a map

EDIT: Forgot to mention that my programming language is C++, and my IDE is Qt Creator.
I don't understand why I am having trouble adding elements to a referenced vector of a map (i.e. sometimes it works and sometimes it fails).
For example:
class C_html4_tags {
public:
C_html4_tags();
//.......
typedef std::vector<S_html_attr_value> TYPE_attr_values;
//.....
};
//...
C_html4_tags::C_html4_tags() {
//........
map<S_browser, TYPE_attr_values> attr_supported_attr_values_map;
S_browser dummy_browser; //a fake browser key for referencing a fully Html 4.01-compliant supported attr values list
dummy_browser.name = "Dummy";
//.....
TYPE_attr_values& attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
//......
**attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];**
//...
**attr_supported_attr_values.clear();
attr_supported_attr_values_map.clear();**
//......
**attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];**
//...
**attr_supported_attr_values.clear();
attr_supported_attr_values_map.clear();**
}
I do the bolded lines multiple times with a bunch of different attributes, with very little difference between them, without a problem until reaching this one attribute (a_tabindex_attr), in which the IDE doesn't report anything wrong when running it normally (except "The program has unexpectedly finished." However, when debugging it, it now reports:
Signal received
The inferior stopped because it received a signal from the Operating
System.
Signal name : SIGSEGV Signal meaning : Segmentation fault
And the backtrace points to the attribute I mentioned above, on the line of code which does this:
attr_supported_attr_values.clear();
Now, after adding some debugging cout lines to the code, I learned that what's happening is, for some reason, even after doing:
attr_supported_attr_values.push_back(attr_value);
the vector object which is the returned mapped value of:
attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
is not actually being changed when I push_back an S_html_attr_value object to the referenced vector. Now, I don't why that is, since I do pretty much the exact same thing in a bunch of other attributes' code before this one, without any problem, but for some reason now, on this one, it ain't adding the object to attr_supported_attr_values (which is a reference to the returned mapped value of 'dummy_browser'). And I know this for a fact, because I outputted the size of the internal mapped value object of the map (using an iterator for the map), and it was 0 after the call to push_back(). However, what is even more odd is, I ALSO outputted attr_supported_attr_values.size() after the call to push_back(), and that was 1! Now how could that be since they're both supposed to be the same object??
Note:
The full code of what I'm talking about is below (or at least the attribute code, minus the debugging statements...):
//a_tabindex_attr:
attr_desc = "Specifies the position of an <a> element in the\n"
"tabbing order for the current document.\n"
"The tabbing order defines the order in which\n"
"elements will receive focus when navigated by\n"
"the user via the keyboard. The tabbing order\n"
"may include elements nested within other elements.\n"
"Elements that may receive focus based on tabindex\n"
"adhere to the following rules:\n\n"
"1. Those elements that support this attribute and\n"
"assign a positive value to it are navigated first.\n"
"Navigation proceeds from the element with the\n"
"lowest tabindex value to the element with the\n"
"highest value. Values need not be sequential\n"
"nor must they begin with any particular value.\n"
"Elements that have identical tabindex values\n"
"should be navigated in the order they appear\n"
"in the character stream.\n"
"2. Those elements that do not support this\n"
"attribute or support it and assign it a value\n"
"of \"0\" are navigated next. These elements are\n"
"navigated in the order they appear in the\n"
"character stream.\n"
"3. Elements that are disabled do not participate\n"
"in the tabbing order.";
attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
attr_value_desc = "A number you specify for the tab index/order.\n"
"It must be a value between 0 and 32767.";
attr_value_content = "<i>number</i>";
attr_value = C_html4_attributes_obj.getAttrValue(attr_value_desc, attr_value_content,
attr_value_supported_browsers,
attr_value_required, attr_value_deprecated,
attr_value_notes, attr_value_tips);
attr_value.is_relative = true;
attr_supported_attr_values.push_back(attr_value);
try {
N_init_class_members::initAttr(C_html4_attributes::attr_tabindex, a_tabindex_attr, attr_desc,
attr_supported_browsers, attr_supported_attr_values_map, attr_required,
attr_deprecated, attr_notes, attr_tips);
}
catch (const char* exc) {
string exc_str = "Error! Call to N_init_class_members::initAttr() from\n"
"constructor of C_html4_tags class. That function\n"
"reported the following exception:\n\n";
exc_str += exc;
throw (exc_str.c_str()); //re-throw exception
}
a_tabindex_attr.is_standard_attr = true;
a_tabindex_attr.is_optional_attr = true;
//cleanup from attribute operations so we can begin working on the next attribute:
C_html4_attributes_obj.clear(); //wipes the slate clean for all the supported attributes' properties except content
attr_desc.clear();
attr_supported_attr_values.clear();
attr_supported_attr_values_map.clear();
attr_value_desc.clear();
attr_value_content.clear();

Resources