when rv meets cep (rv 2016 tutorial)
TRANSCRIPT
When RV Meets CEP...When RV Meets CEP...
A NEW TUTORIAL BY SYLVAIN HALLÉ
RUNTIMEVERIFICATION
COMPLEX EVENTPROCESSING
CRSNGNSERC
(C) 2016 LABORATOIRE D'INFORMATIQUE FORMELLE, UNIVERSITÉ DU QUÉBEC À CHICOUTIMI, CANADA
PRESENTED AT THE INTERNATIONAL CONFERENCE ON RUNTIME VERIFICATION, MADRID, SPAIN, SEPTEMBER 27TH, 2016
WORK FUNDED BY THE CANADA RESEARCH CHAIR IN SPECIFICATION, TESTING AND VERIFICATION OF SOFTWARE SYSTEMS
Canthese
two fieldsbenefitfromeach
other?
TODAY'SPROGRAM
Part IRV vs. CEP
Part IIA Fistful of Processors
Part IIIThe Monitor Strikes Back
PART ONE
RV vs. CEP
public static voidmain(String[] args) { Map m = new HashMap(); ... Iterator i = m.iterator(); while (i.hasNext()) { ... }}
public static voidmain(String[] args) { Map m = new HashMap(); ... Iterator i = m.iterator(); while (i.hasNext()) { ... }}
HashMap.new = HashMap$1263HashMap$1263.iterator() = Iterator$32045HashMap$1263.contains(MyObject$26) = falseIterator$32045HashMap$1263.hasNext = true...
Methodcalls
Any call to next() must be immediately preceded by a call to hasNext() that returns true.
Two calls to remove() must be separated by at least one call to next().
Calls to an iterator's methods are forbidden once its parent collection has been modified by calls like put() or remove().
06bb5c mov esp, ebp | EBP=001bfbf4 | ESP=001bfbf406bb5d pop ebp | ESP=001bfbf4 [001bfbf4]=001bfc24 | EBP=001bfc24 ESP=001bfbf806bb5e push ecx | ECX=71f1a8b9 ESP=001bfbf8 | ESP=001bfbf4 [001bfbf4]=71f1a8b906bb5f ret | ESP=001bfbf4 [001bfbf4]=71f1a8b9 | ESP=001bfbf806bb60 ret | ESP=001bfbf8 [001bfbf8]=01391036 | ESP=001bfbfc06bb61 add esp, 0x20 | ESP=001bfbfc | ESP=001bfc1c EFLAGS=06bb62 cmp [ebp-0x4], 0x3e8 | [001bfc20]=000003e8 EBP=001bfc24 | EFLAGS=ZP06bb63 jnz 0x1391057 | EFLAGS=ZP |06bb64 push 0x1392144 | ESP=001bfc1c | ESP=001bfc18 [001bfc18]=01392144
Return address protectionInteger overflow detectionCall sequence profilingPointer subterfuge detectionMalicious pattern detectionEtc.
06bb5c mov esp, ebp | EBP=001bfbf4 | ESP=001bfbf406bb5d pop ebp | ESP=001bfbf4 [001bfbf4]=001bfc24 | EBP=001bfc24 ESP=001bfbf806bb5e push ecx | ECX=71f1a8b9 ESP=001bfbf8 | ESP=001bfbf4 [001bfbf4]=71f1a8b906bb5f ret | ESP=001bfbf4 [001bfbf4]=71f1a8b9 | ESP=001bfbf806bb60 ret | ESP=001bfbf8 [001bfbf8]=01391036 | ESP=001bfbfc06bb61 add esp, 0x20 | ESP=001bfbfc | ESP=001bfc1c EFLAGS=06bb62 cmp [ebp-0x4], 0x3e8 | [001bfc20]=000003e8 EBP=001bfc24 | EFLAGS=ZP06bb63 jnz 0x1391057 | EFLAGS=ZP |06bb64 push 0x1392144 | ESP=001bfc1c | ESP=001bfc18 [001bfc18]=01392144
Return address protection
"After a call instruction, the current location onthe stack cannot be the target of a MOVinstruction until the call returns."
start(vase,3,15).bid(vase,15).start(ring,5,30).endOfDay.bid(ring,32).bid(ring,33).bid(vase,18).sell(vase).
start(vase,3,15).bid(vase,15).start(ring,5,30).endOfDay.bid(ring,32).bid(ring,33).bid(vase,18).sell(vase).
Event name
start(vase,3,15).bid(vase,15).start(ring,5,30).endOfDay.bid(ring,32).bid(ring,33).bid(vase,18).sell(vase).
Parameters
start(vase,3,15).bid(vase,15).start(ring,5,30).endOfDay.bid(ring,32).bid(ring,33).bid(vase,18).sell(vase).
For a given item, any bid must be higher than the previous one.
Any bid must be higher than the minimum price.
No bid can be placed before a start event.
Server
Ajaxwebapp
Server
Ajaxwebapp
<message> <name>CartAdd</name> <CartId>123</CartId> <Items> <ItemId>42</ItemId> <ItemId>23</ItemId> </Items></message>
<message> <name>CartAddResponse</name> <CartId>123</CartId></message>
TheBeepStore
GO
Sign inor regi ster
What is this?
Login
Ask for account
Contact us
Fault parameters
Search: Your Cart
Fault parameters
Don’t check Results’s typeIn the detailed search form, sends an ItemSearch message withoutchecking that the Results element is an integer.
"Add to cart" enabled if item present in cartMakes the "Add to cart" button available for items that are already in theuser's cart.
Message schemas
Cart manipulations
Highlightsdocumentation
Disables theverification
1. The element must be an integer between 1 and 20.
2. The element is mandatory only if is present,otherwise it is forbidden.
3. The request cannot be resent if its response issuccessful.
4. must follow a successful Logi nResponse.
5. There can be at most one active cart ID per session key.
6. You cannot add the same item twice to the shopping cart.
Page
Page Resul t s
Logi n
Car t Cr eat e
???
CAM 1
CAM 1
The lock graph of a set of tasks should not contain cycles
A communication window has three phases: prep, active and cleanup
Every command must be responded by either a success or a failure
RV
untime
erification
System
System
System
Instrumentation
System
Instrumentation
System
Instrumentation
Trace
System
Instrumentation
Trace
Events
System
Instrumentation
Trace
Events
System
Instrumentation
Trace
Events
Tracevalidation
System
Instrumentation
System
Runtime monitoringInstrumentation
System
Runtime monitoringInstrumentation
System
Runtime monitoring
Overhead
Instrumentation
hasNext
next
hasNext
Option #1 Finite-State Machines
hasNext
next
hasNext
Option #1 Finite-State Machines
...and extensions
1 2 3groupStart(t)
init(p)∀p
QEA: Reger et al., TACAS 2015
groupEnd(t2)
phaseStart
4run(p)
finish(p)
t2−t < 480
A call to next must be followed by a callto hasNext
No CartCreate request can occurbefore a LoginResponse message
A received order must eventuallybe shipped
Three successive login attempts shouldtrigger an alarm
G (next → X hasNext)
¬ CartCreate U hasNext
G (receive → F ship)
G ¬(fail ∧ (X (fail ∧ X fail)))
Option #2 Linear Temporal Logic
G (∃ retAddrVal ∈ ./return-address : ( (./instruction = call) ∧ (¬ ((F( ((./instruction = mov)∧ (./output/type = general-register)) → (∃ regA ∈ ./output/name : (F (( ((./instruction = mov) ∧ (./output/type = general-register)) ∧ (./input/type = litteral) ) → (∃ regB ∈ ./output/name : ( ∃ constAddr ∈ ./input/value : (F (((./instruction = cmp ) ∧ (./output/type = regA)) → (∃ loc ∈ ./location : (F((((./instruction = mov ) ∧(./output/type = general-register)) ∧(./output/name = regA ) ) ∧((./input/name = regB ) ∧ (./input/type = ptr)))))) ))))) ))) U ((./instruction = return) ∧ (./fonction-returned = retAddrVal)) )) ))
...and extensionsLTL-FO+, Hallé et al.IEEE Trans. Serv. Comput. 2012
νZ.(∨a ∈ A
a ⊤ ∧ ∧a ∈ A
[a] Z )
Option #4 mu-calculus
(hasNext+ next)*
Option #3 Regex
class SeqMonitor extends EvrMonitor { val SeqStart, SeqDone = fact def seq name(s:String) = words(s)(2)
"start_seq" −− EVR(’id -> "EVR_SEQ_START", ’sclk -> ’S, ’msg -> ’M) 7−-> { val w = words(’M.s) val seq name = w(15).slice(1, w(15).length−2) insert (SeqStart(seq name, ’S.d)) }
"end_seq_ok" −− EVR(’id -> "EVR_SEQ_SUCCESS", ’sclk -> ’E, ’msg -> ’M) & ’SeqStart(’name, ’S) --> { if (seq name(’M.s) == ’sname.s) { replace (SeqStart)(SeqDone(’name.s, ’S.d, ’E.d, "OK")) } }
"end_seq_fail" −− EVR(’id -> "EVR_SEQ_FAILURE", ’sclk -> ’F, ’msg -> ’M) & ’SeqStart(’name, ’S) --> { if (seq name(’M.s) == ’name.s) { replace (SeqStart)(SeqDone(’name.s, ’S.d, ’F.d, "FAIL")) } }
"print" −− SeqDone(’name, ’S, ’E, ’stat) --> { updateCSV(’name.s, ’S.d, ’E.d, ’ stat .s) remove(SeqDone) }} Option #5 LogFire
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
10/2/29 APPL 1212.210/2/29 MSFT 1031.610/2/29 GOGL 341.110/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.210/4/29 APPL 1164.310/4/29 MSFT 1025.110/4/29 GOGL 345.410/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.210/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.2
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
10/2/29 APPL 1212.210/2/29 MSFT 1031.610/2/29 GOGL 341.110/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.210/4/29 APPL 1164.310/4/29 MSFT 1025.110/4/29 GOGL 345.410/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.210/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.2
Timestamp
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
10/2/29 APPL 1212.210/2/29 MSFT 1031.610/2/29 GOGL 341.110/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.210/4/29 APPL 1164.310/4/29 MSFT 1025.110/4/29 GOGL 345.410/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.210/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.2
Stock symbol
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
10/2/29 APPL 1212.210/2/29 MSFT 1031.610/2/29 GOGL 341.110/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.210/4/29 APPL 1164.310/4/29 MSFT 1025.110/4/29 GOGL 345.410/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.210/3/29 MSFT 1024.410/3/29 APPL 1179.010/3/29 GOGL 362.2
Price
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
What is the closing price of MSFT for the first five trading days?
Select all days after the 100th where MSFT closed over $50.
On every 5th day, calculate the average closing price for MSFT for the last 5 days.
What are the stocks that closed higher than MSFT for a given day?
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
What is the closing price of MSFT for the first five trading days?
Select all days after the 100th where MSFT closed over $50.
On every 5th day, calculate the average closing price for MSFT for the last 5 days.
What are the stocks that closed higher than MSFT for a given day?
Snapshot query
Landmark query
Sliding query
Join query
4948
4949
6.3132
4948
4949
6.3132
Testresult
4948
4949
6.3132
Drugprescriptions
4948
4949
6.3132
Meeting
4948
4949
6.3132
MSH|^~\&|SOURCE|383018129|PRIORITY HEALTH|382715520|2007100914484648||ORU^R01|0129938170710091448|P|2.3|PID|1|1034157|012993817||LASTNAME^FIRSTNAME||19520101|M|||1234 MAIN^^DEARBORN HEIGHT^MI^48127||||||||PID|1||94000000000^^^Priority Health||LASTNAME^FIRSTNAME||19400101|F|PD1|1|||1234567890^DOCLAST^DOCFIRST^M^^^^^NPI|OBR|1|||80061^LIPID PROFILE^CPT-4||20070911||||||||||OBX|1|NM|13457-7^LDL (CALCULATED)^LOINC|49.000|MG/DL| 0.000 - 100.000|N|||F|OBX|2|NM|2093-3^CHOLESTEROL^LOINC|138.000|MG/DL|100.000 - 200.000|N|||F|OBX|3|NM|2086-7^HDL^LOINC|24.000|MG/DL|45.000 - 150.000|L|||F|OBX|4|NM|2571-8^TRIGLYCERIDES^LOINC|324.000|
HL7HL7
Notify me when two out of three successive data points lie more than 1 standard deviation from the mean on the same side of the mean line.
Notify me when two out of three successive data points lie more than 1 standard deviation from the mean on the same side of the mean line.
Trend query
TOLL
TOLL
TollIdTollLicenseStateModel
48392$3.50QF5010KWT
TOLL
TollIdTollLicenseStateModel
48392$3.50QF5010KWT
TOLL
Compute the toll of each booth over 3-minute intervals
CE
omplex
vent
Processing
Select AVG(closingPrice)From ClosingStockPricesWhere stockSymbol = ‘MSFT’for (t = ST; t < ST+50, t+= 5) { WindowIs(ClosingStockPrices, t - 4, t);}
Select c2.*FROM ClosingStockPrices as c1, ClosingStockPrices as c2WHERE c1.stockSymbol = ‘MSFT’ and c2.stockSymbol!= ‘MSFT’ and c2.closingPrice > c1.closingPrice and c2.timestamp = c1.timestampfor (t = ST; t < ST +20 ; t++ ){ WindowIs(c1, t - 4, t); WindowIs(c2, t - 4, t);}
Two queries inthe language ofTelegraphCQ
SELECT * FROM FILTER {cnt >= 10}( (SELECT *, 1 AS cnt FROM FILTER {contains(summary,’iPod’) = 1}(webfeeds)) FOLD {, $.cnt < 10 AND DUR < 1 DAY, $.cnt + 1 AS cnt} (SELECT * FROM FILTER {contains(summary,’iPod’) = 1}(webfeeds)) )PUBLISH ipod_popularity
A query in the language of Cayuga
from inputtrace#window.length(10)select stockSymbol, timestamp, avg(closingPrice) as avg10insert into avg10trace;
from inputtrace#window.length(20)select stockSymbol, timestamp, avg(closingPrice) as avg20insert into avg20trace;
@info(name = 'query1')from avg10trace#window.length(10) join avg20trace#window.length(20)on avg10trace.timestamp == avg20trace.timestampselect avg10trace.stockSymbol as stockSymbol, avg10trace.timestamp, avg20trace.timestamp as ts2, avg10trace.avg10 as avg10, avg20trace.avg20 as avg20having avg10 > 50 or avg20 > 50insert into output;
SiddhiQL...
CEPRVevent traces
"properties"
tuple-ish
overhead
event streams
"queries"
tuples*
throughput
=When
CEPRVoutputs T/F
result cannot be reused in another property
mostly variants of FSM and logic
good for sequential patterns
not quite
When
outputs event streams
result can be reused as input of another query
mostly "extensions" of SQL
not quite
good for data manipulation
CEPRVBeyond &
CEPRVBeyond &
Both RV and CEP assume events to be "tuples":associative maps from strings to single scalar values
start(vase,3,15).bid(vase,15).start(ring,5,30).
3/10/29 MSFT 1059.23/10/29 APPL 365.43/10/29 GOGL 1120.1
HashMap.new = HashMap$1263HashMap$1263.hasNext =true
TollIdTollLicenseStateModel
48392$3.50QF5010KWT
CEPRVBeyond &
Both RV and CEP assume events to be "tuples":associative maps from strings to single scalar values
start(vase,3,15).bid(vase,15).start(ring,5,30).
3/10/29 MSFT 1059.23/10/29 APPL 365.43/10/29 GOGL 1120.1
HashMap.new = HashMap$1263HashMap$1263.hasNext =true
TollIdTollLicenseStateModel
48392$3.50QF5010KWT
And what if eventsare not tuples?
CEPRVBeyond &
Both RV and CEP assume events to be "tuples":associative maps from strings to single scalar values
start(vase,3,15).bid(vase,15).start(ring,5,30).
3/10/29 MSFT 1059.23/10/29 APPL 365.43/10/29 GOGL 1120.1
HashMap.new = HashMap$1263HashMap$1263.hasNext =true
TollIdTollLicenseStateModel
48392$3.50QF5010KWT
And what if eventsare not tuples?And what if eventsare not tuples?
We make themfit!
CEPRVBeyond &
Suppose each event is a set:
{6,5,3,9}{5,4,10}...
We can "fit" it into a tuple:
a6
a=4 ∨ b=4 ∨ c=4 ∨ d=4
c3
d9
Imposes upperbound on set size
But then 4 ∈ S becomes:
b5
CEPRVBeyond &
CEPRVBeyond &
CEPRVBeyond &
CEPRVBeyond &
Both RV and CEP rely on monolithicspecification/query languages
Everything must be writtenin that one language (FO-LTL,QEA, SiddhiQL, etc.)
The language mustaccommodate every possibleuse case
In general, no support forextensions
Part 2:A Fistful ofProcessors
Event stream query engine developedbased on the previous observationsAims at borrowing strengths from bothRV and CEP (and beyond)Key concepts: composability, modularity,extensibilityOpen source, developed in Javahttp://liflab.github.io/beepbeep-3
peeB peeB 3
EventsEvents
An event is an element e taken fromsome set E, called the event type.
No restriction on the type! In BeepBeep, events can be any Object.
Booleans Numbers
234
π
Strings
abc
Functions Sets PlotsTuples
3 8 a3 8 a
2 6 c
+⊇?
XMLdocuments
<a><a><a>
. . .
?
TracesTraces
An event trace (or event stream) is a potentiallyinfinite sequence of events of a given type:
2 0 6 34 9 . . .
Traces are symbolically denoted by:
e = e0 e1 e2 e3 ...
The set of all traces of type T is denoted as:
T*
FunctionsFunctions
A function takes 0 or more events as itsinput, and returns 1 or more events.
Functions are first-class objects; they descendfrom the class Function
1 : 1function 2 : 1
function1 : 2
function
⊇?
34
2+5i
₹
2 5
6
0 : 1function
6
ProcessorsProcessors
A processor takes 0 or more event traces asits input, and returns 0 or more event traces asits output
1 : 1 processor
2 : 1 processor
. . . . . .
ProcessorsProcessors
When a processor takes more than one inputtrace, the set of events at matching positionsin each trace is called a front.
bacd
3601
b 3
a 6
c 0
d 1
1st event
2nd
3rd
4th
. . .
. . . . . .
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
5
3
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
5
3
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
5
3
+
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
8
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
1
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
1
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
6 1
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
6 1
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
6 1
4
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
6 1
4
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
6 1
4
+
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
6
5
Synchronous processingSynchronous processing
Events are processed one front at a time.
+
Buffers collect events until a completefront can be processed.
⇒
6
Synchronous processingSynchronous processing
Makes a couple of things simpler
Don't care about what event arrivedfirst or upstream computation time"Pen and paper" calculation is identicalto the real oneOtherwise, can do a lot with simpletimeouts ⇒ contained asynchrony
Motto: Don't use asychronous processing...
Synchronous processingSynchronous processing
Makes a couple of things simpler
Don't care about what event arrivedfirst or upstream computation time"Pen and paper" calculation is identicalto the real oneOtherwise, can do a lot with simpletimeouts ⇒ contained asynchrony
Motto: Don't use asychronous processing......unless you really have to
Synchronous processingSynchronous processing
In BeepBeep, all synchronous processorsare descendents of the SingleProcessorclass
Takes care of handling input/outputbuffersCalls (abstract) method process() whenan input front is ready to be consumedProcessor only needs to produce anoutput front from this inputMakes it easy to create your own(more on that later)
A high-level event trace can be produced bycomposing ("piping") together one or moreprocessors from lower-level traces
CompositionComposition
Each processor has its own input/outputbuffers
CompositionComposition
Any output can be connected to any input, aslong as they have the same type
CompositionComposition
Any output can be connected to any input, aslong as they have the same type
CompositionComposition
Many types can occur in the same chain
Trace ManipulationFunctions/Processors
ArchitectureArchitecture
TMF/P EMF/P
Event ManipulationFunctions/Processors
Type-agnosticStateful
Type-dependentStateless
Trace ManipulationFunctions/Processors
ArchitectureArchitecture
TMF/P EMF/P
Event ManipulationFunctions/Processors
Type-agnosticStateful
Type-dependentStateless
Not clear-cut, but general design goal
ArchitectureArchitecture
BeepBeep provides only a few built-inprocessors and functions
PaletteSet of processors and functions,centered around a particularuse case
Concretely, a JAR librarydefining new Processor andFunction objects
<?
+
<? =?
−
÷ ×f Σ f
n
{
n
n
Function Cumulative Trim
ForkDecimate Group
WindowSliceFilter
Built-in processors
Built-infunctions
.n <
<
SemanticsSemantics
Let P be a processor and abc
= a1,a2,...= b1,b2,...= c1,c2,... be traces
a,b,c : P [[ n = e1,e2,...
denotes the n-th output trace of P, giventraces a, b, c as input.
f
FunctionFunction
Applies an n-ary function f toevery front of size n
"Lifts" any function into aprocessor
a,b : f [[ n = f n(ai,bi)
f
FunctionFunction
Applies an n-ary function f toevery front of size n
"Lifts" any function into aprocessor
a,b : f [[ n = f n(ai,bi)The n-th output
f
FunctionFunction
Applies an n-ary function f toevery front of size n
"Lifts" any function into aprocessor
a,b : f [[ n = f n(ai,bi)The n-th output
iThe i-th event
f
FunctionFunction
Applies an n-ary function f toevery front of size n
"Lifts" any function into aprocessor
a,b : f [[ n = f n(ai,bi)The n-th output
iThe i-th event
f+
f<0?
Pairwise sum ofevents
Is each eventnegative?
CumulativeCumulative
Applies a 2 : 1 function f toits previous value and thecurrent event
a : Σf [[ = f(x,a1), f(f(x,a1),a2), ...
+ <Sum of all
eventsHave we seen⊤ so far?
Σ fx
Σ f Σ f0 ⊥
TrimTrim
Returns the input trace,trimmed of its first n events
a : [[ = an+1, an+2, ...
n
n
TrimTrim
Returns the input trace,trimmed of its first n events
a : [[ = an+1, an+2, ...
n
n
1
f=?=? <
Σ f⊥
Does the samenumberrepeat twice ina row?
GroupGroup
Makes a set of connectedprocessors behave as a singleprocessor
GroupGroup
Makes a set of connectedprocessors behave as a singleprocessor
1
f=?=? <
Σ f⊥
ForkFork
Replicates its input on eachof its n outputs
a : Ψ [[ = a1, a2, ...n
DecimateDecimate
Outputs every n-th inputevent
a : [[ = a1, an+1, a2n+1, ...nΨ
n
FilterFilter
A n : n-1 processor; outputs the n-1 first components of afront if its last component is ⊤;otherwise, discards it
a , a , ..., a : =[[ 2k
1 n Fi {a if a =⊤
ε otherwise
ki
ni
Powerful mechanism: "anything canbe filtered" (don't care about condition)Boolean trace does not need to comefrom the same source as the inputs beingfiltered
FilterFilter
A n : n-1 processor; outputs the n-1 first components of afront if its last component is ⊤;otherwise, discards it
f<0?
Get only the negativeevents of the input
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
a : Υ =[[ P i
Powerful mechanism: "anything canbe windowed" (don't care about function)
n
{
n ai, ... ai+n : P [[*
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
a : Υ =[[ P i
Powerful mechanism: "anything canbe windowed" (don't care about function)
n
{
n ai, ... ai+n : P [[*
The last event
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1 3 4 2
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1 3 4 2
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1 3 24
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1 243
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1
2
243
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1
2
243
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1
2
243
4
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1
6
243
2
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1
6
243
23
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1
9
243
6 2
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1
9
243
6 23 2 1
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1
9
243
6 2
9
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1 243 9
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
1 43 9
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
43 91
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
43 91
4
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
43 91
4
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
43 91
43
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
43 91
7 4
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
43 91
7 41
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
43 91
8 7 4
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
43 81
8 7 4
9
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
43 81 9
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
31 8 9
WindowWindow
Returns the output of aprocessor P on a slidingwindow of width n
n
{
3
{+
Σ f0
31 8 9
The sum of all 3successive events
SliceSlice
Dispatches an event e to adistinct instance of processorP according to the value ofsome function f
{a if f(ai)=kε otherwise
iπfk[a : =[i
Pf[a : =[i U πf
k[a1,...ai : [i[ [: Pk *+
SliceSlice
Dispatches an event e to adistinct instance of processorP according to the value ofsome function f
{a if f(ai)=kε otherwise
iπfk[a : =[i
Pf[a : =[i U πf
k[a1,...ai : [i[ [: Pk *+
Multiset union
f(x) = x mod 2
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
5
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
5
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
5
U+
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
5
U+
{9}{5}
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
5
U+
{9}{5}
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
5
{9}{5}6
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
5
{9}{5}
6
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
5
{9}{5}
6
U+
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
5
{9}{6,5}
6
U+
{9}{5}
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
5
{9}{6,5}
6
{9}{5}1
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
5
{9}{6,5}
6
{9}{5}
1
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
1
{9}{6,5}
6
{9}{5}
5
U+
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
1
{9}{6,1}
6
{9}{6,5}
5
U+
{5}
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
1
{9}{6,1}
6
{9}{6,5}
5
U+
{5}
The last odd and evennumbers seen so far
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
+
Σ f0
f(x) = x mod 2
πf0[a : =[subtrace of even numbers
πf1[a : =[subtrace of odd numbers
mod 2
+
Σ f0
The sum of all oddnumbers and all evennumbers seen so far
{9}{6,6} {9}{6,5} {5}
Input/outputInput/output
0 : 1 processors can be used to produce anevent trace out of an external source (i.e.standard input, a file, etc.)
Ditto for 1 : 0 processors
a . . .b
a . . .b
WARP ZONE
PalettesPalettes
BeepBeep provides only a few built-inprocessors and functions
PaletteSet of processors and functions,centered around a particularuse case
Concretely, a JAR librarydefining new (reusable!)Processor and Functionobjects
XMLXML
Provides two new Functions
Ditto for the JSON library (using json-lif)
XML parser: converts String eventsinto XMLElement events (fromxml-lif library)XPath: evaluates an XPath expressionon an XMLElement (result is a set ofXMLElements)
SetsSets
New Functions:
New processor:
Multiset operations: add/removeelements, membership, union/intersection
→ →
Dropper
Outputs each element of amultiset as an event
GnuplotGnuplot
New Functions:
New processor:
Scatterplot: converts a set of (x,y) pairsinto a Gnuplot string producing a plot(ditto for Histogram)
→ →
Gnuplot Caller
Calls Gnuplot on a string andreturns its output (i.e. a binarystring)
TuplesTuples
New event type: tuple
New function: SELECTCreates an output tuple by combiningattributes from input tuples
Grammar extension: allow eSQL to use aSELECT statement, backward-compatible withSQL
3 8 a3 8 a
2 6 c
TuplesTuples
SELECT <tuple> FROM <processor-list>
* | <tuple-element> | <tuple-element> , <tuple>
<tuple-name> <rename> | <function-call> <rename>
<word>.<word> | <word>
<processor> <rename> | <processor> <rename> , <processor-list>
AS <eml-attribute>
<select> ::=
<tuple> ::=
<tuple-element> ::=
<tuple-name> ::=
<processor-list> ::=
<rename> ::=
FSMFSM
New processor: finite-state machine
→
→?
?T
/a/b
//status/text()
=? Walker
*
/a/b
//status/text()
=? Blocker
*
*
Guards on transitionsare arbitrary functionson events States output values
of any type (Moore machine)
Linear Temporal LogicLinear Temporal Logic
New processors for LTL temporal operatorsand first-order quantification (LTL-FO+)
Two semantics for a formula φ:
Boolean: the i-th output is the (2-valued)verdict of evaluating φ, starting at the i-thevent⇒ filter
Troolean: the i-th output is the (3-valued)verdict of evaluating φ up to the i-th event⇒ monitor
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a monitoring context, we want theoutput of processor F b to be:
ac c b
F b
"Tell me whethereventually b"
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a monitoring context, we want theoutput of processor F b to be:
ac c b
F b
"Tell me whethereventually b"
c
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a monitoring context, we want theoutput of processor F b to be:
ac c b
F b
"Tell me whethereventually b"
?
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a monitoring context, we want theoutput of processor F b to be:
ac c b
F b
"Tell me whethereventually b"
?c
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a monitoring context, we want theoutput of processor F b to be:
ac c b
F b
"Tell me whethereventually b"
? ?
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a monitoring context, we want theoutput of processor F b to be:
ac c b
F b
"Tell me whethereventually b"
? ?b
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a monitoring context, we want theoutput of processor F b to be:
ac c b
F b
"Tell me whethereventually b"
⊤ ? ?
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a monitoring context, we want theoutput of processor F b to be:
ac c b
F b
"Tell me whethereventually b"
⊤ ? ?a
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a monitoring context, we want theoutput of processor F b to be:
ac c b
F b
"Tell me whethereventually b"
⊤ ⊤ ? ?
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a filtering context, we want theoutput of processor F b to be:
ac c b
F b
"Get me all the eventswhere eventually b"
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a filtering context, we want theoutput of processor F b to be:
ac c b
F b
"Get me all the eventswhere eventually b"
c
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a filtering context, we want theoutput of processor F b to be:
ac c b
F b
"Get me all the eventswhere eventually b"
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a filtering context, we want theoutput of processor F b to be:
ac c b
F b
"Get me all the eventswhere eventually b"
c
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a filtering context, we want theoutput of processor F b to be:
ac c b
F b
"Get me all the eventswhere eventually b"
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a filtering context, we want theoutput of processor F b to be:
ac c b
F b
"Get me all the eventswhere eventually b"
b
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a filtering context, we want theoutput of processor F b to be:
ac c b
F b
"Get me all the eventswhere eventually b"
⊤ ⊤ ⊤
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a filtering context, we want theoutput of processor F b to be:
ac c b
F b
"Get me all the eventswhere eventually b"
a ⊤ ⊤ ⊤
Linear Temporal LogicLinear Temporal Logic
Consider the LTL formula F b on thetrace
In a filtering context, we want theoutput of processor F b to be:
ac c b
F b
"Get me all the eventswhere eventually b"
⊤ ⊤ ⊤
Linear Temporal LogicLinear Temporal Logic
Boolean operators are easy
X
G F
U
1
<Σ f
⊥
<
Σ f⊥
F
G
=
= =
= Σ f
?
♣
Linear Temporal LogicLinear Temporal Logic
First-order quantifiers
Processor to runon each slice
→
A→ x →
E→ x
Quantifiedvariable
(Arbitrary) domainfunction
Variable is added tothe processor's contextBoolean and Trooleanversions
Let's put it alltoghether!
i.e. a few examples ofqueries from past publications
Use BeepBeep asa library in yourprogram
→
Fork f = new Fork(2);
Use BeepBeep asa library in yourprogram
→
→
→
→
Fork f = new Fork(2);FunctionProcessor sum = new FunctionProcessor( );
f
Use BeepBeep asa library in yourprogram
→
→
→
+
→
Fork f = new Fork(2);FunctionProcessor sum = new FunctionProcessor(Addition.instance);
f
Use BeepBeep asa library in yourprogram
→
→
→
+
→
Fork f = new Fork(2);FunctionProcessor sum = new FunctionProcessor(Addition.instance);CountDecimate decimate = new CountDecimate(n);
f
n Use BeepBeep asa library in yourprogram
→
→
→
+
→→
Fork f = new Fork(2);FunctionProcessor sum = new FunctionProcessor(Addition.instance);CountDecimate decimate = new CountDecimate(n);Connector.connect(fork, LEFT, sum, LEFT)
f
n Use BeepBeep asa library in yourprogram
→
→
→
+
→
→
→
Fork f = new Fork(2);FunctionProcessor sum = new FunctionProcessor(Addition.instance);CountDecimate decimate = new CountDecimate(n);Connector.connect(fork, LEFT, sum, LEFT) .connect(fork, RIGHT, decimate, INPUT)
f
n Use BeepBeep asa library in yourprogram
→
→
→
+
→
→
→
Fork f = new Fork(2);FunctionProcessor sum = new FunctionProcessor(Addition.instance);CountDecimate decimate = new CountDecimate(n);Connector.connect(fork, LEFT, sum, LEFT) .connect(fork, RIGHT, decimate, INPUT) .connect(decimate, OUTPUT, sum, RIGHT);
f
n Use BeepBeep asa library in yourprogram
→
→
→
+
→
→
→
Fork f = new Fork(2);FunctionProcessor sum = new FunctionProcessor(Addition.instance);CountDecimate decimate = new CountDecimate(n);Connector.connect(fork, LEFT, sum, LEFT) .connect(fork, RIGHT, decimate, INPUT) .connect(decimate, OUTPUT, sum, RIGHT);Pullable p = sum.getOutputPullable(OUTPUT);while (p.hasNext() != NextStatus.NO) { Object o = p.next(); ...}
f
n Use BeepBeep asa library in yourprogram
→
→ →
^
n
→
→ →
+
→→
→
→
→
÷
→ →1 → →
+
Σ
Σ
0
0
The statistical moment of order n
→
→ →
^
n
→
→ →
+
→→
→
→
→
÷
→ →1 → →
+
Σ
Σ
0
0
The statistical moment of order n
→ →E(x)
n
As a groupprocessor
Trigger an alarm
→
→
→→
1
→ → >
Trigger an alarm when two successive events
→
→
→
1
→
→
→
→→
<?
→
→→
1
→ → >
Trigger an alarm when two successive events are more than 1
→
→
→
→
1
→ →
→
÷→
→
→
→→
<?
→
→→
1
→
→ →σ
→ >
Trigger an alarm when two successive events are more than 1 standard deviation
→
→→
→
→
1
→ →
→
-→ →
→
÷→
→
→
→→
<?
→
→→
1
→
→ →E(x)
1
→ →σ
→ >
Trigger an alarm when two successive events are more than 1 standard deviation from the mean
→
⊇?
→ → → A →→T
??...<a> <a> .../a/b
//character/id/text()
→ →
→
→
?
?T
/a/b
//status/text()
=? Walker
*
/a/b
//status/text()
=? Blocker
*
*
→→ →
/a/b
//character
→→→
A/a/b//id/text()
→T
??...<a> <a> ...
→
A/a/b//character[status=Walker]/id/text()
→ p1
→
A
→ p2
→ →→
→
/a/b
//character[status=Blocker]/id/text()
→
→→
3
→
→
→
<?
→
→
→
→
→
→→
→
f1
f2
→
→ →
→
→
→
→
/a/b
//character[id=p1]/position/x/text()
/a/b
//character[id=p2]/position/x/text()
-
|...|
<?
6
>
...
f1
/a/b
//character[id=p1]/position/x/text()
/a/b
//character[id=p2]/position/x/text()
-
|...|f2
→
→
**
*
*
Create Auction=?0
@
Last PriceDays
0:=
3@Max. Days :=Min. Price 2@:=
Days :=Days 1
+
End of Day=?
0
@
>
<?Days
Last Price
2
@:=
Bid=?
0
@
>
Min. Price<?
2
@
Last Price>?
2
@
Bid=?
0
@
>
Last Price>?
2
@
Days :=Days 1
+
End of Day=?
0
@
Max. Days
→
End of Day *1@*
→→→ →
*Sold
=?0
@
Days
Days
+ | |.÷
→→
1@+=
Sanitise=?0
@
Clean :=
Derive=?
0
@
>
∊?Clean
T??...Derive(a,b)
Clean
2@+=Clean :=
Clean
1
@
Use=?
0
@
>
∊?Clean
1
@
T * *
T
...
Fastest car in theworld
Fastest car in theworld
Slow on everytype of road
Fastest car in theworld
Slow on everytype of road
Only runs on aclosed circuit
Fastest car in theworld
Slow on everytype of road
Only runs on aclosed circuit
Works on everytype of road
Fastest car in theworld
Slow on everytype of road
Only runs on aclosed circuit
Works on everytype of road
Heavy setup required
Fastest car in theworld
Slow on everytype of road
Only runs on aclosed circuit
Works on everytype of road
Heavy setup required Turn the key
PART THREE
The MonitorStrikes Back
import ca.uqac.lif.cep.*;
public class MyProcessor extends SingleProcessor {
public Queue<Object[]> compute(Object[] inputs) {
}
public void build(Stack<Object> s) {
}}
. . . Create output events from input . . .
. . . Instantiate processor from parse stack . . .
<processor> := . . .<number> := . . .<string> := . . .
Add new rules to any symbol fromthe basic grammar
Example: let us create a new 1 : 1 Processor that increments its input by a fixed value
We would like to use it in eSQL with thissyntax:
INCREMENT ( P ) BY value
Any expressiondefining a processor
Number
<processor> := <my_processor> ;
<my_processor> := INCREMENT ( <processor> ) BY <number> ;
Symbols already defined in basic grammar
Adds a new case to an existing rule
import ca.uqac.lif.cep.*;
public class MyProcessor extends SingleProcessor {
private int increment;
public Queue<Object[]> compute(Object[] inputs) { Queue<Vector<Object>> out = new Queue<Vector<Object>>(); Object[] v = new Object[1]; Integer i = (Integer) inputs[0] + increment; v[0] = i; out.put(v); return out; }
. . .
. . .
public void build(Stack<Object> s) { Number n = (Number) s.pop(); s.pop(); s.pop(); Processor p = (Processor) s.pop(); s.pop(); s.pop();
increment = n.intValue();
Connector.connect(p, this);
s.push(this); }}
Read contents ofparse stack
<number>BY(<processor>)INCREMENT
Set processor's statePipe it to its inputPut on parse stack
Total: 6+9=15 lines of code
. . .
public void build(Stack<Object> s) { Number n = (Number) s.pop(); s.pop(); s.pop(); Processor p = (Processor) s.pop(); s.pop(); s.pop();
increment = n.intValue();
Connector.connect(p, this);
s.push(this); }}
Read contents ofparse stack
<number>BY(<processor>)INCREMENT
Set processor's statePipe it to its inputPut on parse stack
Some pre-packaged grammar extensions:
Manipulation of name-value tuples
Set theory
Formatted input (CSV, XML, JSON)
Graphing (histograms, scatterplots, ...)
Basic signal processing (smoothing, peak detection, ...)
Create your own!
import ca.uqac.lif.cep.*;import ca.uqac.lif.cep.eml.tuples.*;
public class MyExample {
public static void main(String[] args) { Interpreter my_int = new Interpreter();
my_int.extendGrammar(TupleGrammar.class);
Pullable p = my_int.executeQuery( "\"HELLO WORLD\"");
for (int i = 0; i < 10; i++) { EmlString s = (EmlString) p.pull(); System.out.println(s); } }}
Create query interpreterLoad a grammar extension
Execute a query
Pull an output event
Example: let us create a new 1 : 1 Processor that parses XML events (using an existingXML library)
This can be done by first defining a Functionthat converts Strings into XML objects
import ca.uqac.lif.cep.*;import ca.uqac.lif.xml.*;
public static class XmlParsingFunction extends UnaryFunction<String,XmlElement> { public static XmlParsingFunction instance = new XmlParsingFunction();
private XmlParsingFunction() { super(String.class, XmlElement.class); }
public XmlElement getValue(String x) { try { return XmlElement.parse(x); } catch (XmlParseException e) { } return null; } }}
import ca.uqac.lif.cep.*;import ca.uqac.lif.xml.*;
public static class XmlParsingFunction extends UnaryFunction<String,XmlElement> { public static XmlParsingFunction instance = new XmlParsingFunction();
private XmlParsingFunction() { super(String.class, XmlElement.class); }
public XmlElement getValue(String x) { try { return XmlElement.parse(x); } catch (XmlParseException e) { } return null; } }} Total: 10 lines of code
Query Editor
+ ?
>
>
<
>
=
+
*
n
A /
A /
Playback controls
Can execute a query one event at a time (play/pause), or at a custom input rate
A /
Toggle between graphand grammar view
>
>
<
>
=
+
*
n
Palettes: drag/drop on playgroundto compose query. Conventions:
Light pipes = inputDark pipes = output
Colours = event types
Correct flow = dark → lightType discipline = matching colours
Logic
I/O
Tuples
Plumbing
Numbers
Booleans
BlobsName-value tuples
Math
Query Editor
+ ?
>
>
<
>
=
+
*
n
A /
3 5 53 2
"Magnifier" revealsrealtime content of messagequeues...
Query Editor
+ ?
>
>
<
>
=
+
*
n
A /
Threshold
Some processors have parameters;can modify them with contextual menu
Query Editor
+ ?
>
>
<
>
=
+
*
n
A /
Site C
Site BSite A
Separation of query parts onmultiple sites
BeepBeep needs you!BeepBeep needs you!
Licensed under LGPL: download anduse it
Create you own domain-specific palettes
Take your own monitor/script and wrapit into a new Processor object
For free: benefit from all existing processorsand functions already available
https://liflab.github.io/beepbeep-3