Flink CEP: FollowedBy pattern: same event loops the pattern multiple times - apache-flink

I am new to Flink CEP and have been playing around with the patterns for better understanding of them.
I have a simple case of a "begin" & a followedBy".
I notice that in the case of followedBy, the same event is looping through it multiple times.
What am I missing here?
Pattern match_win = Pattern.begin("first").where(new SimpleCondition() {
public boolean filter(HitDTO hitDTO) throws Exception {
boolean result = false;
if (hitDTO.getHitScore() == 4)
{
System.out.println("First:" + hitDTO + ": " + hitDTO.getHitScore());
result = true;
}
return result;
}
}).followedBy("next").where(new SimpleCondition<HitDTO>(){
public boolean filter(HitDTO hitDTO) throws Exception
{
boolean result = false;
if (hitDTO.getHitScore() == 6)
{
System.out.println("Next:" + hitDTO+ ": " + hitDTO.getHitScore());
result = true;
}
return result;
}
});
I am passing in 4,4,6
Parallelism is set at 1.
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment().setParallelism(1);
However, this is what I see in the logs for the printout within the patterns, where 6 is looping 4 times when it was passed in only once.
First:com.rs.dto.HitDTO#17619295: 4
First:com.rs.dto.HitDTO#c108f70: 4
Next:com.rs.dto.HitDTO#5d13aab8: 6
Next:com.rs.dto.HitDTO#5d13aab8: 6
Next:com.rs.dto.HitDTO#5d13aab8: 6
Next:com.rs.dto.HitDTO#5d13aab8: 6
Just wondering why the same event is looping through multiple times but the outcome is correct.
Thanks for your answer.

It is normal that the process of attempting to match a pattern to an input sequence will involve multiple evaluations of various components of the pattern. That's how pattern matching works: the pattern is compiled to a finite state machine, and all possible paths the input might take through that FSM are considered, looking for paths that lead to the terminal, matching state. If you're not careful in how you define your pattern, this can lead to a combinatorial explosion of effort.

Related

QS5026 - The variable cannot be reassigned here

I'm following tutorial from the official Microsoft learning page (https://learn.microsoft.com/en-us/azure/quantum/tutorial-qdk-explore-entanglement?pivots=ide-azure-portal) about quantum entanglement.
Basically, I copied an example posted there and I am getting error:
QS5026 The variable "numOnesQ1" cannot be reassigned here. In conditional blocks that depend on a measurement result, the target QuantinuumProcessor only supports reassigning variables that were declared within the block.
I understand what it says but it's just a copy from the official Microsoft tutorial. Am I missing something simple like imports, wrong settings? If not, how can I in other way set variables declared outside conditional blocks that depend on a measurement result?
Here is my code:
namespace Quantum.QuantumDream {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
operation GetRandomResult() : Result {
use q = Qubit();
H(q);
return M(q);
}
#EntryPoint()
operation TestBellState(count : Int, initial : Result) : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones':
if resultQ1 == One {
set numOnesQ1 += 1;
}
if resultQ2 == One {
set numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Return number of |0> states, number of |1> states
Message("q1:Zero, One q2:Zero, One");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
}
This tutorial code is only supposed to run on a local simulator (using %simulate magic commands in a Jupyter Notebook). From the error message, it looks like you've tried to run it on one of Quantinuum targets, which have some limitations on the kinds of things you can do in the code. To run equivalent code on Quantinuum, you'd need to define an operation for just the body of the loop (preparing a state and measuring it) and run it as a job - the cloud targets will take care of the loop themselves, running your code multiple times and returning to you a histogram of the results. For an example, you can see the QRNG sample in the samples gallery in Azure Portal.

Java 8: iterating across some Map elements

I'm having a validate method that return a boolean.
I'm invoking this method (Java 7) as follow:
boolean isValid = true;
for (String key: aMap.keySet()) {
isValid &= validate(key, aMap.get(key));
if(!isValid) {
break;
}
}
I would like to rewrite this code in Java 8.
Java 8 allows iterating across a Map using:
aMap.forEach((k,v) -> validate(k, v));
But this won't work:
aMap.forEach((k,v) -> isValid &= validate(k, v));
Question
How can I rewrite the the Java 7 code into Java 8 to achieve the same result?
Note
Raised a similar question here (but this time, for the iteration to continue through all the Map elements)
boolean isValid = aMap.keySet()
.stream()
.allMatch(key -> validate(key, paramRow.getRowMap().get(colName))
As a side note, what does paramRow.getRowMap().get(colName) do? And where do you get colName? May be you don't have to recompute this for every single key

ProcessCmdKey - Keys.Tab == Keys.D9? [duplicate]

I have the following code, meant to prevent user from writing new-lines in a memo text editor:
private void m_commentMemoEdit_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData.HasFlag(Keys.Enter))
{
e.SuppressKeyPress = true;
}
}
It really does prevent Enter from being inserted, but strangely enough it prevents other keys from being inserted as well. So far we've discovered that the keys: 'O', 'M', '/' and '-' are also being "caught".
Update: The following code does what I need:
private void m_commentMemoEdit_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyValue == (int)Keys.Return)
{
e.SuppressKeyPress = true;
}
}
But I still don't understand the former code does not work and this does.
I've looked at the System.Windows.Forms.Keys enum but didn't find any clues (though I must say this is one weirdly constructed enum). Can anyone explain why is this happening?
HasFlags() is inherited from Enum.HasFlags(). It is useful on enums that are declared with the [Flags] attribute. It uses the & operator to do a test on bit values. Trouble is, Keys.Enter is not a flag value. Its value is 0x0d, 3 bits are set. So any key that has a value with bits 0, 2 or 3 turned on is going to return true. Like Keys.O, it has value 0x4f. 0x4f & 0x0d = 0x0d so HasFlags() returns true.
You should only use it with Keys values that actually represent flag values. They are Keys.Alt, Keys.Control and Keys.Shift. Note that these are modifier keys. So you can use HasFlags to see the difference between, say, F and Ctrl+F.
To detect Keys.Enter you should do a simple comparison. As you found out. Note that your if() statement is also true for Alt+Enter, etcetera, this might not be what you want. Instead use
if (e.KeyData == Keys.Return) e.SuppressKeyPress = true;
Which suppresses the Enter key only if none of the modifier keys are pressed.
I suspect it has something to do with the underlying values of the System.Windows.Forms.Keys enum being mapped directly to the keyboard codes, which are not always mutually exclusive. The documentation says that you should not use any kind of bitwise operation on them, and gives an example of why not (Beware the FlagsAttribute on the enum!).
MSDN also says that the HasFlag function returns the result of this: thisInstance And flag = flag, so you could potentially set a breakpoint and look at the actual binary codes coming in and see if that operation would give you a true for the set of keys you listed.
In the end, your updated code is the right way to do what you want to do.
HasFlag is for Flags - which means if a bit is set or not
the keyvalue is an ordinal value, so completely different from flags
use the comparison operator and everything should be fine.
some enum fields are defined like flags, e.g.
enum SomeFlag
{
BitOne = 1,
BitTwo = 2,
Bitthree = 4
};
here it makes sense to use "HasFlag"

Aggregation and filtering through the consumer template

This is more a general, whats the best practice question...
I have a few processes where the consumer template has been used to read a directory (or a MQ queue) for whatever is available and then stop itself, the entire route-set it calls is created programmatically based of a few parameters
So using the consumer template method below... Is there a way to assign
A filter operation programmatically (ie, if i want to filter out certain files from the below, its easy if its through a standard route... (through .filter) but at the moment, i have no predefined beans, so adding #filter=filter to the EIP is not really an option).
An aggregation function from inside my while loop. (while still using the template).
#Override
public void process(Exchange exchange) throws Exception {
getConsumer().start();
int exchangeCount = 0;
while (true) {
String consumerEp = "file:d://directory?delete=true&sendEmptyMessageWhenIdle=true&idempotent=false";
Exchange fileExchange = getConsumer().receive(consumerEp);
if (fileExchange == null || fileExchange.getIn()==null || fileExchange.getIn().getHeader(CAMEL_FILE_NAME)==null) {
break;
}
exchangeCount++;
Boolean batchStatus = (Boolean) fileExchange.getProperty(PROP_CAMEL_BATCH_COMPLETE);
LOG.info("---PROCESSING : " + fileExchange.getIn().getHeader(CAMEL_FILE_NAME));
getProducer().send("direct:some-other-process", fileExchange);
//Get the CamelBatchComplete Property to establish the end of the batch, and not cycle through twice.
if(batchStatus!=null && batchStatus==true){
break;
}
}
// Stop the consumer service
getConsumer().stop();
LOG.info("End Group Operation : Total Exchanges=" + exchangeCount);
}

Loops' iterating in ANTLR

I'm trying to make a Pascal interpreter using ANTLR and currently have some troubles with processing loops while walking the AST tree.
For example for loop is parsed as:
parametricLoop
: FOR IDENTIFIER ASSIGN start = integerExpression TO end = integerExpression DO
statement
-> ^( PARAMETRIC_LOOP IDENTIFIER $start $end statement )
;
(variant with DOWNTO is ignored).
In what way can I make walker to repeat the loop's execution so much times as needed? I know that I should use input.Mark() and input.Rewind() for that. But exactly where should they be put? My current wrong variant looks so (target language is C#):
parametricLoop
:
^(
PARAMETRIC_LOOP
IDENTIFIER
start = integerExpression
{
Variable parameter = Members.variable($IDENTIFIER.text);
parameter.value = $start.result;
}
end = integerExpression
{
int end_value = $end.result;
if ((int)parameter.value > end_value) goto EndLoop;
parametric_loop_start = input.Mark();
}
statement
{
parameter.value = (int)parameter.value + 1;
if ((int)parameter.value <= end_value)
input.Rewind(parametric_loop_start);
)
{
EndLoop: ;
}
;
(Hope everything is understandable). The condition of repeating should be checked before the statement's first execution.
I tried to play with placing Mark and Rewind in different code blocks including #init and #after, and even put trailing goto to loops head, but each time loop either iterated one time or threw exceptions like Unexpected token met, for example ':=' (assignement). I have no idea, how to make that work properly and can't find any working example. Can anybody suggest a solution of this problem?
I haven't used ANTLR, but it seems to me that you are trying to execute the program while you're parsing it, but that's not really what parsers are designed for (simple arithmetic expressions can be executed during parsing, but as you have discovered, loops are problematic). I strongly suggest that you use the parsing only to construct the AST. So the parser code for parametricLoop should only construct a tree node that represents the loop, with child nodes representing the variables, conditions and body. Afterwards, in a separate, regular C# class (to which you provide the AST generated by the parser), you execute the code by traversing the tree in some manner, and then you have complete freedom to jump back and forth between the nodes in order to simulate the loop execution.
I work with ANTLR 3.4 and I found a solution which works with Class CommonTreeNodeStream.
Basically I splitted off new instances of my tree parser, which in turn analyzed all subtrees. My sample code defines a while-loop:
tree grammar Interpreter;
...
#members
{
...
private Interpreter (CommonTree node, Map<String, Integer> symbolTable)
{
this (new CommonTreeNodeStream (node));
...
}
...
}
...
stmt : ...
| ^(WHILE c=. s1=.) // ^(WHILE cond stmt)
{
for (;;)
{
Interpreter condition = new Interpreter (c, this.symbolTable);
boolean result = condition.cond ();
if (! result)
break;
Interpreter statement = new Interpreter (s1, this.symbolTable);
statement.stmt ();
}
}
...
cond returns [boolean result]
: ^(LT e1=expr e2=expr) {$result = ($e1.value < $e2.value);}
| ...
Just solved a similar problem, several points:
Seems you need to use BufferedTreeNodeStream instead of CommonTreeNodeStream, CommonTreeNodeStream never works for me (struggled long time to find out)
Use seek seems to be more clear to me
Here's my code for a list command, pretty sure yours can be easily changed to this style:
list returns [Object r]
: ^(LIST ID
{int e_index = input.Index;}
exp=.
{int s_index = input.Index;}
statements=.
)
{
int next = input.Index;
input.Seek(e_index);
object list = expression();
foreach(object o in (IEnumerable<object>)list)
{
model[$ID.Text] = o;
input.Seek(s_index);
$r += optional_block().ToString();
}
input.Seek(next);
}

Resources