fourValuedLogicValue
Four valued logic value
ageConstraint(stimulus: Events[Int], response: Events[Int], minTimeDiff: Int, maxTimeDiff: Int): Events[fourValuedLogicValue]
Checks the AgeConstraint defined in TADL2.
For each response event on stimulus, there must be an stimulus event of the same color in response in the given time distance before the stimulus event. The color attribute is represented as integer. The source code expects the colors of the streams to fulfill the correctness of event chain. See checkEventChain to check this.
Usage Example
in stimulus: Events[Int]
in response: Events[Int]
def minTimeDiff = 5
def maxTimeDiff = 5
def constraint= TADL2.ageConstraint(stimulus, response, minTimeDiff, maxTimeDiff)
out constraint.value
out constraint.final
Trace Example
option timeDomain:[-1,25]
1: stimulus = 1
1: constraint.value = true
1: constraint.final = false
6: response = 1
6: constraint.value = true
6: constraint.final = false
8: stimulus = 4
8: constraint.value = true
8: constraint.final = false
10: stimulus = 2
10: constraint.value = true
10: constraint.final = false
13: stimulus = 3
13: constraint.value = true
13: constraint.final = false
15: response = 2
15: constraint.value = true
15: constraint.final = false
18: response = 3
18: constraint.value = true
18: constraint.final = false
def ageConstraint(stimulus: Events[Int], response: Events[Int], minTimeDiff: Int, maxTimeDiff: Int):
Events[fourValuedLogicValue] :=
ageConstraintReset(stimulus, response, minTimeDiff, maxTimeDiff, pseudoInfty)
ageConstraintReset(stimulus: Events[Int], response: Events[Int], minTimeDiff: Int, maxTimeDiff: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the AgeConstraint defined in TADL2.
Any state that leads to a final negative answer is resetted after resetTime.
See ageConstraint
for more information.
def ageConstraintReset(stimulus: Events[Int], response: Events[Int], minTimeDiff: Int, maxTimeDiff: Int,
resetTime: Int): Events[fourValuedLogicValue] := {
#removes colors, that were before timeBound, from the list
def removeOldStimulusColorsFromList(latestStimulusColors: List[Int],
colorTimeStamps: Map[Int, Int], timeBound: Int): List[Int] :=
# list empty
if (List.size(latestStimulusColors) == 0) then
latestStimulusColors
else
# oldest event not too old-> return current list
if (Map.contains(colorTimeStamps, List.head(latestStimulusColors)) &&
Map.get(colorTimeStamps, List.head(latestStimulusColors)) >= timeBound) then
latestStimulusColors
else
# recursive call without oldest color
removeOldStimulusColorsFromList(List.tail(latestStimulusColors), colorTimeStamps, timeBound)
#removes colors, that were before timeBound, from the map
def removeOldStimulusColorsFromSet(latestStimulusColors: List[Int],
colorTimeStamps: Map[Int, Int], timeBound: Int): Map[Int, Int] :=
if (List.size(latestStimulusColors) == 0) then
colorTimeStamps
else
# oldest event not too old-> return current map
if (Map.contains(colorTimeStamps, List.head(latestStimulusColors)) &&
Map.get(colorTimeStamps, List.head(latestStimulusColors)) >= timeBound) then
colorTimeStamps
else
# recursive call without oldest color
removeOldStimulusColorsFromSet(List.tail(latestStimulusColors),
Map.remove(colorTimeStamps, List.head(latestStimulusColors)), timeBound)
# map with unmatched stimulus events after stimulus
def stimulusEventsNewStimulus : Events[Map[Int, Int]] :=
# stimulus events in this timestamp-> insert event in Map, else keep previous map
if (defaultTime(stimulus) >= defaultTime(response)) then
Map.add(default(last(stimulusEvents, merge(stimulus, response)), Map.empty[Int, Int]),
stimulus, defaultTime(stimulus))
else
default(last(stimulusEvents, merge(stimulus, response)), Map.empty[Int, Int])
#unmatched stimulus events, remove events that are too old
def stimulusEvents:=
slift3(default(last(stimulusColorsYoungerThanMax, stimulus), List.empty[Int]),
stimulusEventsNewStimulus,
defaultTime(merge(stimulus, response)) - maxTimeDiff,
removeOldStimulusColorsFromSet)
#unmatched stimulus events, that are younger than maximum
def stimulusColorsYoungerThanMax: Events[List[Int]]:=
slift3(
List.append(slift(default(last(stimulusColorsYoungerThanMax, stimulus), List.empty[Int]),
stimulus, List_remove), stimulus),
stimulusEventsNewStimulus,
defaultTime(merge(stimulus, response)) - maxTimeDiff,
removeOldStimulusColorsFromList)
#evaluation
# 'now' has response event => time matches to unmatched stimulus event
stillFulfillableReset(
if ((!(defaultTime(stimulus) <= defaultTime(response))) ||
Map.contains(stimulusEventsNewStimulus, merge(response, -1)) &&
Map.get(stimulusEventsNewStimulus, merge(response, -1)) + minTimeDiff <= defaultTime(response) &&
Map.get(stimulusEventsNewStimulus, merge(response, -1)) + maxTimeDiff >= defaultTime(response)) then
{value= true, final= false}
else
{value= false, final= true},
resetTime)
}
arbitraryConstraint[A](e: Events[A], minDist: List[Int], maxDist: List[Int]): Events[fourValuedLogicValue]
Checks the ArbitraryConstraint defined in TADL2.
The ArbitraryConstraint describes the time distances between several subsequent events
Usage Example
in x: Events[Unit]
def minDist: List[Int] := List.append(List.append(List.empty[Int], 1), 5)
def maxDist: List[Int] := List.append(List.append(List.empty[Int], 5), 6)
def constraint = TADL2.arbitraryConstraint(x, minDist, maxDist)
out constraint.value
out constraint.final
Trace Example
1: x = ()
1: constraint.value = true
1: constraint.final = false
6: x = ()
6: constraint.value = true
6: constraint.final = false
7: x = ()
7: constraint.value = true
7: constraint.final = false
11: x = ()
11: constraint.value = true
11: constraint.final = false
12: x = ()
12: constraint.value = true
12: constraint.final = false
16: x = ()
16: constraint.value = true
16: constraint.final = false
17: x = ()
17: constraint.value = true
17: constraint.final = false
21: x = ()
21: constraint.value = true
21: constraint.final = false
22: x = ()
22: constraint.value = true
22: constraint.final = false
26: x = ()
26: constraint.value = true
26: constraint.final = false
27: x = ()
27: constraint.value = true
27: constraint.final = false
31: x = ()
31: constraint.value = true
31: constraint.final = false
32: x = ()
32: constraint.value = true
32: constraint.final = false
36: x = ()
36: constraint.value = true
36: constraint.final = false
37: x = ()
37: constraint.value = true
37: constraint.final = false
41: x = ()
41: constraint.value = true
41: constraint.final = false
42: x = ()
42: constraint.value = true
42: constraint.final = false
46: x = ()
46: constraint.value = true
46: constraint.final = false
def arbitraryConstraint[A](e: Events[A], minDist: List[Int], maxDist: List[Int]): Events[fourValuedLogicValue] :=
arbitraryConstraintRec(e, minDist, maxDist, 1, pseudoInfty)
arbitraryConstraintReset[A](e: Events[A], minDist: List[Int], maxDist: List[Int], resetTime: Int): Events[fourValuedLogicValue]
Checks the ArbitraryConstraint defined in TADL2.
Resets a negative output after resetTime.
See arbitraryConstraint
for more information.
def arbitraryConstraintReset[A](e: Events[A], minDist: List[Int], maxDist: List[Int], resetTime: Int):
Events[fourValuedLogicValue] :=
arbitraryConstraintRec(e, minDist, maxDist, 1, resetTime)
burstConstraint[A](e: Events[A], length: Int, maxOccurrences: Int, minDist: Int): Events[fourValuedLogicValue]
Checks the BurstConstraint defined in TADL2.
The BurstConstraints limits the number of events (maxOccurences) in a time interval of a specific length (length). Additionally, it is checked if subsequent events have a minimal distance (minDist).
Usage Example
in event: Events[Unit]
def length = 5
def maxOccurences = 3
def minDist = 1
def constraint= TADL2.burstConstraint(event, length, macOccurences, minDist)
out constraint.value
out constraint.final
Trace Example
1: event = ()
1: constraint.value = true
1: constraint.final = false
2: event = ()
2: constraint.value = true
2: constraint.final = false
3: event = ()
3: constraint.value = true
3: constraint.final = false
7: event = ()
7: constraint.value = true
7: constraint.final = false
8: event = ()
8: constraint.value = true
8: constraint.final = false
9: event = ()
9: constraint.value = true
9: constraint.final = false
20: event = ()
20: constraint.value = true
20: constraint.final = false
21: event = ()
21: constraint.value = true
21: constraint.final = false
22: event = ()
22: constraint.value = true
22: constraint.final = false
def burstConstraint[A](e: Events[A], length: Int, maxOccurrences: Int, minDist: Int): Events[fourValuedLogicValue] :=
burstConstraintReset(e, length, maxOccurrences, minDist, pseudoInfty)
burstConstraintReset[A](e: Events[A], length: Int, maxOccurrences: Int, minDist: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the BurstConstraint as defined in TADL2
resets a negative output and an invalid state after resetTime
See burstConstraint
for more information.
def burstConstraintReset[A](e: Events[A], length: Int, maxOccurrences: Int, minDist: Int,
resetTime: Int): Events[fourValuedLogicValue] :=
# application of repeatConstraint
fourValuedConjunction(repeatConstraintReset(e, length, pseudoInfty, maxOccurrences, resetTime),
repeatConstraintReset(e, minDist, pseudoInfty, 1, resetTime))
checkEventChain(stimulus: Events[Int], response: Events[Int]): Events[fourValuedLogicValue]
The function checkEventChain checks the correctness of event chains. Any stimulus event of a specific color must occur before the first response event with the same color.
This function should only be used, when there is no other reasonable way to check the correctness of event chain, because it stores each color that occurs in the response stream.
Usage Example
in stimulus: Events[Int]
in response: Events[Int]
def constraint= TADL2.checkEventChain(stimulus, response)
out constraint.value
out constraint.final
Trace Example
option timeDomain:[-1,90]
1: stimulus = 1
1: constraint.value = true
1: constraint.final = false
2: stimulus = 2
2: constraint.value = true
2: constraint.final = false
3: stimulus = 3
3: constraint.value = true
3: constraint.final = false
4: stimulus = 4
4: constraint.value = true
4: constraint.final = false
11: response = 1
11: constraint.value = true
11: constraint.final = false
12: response = 2
12: constraint.value = true
12: constraint.final = false
13: response = 3
13: constraint.value = true
13: constraint.final = false
14: response = 4
14: constraint.value = true
14: constraint.final = false
def checkEventChain(stimulus: Events[Int], response: Events[Int]): Events[fourValuedLogicValue]:=
checkEventChainReset(stimulus, response, pseudoInfty)
checkEventChainReset(stimulus: Events[Int], response: Events[Int], resetTime: Int): Events[fourValuedLogicValue]
Checks the correctness of EventChains as defined in TADL2.
Any state that leads to a final negative answer is resetted after resetTime.
See checkEventChain
for more information.
def checkEventChainReset(stimulus: Events[Int], response: Events[Int], resetTime: Int):
Events[fourValuedLogicValue]:= {
# next timestamp after 'falling flank'
def failingTimeStamps: Events[Unit] =
filter(mergeUnit(stimulus, response), last(result.final, mergeUnit(stimulus, response)) &&
!(last(last(result.final, mergeUnit(stimulus, response)), mergeUnit(stimulus, response))))
#timestamps, in which the state of the monitor is resetted
def resets: Events[Unit]=
delay(const(resetTime, failingTimeStamps)-(time(mergeUnit(stimulus, response)) -
prev(time(mergeUnit(stimulus, response)))),
failingTimeStamps)
# colors that occured in response-> not allows in stimulus anymore
def previousResponseColors: Events[Set[Int]]:=
merge(merge(const(Set.empty[Int], resets),
Set.add(last(previousResponseColors, response), response)),
Set.empty[Int])
def result:= stillFulfillableReset(
if on(merge(stimulus, response),
# stimulus event-> color didn't occur in response earlier
if (defaultTime(stimulus) >= defaultTime(response)) then
!Set.contains(previousResponseColors, stimulus)
else
true) then
{value= true, final= false}
else
{value= false, final= true},
resetTime)
result
}
delayConstraint[A, B](source: Events[A], target: Events[B], lower: Int, upper: Int): Events[fourValuedLogicValue]
Checks the DelayConstraint defined in TADL2.
Each source event must be followed by at least one target event, which occurs within a time distance between lower and upper. Additional target events are allowed.
Usage Example
in source: Events[Unit]
in target: Events[Unit]
def lower = 15
def upper = 25
def constraint:= TADL2.delayConstraint(source, target, lower, upper)
out constraint.value
out constraint.final
Trace Example
10: source = ()
10: constraint.value = false
10: constraint.final = false
25: target = ()
25: constraint.value = true
25: constraint.final = false
50: source = ()
50: constraint.value = false
50: constraint.final = false
65: target = ()
65: constraint.value = true
65: constraint.final = false
75: target = ()
75: constraint.value = true
75: constraint.final = false
80: target = ()
80: constraint.value = true
80: constraint.final = false
def delayConstraint[A, B](source: Events[A], target: Events[B], lower: Int, upper: Int) :
Events[fourValuedLogicValue] :={
delayConstraintReset(source, target, lower, upper, pseudoInfty)
}
delayConstraintReset[A, B](source: Events[A], target: Events[B], lower: Int, upper: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the DelayConstraint defined in TADL2.
Each source event must be followed by at least one target event, which occurs within a time distance between lower and upper. Additional target events are allowed. A final false output will be set to unfinfal after resetTime.
Usage Example
in source: Events[Unit]
in target: Events[Unit]
def lower = 15
def upper = 25
def resetTime
def constraint:= TADL2.delayConstraintReset(source, target, lower, upper, resetTime)
out constraint.value
out constraint.final
Trace Example
10: source = ()
10: constraint.value = false
10: constraint.final = false
25: target = ()
25: constraint.value = true
25: constraint.final = false
50: source = ()
50: constraint.value = false
50: constraint.final = false
65: target = ()
65: constraint.value = true
65: constraint.final = false
75: target = ()
75: constraint.value = true
75: constraint.final = false
80: target = ()
80: constraint.value = true
80: constraint.final = false
def delayConstraintReset[A, B](source: Events[A], target: Events[B], lower: Int, upper: Int,
resetTime: Int) : Events[fourValuedLogicValue] :={
# timestamps of source events, which did not have matching target event yet,
# including the timestamps, which matches in this this timestamp
def unfinishedSourceTimesNewSource: Events[List[Int]] :=
# 'now' has source event
if (defaultTime(source) >= defaultTime(target)) then
List.append(default(last(unfinishedSourceTimes, mergeUnit(source, target)), List.empty[Int]),
time(source))
else
default(last(unfinishedSourceTimes, mergeUnit(source, target)), List.empty[Int])
def unfinishedSourceTimesAfterReset: Events[List[Int]] :=
if (List.size(unfinishedSourceTimesNewSource) != 0) then
if (List.head(unfinishedSourceTimesNewSource) + resetTime < time(mergeUnit(source, target))) then
removeItemsSmallerThanAFromListFront(unfinishedSourceTimesNewSource,
time(mergeUnit(source, target)) - upper)
else
unfinishedSourceTimesNewSource
else
List.empty[Int]
# timestamps of source events, which did not have matching target event yet
def unfinishedSourceTimes: Events[List[Int]]:=
# 'now' has target event
if (defaultTime(source) <= defaultTime(target) &&
# List has source event without matching target
List.size(unfinishedSourceTimesAfterReset) > 0 &&
# target event now matches with oldest source event
List.head(unfinishedSourceTimesAfterReset) + lower <= defaultTime(target) &&
List.head(unfinishedSourceTimesAfterReset) + upper >= defaultTime(target)) then
#remove matched target events
merge(slift(unfinishedSourceTimesAfterReset, defaultTime(target) - lower + 1,
removeItemsSmallerThanAFromListFront),
List.empty[Int])
else
merge(unfinishedSourceTimesAfterReset, List.empty[Int])
# timestamps, in which the evaluation occurs
def evaluateTimes = mergeUnit(mergeUnit(source, target),
safeDelay(if (List.size(unfinishedSourceTimes) == 0) then
-1
else
List.head(unfinishedSourceTimes) + upper - time(mergeUnit(source, target))+1,
mergeUnit(source, target)))
stillFulfillableReset(
# no unfinished source events -> current true
if (List.size(unfinishedSourceTimes) == 0) then
{value= true, final= false}
else
# oldest source event can still be finished-> current false
if (time(evaluateTimes) <= List.head(unfinishedSourceTimes) + upper) then
{value= false, final= false}
# oldest source event is too old -> final false
else
{value= false, final= true},
resetTime)
}
executionTimeConstraint[A, B, C, D](start: Events[A], end: Events[B], preempt: Events[C], resume: Events[D], lower: Int, upper: Int): Events[fourValuedLogicValue]
Checks the executionTimeConstraint defined in TADL2.
Checks, if the time between one start event and the next end event, minus the preemptions, is between lower and upper. The source code is only tested for events in logical order.
Usage Example
in start: Events[Unit]
in end: Events[Unit]
in preempt: Events[Unit]
in resume: Events[Unit]
def lower = 10
def upper = 12
def constraint= TADL2.executionTimeConstraint(start, end, preempt, resume, 10, 12)
out constraint.value
out constraint.final
Trace Example
5: start = ()
5: constraint.value = true
5: constraint.final = false
10: preempt = ()
10: constraint.value = true
10: constraint.final = false
12: resume = ()
12: constraint.value = true
12: constraint.final = false
15: preempt = ()
15: constraint.value = true
15: constraint.final = false
17: resume = ()
17: constraint.value = true
17: constraint.final = false
20: end = ()
20: constraint.value = true
20: constraint.final = false
def executionTimeConstraint[A, B, C, D](start: Events[A], end: Events[B], preempt: Events[C], resume: Events[D],
lower: Int, upper: Int): Events[fourValuedLogicValue] :={
executionTimeConstraintReset(start, end, preempt, resume, lower, upper, pseudoInfty)
}
executionTimeConstraintReset[A, B, C, D](start: Events[A], end: Events[B], preempt: Events[C], resume: Events[D], lower: Int, upper: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the executionTimeConstraint defined in TADL2.
Resets a negative output after resetTime.
See executionTimeConstraint
for more information.
def executionTimeConstraintReset[A, B, C, D](start: Events[A], end: Events[B], preempt: Events[C], resume: Events[D],
lower: Int, upper: Int, resetTime: Int): Events[fourValuedLogicValue] :={
# timestamps, when the constraint is evaluated
def inputTimes: Events[Unit] := mergeUnit(mergeUnit(mergeUnit(start, end), preempt), resume)
# timestamps, in which the evaluation occurs
def evaluateTimes: Events[Unit] :=
mergeUnit(inputTimes, safeDelay(if (time(inputTimes) != defaultTime(end) &&
time(inputTimes) != defaultTime(preempt)) then
upper - execTime + 1
else
-1, inputTimes))
# evaluation
def execTime : Events[Int] := runtime(start, evaluateTimes) - resetSum(runtime(preempt, resume), start)
# 'now' is end event
stillFulfillableReset(
#first event or correct distance to X
if (if (time(evaluateTimes) == defaultTime(end)) then
lower <= execTime && execTime <= upper
else
#ignore lower
execTime <= upper) then
{value= true, final= false}
else
{value= false, final= true},
resetTime)
}
liftable fourValuedConjunction(a: fourValuedLogicValue, b: fourValuedLogicValue)
Conjunction operator on four valued logic values
liftable def fourValuedConjunction(a: fourValuedLogicValue, b: fourValuedLogicValue):=
if ((!a.value && a.final) || (!b.value && b.final)) then
{value= false, final= true}
else
if ((!a.value && !a.final) || (!b.value && !b.final)) then
{value= false, final= false}
else
if ((a.value && !a.final) || (b.value && !b.final)) then
{value= true, final= false}
else
{value= true, final= true}
inputSynchronizationConstraint10(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int], stimulus8: Events[Int], stimulus9: Events[Int], stimulus10: Events[Int], response: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for ten stimulus streams.
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraint10(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int],
stimulus8: Events[Int], stimulus9: Events[Int], stimulus10: Events[Int], response: Events[Int],
tolerance: Int): Events[fourValuedLogicValue] :=
inputSynchronizationConstraintReset10(stimulus1, stimulus2, stimulus3, stimulus4, stimulus5, stimulus6,
stimulus7, stimulus8, stimulus9, stimulus10, response, tolerance, pseudoInfty)
inputSynchronizationConstraint2(stimulus1: Events[Int], stimulus2: Events[Int], response: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for two stimulus streams.
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraint2(stimulus1: Events[Int], stimulus2: Events[Int], response: Events[Int],
tolerance: Int): Events[fourValuedLogicValue] :=
inputSynchronizationConstraintReset2(stimulus1, stimulus2, response, tolerance, pseudoInfty)
inputSynchronizationConstraint3(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], response: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for three stimulus streams.
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraint3(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
response: Events[Int], tolerance: Int): Events[fourValuedLogicValue] :=
inputSynchronizationConstraintReset3(stimulus1, stimulus2, stimulus3, response, tolerance, pseudoInfty)
inputSynchronizationConstraint4(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], response: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for four stimulus streams.
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraint4(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], response: Events[Int], tolerance: Int): Events[fourValuedLogicValue] :=
inputSynchronizationConstraintReset4(stimulus1, stimulus2, stimulus3, stimulus4, response, tolerance,
pseudoInfty)
inputSynchronizationConstraint5(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], response: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for five stimulus streams.
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraint5(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], response: Events[Int], tolerance: Int):
Events[fourValuedLogicValue] :=
inputSynchronizationConstraintReset5(stimulus1, stimulus2, stimulus3, stimulus4, stimulus5, response,
tolerance, pseudoInfty)
inputSynchronizationConstraint6(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], response: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for six stimulus streams.
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraint6(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], response: Events[Int],
tolerance: Int): Events[fourValuedLogicValue] :=
inputSynchronizationConstraintReset6(stimulus1, stimulus2, stimulus3, stimulus4, stimulus5, stimulus6,
response, tolerance, pseudoInfty)
inputSynchronizationConstraint7(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int], response: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for seven stimulus streams.
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraint7(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int],
response: Events[Int], tolerance: Int): Events[fourValuedLogicValue] :=
inputSynchronizationConstraintReset7(stimulus1, stimulus2, stimulus3, stimulus4, stimulus5, stimulus6,
stimulus7, response, tolerance, pseudoInfty)
inputSynchronizationConstraint8(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int], stimulus8: Events[Int], response: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for eight stimulus streams.
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraint8(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int],
stimulus8: Events[Int], response: Events[Int], tolerance: Int): Events[fourValuedLogicValue] :=
inputSynchronizationConstraintReset8(stimulus1, stimulus2, stimulus3, stimulus4, stimulus5, stimulus6,
stimulus7, stimulus8, response, tolerance, pseudoInfty)
inputSynchronizationConstraint9(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int], stimulus8: Events[Int], stimulus9: Events[Int], response: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for nine stimulus streams.
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraint9(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int],
stimulus8: Events[Int], stimulus9: Events[Int], response: Events[Int], tolerance: Int):
Events[fourValuedLogicValue] :=
inputSynchronizationConstraintReset9(stimulus1, stimulus2, stimulus3, stimulus4, stimulus5, stimulus6,
stimulus7, stimulus8, stimulus9, response, tolerance, pseudoInfty)
inputSynchronizationConstraintReset(eventStreamIndices: Events[Map[Int, Int]], stimulusStreamCount: Int, tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint defined in TADL2.
In the InputSynchronizationConstraint, there must be one synchronization cluster of the length tolerance for each response event. Each stimulus stream must have at least one event of the same color as the response event in this cluster. A stream of maps must be created, representing the events of each timestamp. The key of each entry is the index of the stream (0 for the response stream, 1, 2, … for the stimulus streams), in which the event occurred and the value is the color of the event. The creation of this map is already implemented for up to 10 response streams, see inputSynchronizationConstraint2, … . The source code expects the colors of the streams to fulfill the correctness of event chain. See checkEventChain to check this.
Usage Example
in response: Events[Int]
in stimulus1: Events[Int]
in stimulus2: Events[Int]
in stimulus3: Events[Int]
def tolerance = 2
def constraint= TADL2.inputSynchronizationConstraint3(stimulus1, stimulus2, stimulus3, response, tolerance)
out constraint.value
out constraint.final
Trace Example
option timeDomain:[-1,22]
1: stimulus1 = 1
1: constraint.value = true
1: constraint.final = false
5: stimulus1 = 1
5: stimulus2 = 1
5: stimulus3 = 1
5: constraint.value = true
5: constraint.final = false
6: response = 1
6: constraint.value = true
6: constraint.final = false
15: stimulus1 = 2
15: constraint.value = true
15: constraint.final = false
16: stimulus2 = 2
16: constraint.value = true
16: constraint.final = false
17: stimulus3 = 2
17: constraint.value = true
17: constraint.final = false
20: response = 2
20: constraint.value = true
20: constraint.final = false
def inputSynchronizationConstraintReset(eventStreamIndices: Events[Map[Int, Int]], stimulusStreamCount: Int,
tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:= {
# Help functions
#builds the starting point for the state Map
def buildEmptylatestEventTimes(stimulusStreamCount: Int): Map[Int, Map[Int, Int]] :=
if (stimulusStreamCount == 0) then
Map.empty[Int, Map[Int, Int]]
else
Map.add(buildEmptylatestEventTimes(stimulusStreamCount-1), stimulusStreamCount, Map.empty[Int, Int]);
# adds stimulus events to stored events
def addEventsToEmptylatestEventTimes(latestEventTimes: Map[Int, Map[Int, Int]], timeNow: Int,
eventStreamIndices: Map[Int, Int]): Map[Int, Map[Int, Int]] :=
addEventsToEmptylatestEventTimesRec(latestEventTimes, timeNow, eventStreamIndices, Map.keys(eventStreamIndices));
def addEventsToEmptylatestEventTimesRec(latestEventTimes: Map[Int, Map[Int, Int]], timeNow: Int,
eventStreamIndices: Map[Int, Int], remainingKeys: List[Int]): Map[Int, Map[Int, Int]] :=
if (List.size(remainingKeys) == 0) then
latestEventTimes
else
# if resoponse stream -> don't insert
if (List.head(remainingKeys) == 0) then
addEventsToEmptylatestEventTimesRec(latestEventTimes, timeNow, eventStreamIndices,
List.tail(remainingKeys))
else
# insert head of map and recursive call
addEventsToEmptylatestEventTimesRec(
Map.add(latestEventTimes, List.head(remainingKeys),
Map.add(Map.get(latestEventTimes, List.head(remainingKeys)), Map.get(eventStreamIndices,
List.head(remainingKeys)), timeNow)),
timeNow, eventStreamIndices, List.tail(remainingKeys))
# time of the oldest event of the given color
def timeOldestEvent(latestEvents: Map[Int, Map[Int, Int]], color: Int, remainingKeys: List[Int]): Int :=
#static if (Map.size(latestEvents) == 0 || List.size(remainingKeys) == 0) then
if (List.size(remainingKeys) == 0) then
pseudoInfty
else
if (Map.contains(Map.get(latestEvents, List.head(remainingKeys)), color)) then
min(Map.get(Map.get(latestEvents, List.head(remainingKeys)), color),
timeOldestEvent(latestEvents, color, List.tail(remainingKeys)))
else
-pseudoInfty
# time of the youngest event of the given color
def timeYoungestEvent(latestEvents: Map[Int, Map[Int, Int]], color: Int, remainingKeys: List[Int]): Int :=
#static if (Map.size(latestEvents) == 0 || List.size(remainingKeys) == 0) then
if (List.size(remainingKeys) == 0) then
-pseudoInfty
else
if (Map.contains(Map.get(latestEvents, List.head(remainingKeys)), color)) then
max(Map.get(Map.get(latestEvents, List.head(remainingKeys)), color),
timeYoungestEvent(latestEvents, color, List.tail(remainingKeys)))
else
pseudoInfty
# checks, if the synchronization cluster for the given color is fulfilled
def clusterFulfilled(latestEventTimes: Map[Int, Map[Int, Int]], color: Int, tolerance: Int) : Bool =
clusterFulfilledRec(latestEventTimes, Map.keys(latestEventTimes), color, tolerance)
def clusterFulfilledRec(latestEventTimes: Map[Int, Map[Int, Int]], remainingKeys: List[Int], color: Int,
tolerance: Int) : Bool =
if (List.size(remainingKeys) == 0) then
true
else
timeOldestEvent(latestEventTimes, color, remainingKeys) + tolerance >=
timeYoungestEvent(latestEventTimes, color, remainingKeys) &&
clusterFulfilledRec(latestEventTimes, List.tail(remainingKeys), color, tolerance)
#stored information
# time of last stimulus events with given color
# streamIndex -> (color -> time)
def latestEventTimes: Events[Map[Int, Map[Int, Int]]] :=
slift3(default(last(latestEventTimes, time(eventStreamIndices)), buildEmptylatestEventTimes(stimulusStreamCount)),
time(eventStreamIndices), eventStreamIndices, addEventsToEmptylatestEventTimes)
#evaluation
stillFulfillableReset(
# response event-> valid cluster of the same color must exists
if (Map.contains(eventStreamIndices, 0)) then
if slift3(latestEventTimes, Map.get(eventStreamIndices, 0), tolerance, clusterFulfilled) then
{value= true, final= false}
else
{value= false, final= true}
else
# no response event-> invalid trace
{value= true, final= false},
resetTime)
}
inputSynchronizationConstraintReset10(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int], stimulus8: Events[Int], stimulus9: Events[Int], stimulus10: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for ten stimulus streams.
resets a negative output and invalid state after resetTime
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraintReset10(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int],
stimulus8: Events[Int], stimulus9: Events[Int], stimulus10: Events[Int], response: Events[Int],
tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus1),
merge(time(stimulus2),
merge(time(stimulus3),
merge(time(stimulus4),
merge(time(stimulus5),
merge(time(stimulus6),
merge(time(stimulus7),
merge(time(stimulus8),
merge(time(stimulus9),
merge(time(stimulus10),
time(response)))))))))))
def eventStimulus:= if (defaultTime(response) >= timeNow) then Map.add(Map.empty[Int, Int], 0, default(response, -1)) else Map.empty[Int, Int]
def eventResponse1:= if (defaultTime(stimulus1) >= timeNow) then Map.add(eventStimulus, 1, default(stimulus1, -1)) else eventStimulus
def eventResponse2:= if (defaultTime(stimulus2) >= timeNow) then Map.add(eventResponse1, 2, default(stimulus2, -1)) else eventResponse1
def eventResponse3:= if (defaultTime(stimulus3) >= timeNow) then Map.add(eventResponse2, 3, default(stimulus3, -1)) else eventResponse2
def eventResponse4:= if (defaultTime(stimulus4) >= timeNow) then Map.add(eventResponse3, 4, default(stimulus4, -1)) else eventResponse3
def eventResponse5:= if (defaultTime(stimulus5) >= timeNow) then Map.add(eventResponse4, 5, default(stimulus5, -1)) else eventResponse4
def eventResponse6:= if (defaultTime(stimulus6) >= timeNow) then Map.add(eventResponse5, 6, default(stimulus6, -1)) else eventResponse5
def eventResponse7:= if (defaultTime(stimulus7) >= timeNow) then Map.add(eventResponse6, 7, default(stimulus7, -1)) else eventResponse6
def eventResponse8:= if (defaultTime(stimulus8) >= timeNow) then Map.add(eventResponse7, 8, default(stimulus8, -1)) else eventResponse7
def eventResponse9:= if (defaultTime(stimulus9) >= timeNow) then Map.add(eventResponse8, 9, default(stimulus9, -1)) else eventResponse8
def eventResponse10:= if (defaultTime(stimulus10) >= timeNow) then Map.add(eventResponse9, 10, default(stimulus10, -1)) else eventResponse9
inputSynchronizationConstraintReset(eventResponse10, 10, tolerance, resetTime)
}
inputSynchronizationConstraintReset2(stimulus1: Events[Int], stimulus2: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for two stimulus streams.
resets a negative output and invalid state after resetTime
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraintReset2(stimulus1: Events[Int], stimulus2: Events[Int], response: Events[Int],
tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus1),
merge(time(stimulus2),
time(response)))
def eventStimulus:= if (defaultTime(response) >= timeNow) then Map.add(Map.empty[Int, Int], 0, default(response, -1)) else Map.empty[Int, Int]
def eventResponse1:= if (defaultTime(stimulus1) >= timeNow) then Map.add(eventStimulus, 1, default(stimulus1, -1)) else eventStimulus
def eventResponse2:= if (defaultTime(stimulus2) >= timeNow) then Map.add(eventResponse1, 2, default(stimulus2, -1)) else eventResponse1
inputSynchronizationConstraintReset(eventResponse2, 2, tolerance, resetTime)
}
inputSynchronizationConstraintReset3(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for three stimulus streams.
resets a negative output and invalid state after resetTime
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraintReset3(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus1),
merge(time(stimulus2),
merge(time(stimulus3),
time(response))))
def eventStimulus:= if (defaultTime(response) >= timeNow) then Map.add(Map.empty[Int, Int], 0, default(response, -1)) else Map.empty[Int, Int]
def eventResponse1:= if (defaultTime(stimulus1) >= timeNow) then Map.add(eventStimulus, 1, default(stimulus1, -1)) else eventStimulus
def eventResponse2:= if (defaultTime(stimulus2) >= timeNow) then Map.add(eventResponse1, 2, default(stimulus2, -1)) else eventResponse1
def eventResponse3:= if (defaultTime(stimulus3) >= timeNow) then Map.add(eventResponse2, 3, default(stimulus3, -1)) else eventResponse2
inputSynchronizationConstraintReset(eventResponse3, 3, tolerance, resetTime)
}
inputSynchronizationConstraintReset4(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for four stimulus streams.
resets a negative output and invalid state after resetTime
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraintReset4(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus1),
merge(time(stimulus2),
merge(time(stimulus3),
merge(time(stimulus4),
time(response)))))
def eventStimulus:= if (defaultTime(response) >= timeNow) then Map.add(Map.empty[Int, Int], 0, default(response, -1)) else Map.empty[Int, Int]
def eventResponse1:= if (defaultTime(stimulus1) >= timeNow) then Map.add(eventStimulus, 1, default(stimulus1, -1)) else eventStimulus
def eventResponse2:= if (defaultTime(stimulus2) >= timeNow) then Map.add(eventResponse1, 2, default(stimulus2, -1)) else eventResponse1
def eventResponse3:= if (defaultTime(stimulus3) >= timeNow) then Map.add(eventResponse2, 3, default(stimulus3, -1)) else eventResponse2
def eventResponse4:= if (defaultTime(stimulus4) >= timeNow) then Map.add(eventResponse3, 4, default(stimulus4, -1)) else eventResponse3
inputSynchronizationConstraintReset(eventResponse4, 4, tolerance, resetTime)
}
inputSynchronizationConstraintReset5(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for five stimulus streams.
resets a negative output and invalid state after resetTime
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraintReset5(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int):
Events[fourValuedLogicValue] :={
def timeNow =
merge(time(stimulus1),
merge(time(stimulus2),
merge(time(stimulus3),
merge(time(stimulus4),
merge(time(stimulus5),
time(response))))))
def eventStimulus:= if (defaultTime(response) >= timeNow) then Map.add(Map.empty[Int, Int], 0, default(response, -1)) else Map.empty[Int, Int]
def eventResponse1:= if (defaultTime(stimulus1) >= timeNow) then Map.add(eventStimulus, 1, default(stimulus1, -1)) else eventStimulus
def eventResponse2:= if (defaultTime(stimulus2) >= timeNow) then Map.add(eventResponse1, 2, default(stimulus2, -1)) else eventResponse1
def eventResponse3:= if (defaultTime(stimulus3) >= timeNow) then Map.add(eventResponse2, 3, default(stimulus3, -1)) else eventResponse2
def eventResponse4:= if (defaultTime(stimulus4) >= timeNow) then Map.add(eventResponse3, 4, default(stimulus4, -1)) else eventResponse3
def eventResponse5:= if (defaultTime(stimulus5) >= timeNow) then Map.add(eventResponse4, 5, default(stimulus5, -1)) else eventResponse4
inputSynchronizationConstraintReset(eventResponse5, 5, tolerance, resetTime)
}
inputSynchronizationConstraintReset6(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for six stimulus streams.
resets a negative output and invalid state after resetTime
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraintReset6(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], response: Events[Int],
tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus1),
merge(time(stimulus2),
merge(time(stimulus3),
merge(time(stimulus4),
merge(time(stimulus5),
merge(time(stimulus6),
time(response)))))))
def eventStimulus:= if (defaultTime(response) >= timeNow) then Map.add(Map.empty[Int, Int], 0, default(response, -1)) else Map.empty[Int, Int]
def eventResponse1:= if (defaultTime(stimulus1) >= timeNow) then Map.add(eventStimulus, 1, default(stimulus1, -1)) else eventStimulus
def eventResponse2:= if (defaultTime(stimulus2) >= timeNow) then Map.add(eventResponse1, 2, default(stimulus2, -1)) else eventResponse1
def eventResponse3:= if (defaultTime(stimulus3) >= timeNow) then Map.add(eventResponse2, 3, default(stimulus3, -1)) else eventResponse2
def eventResponse4:= if (defaultTime(stimulus4) >= timeNow) then Map.add(eventResponse3, 4, default(stimulus4, -1)) else eventResponse3
def eventResponse5:= if (defaultTime(stimulus5) >= timeNow) then Map.add(eventResponse4, 5, default(stimulus5, -1)) else eventResponse4
def eventResponse6:= if (defaultTime(stimulus6) >= timeNow) then Map.add(eventResponse5, 6, default(stimulus6, -1)) else eventResponse5
inputSynchronizationConstraintReset(eventResponse6, 6, tolerance, resetTime)
}
inputSynchronizationConstraintReset7(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for seven stimulus streams.
resets a negative output and invalid state after resetTime
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraintReset7(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int],
response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus1),
merge(time(stimulus2),
merge(time(stimulus3),
merge(time(stimulus4),
merge(time(stimulus5),
merge(time(stimulus6),
merge(time(stimulus7),
time(response))))))))
def eventStimulus:= if (defaultTime(response) >= timeNow) then Map.add(Map.empty[Int, Int], 0, default(response, -1)) else Map.empty[Int, Int]
def eventResponse1:= if (defaultTime(stimulus1) >= timeNow) then Map.add(eventStimulus, 1, default(stimulus1, -1)) else eventStimulus
def eventResponse2:= if (defaultTime(stimulus2) >= timeNow) then Map.add(eventResponse1, 2, default(stimulus2, -1)) else eventResponse1
def eventResponse3:= if (defaultTime(stimulus3) >= timeNow) then Map.add(eventResponse2, 3, default(stimulus3, -1)) else eventResponse2
def eventResponse4:= if (defaultTime(stimulus4) >= timeNow) then Map.add(eventResponse3, 4, default(stimulus4, -1)) else eventResponse3
def eventResponse5:= if (defaultTime(stimulus5) >= timeNow) then Map.add(eventResponse4, 5, default(stimulus5, -1)) else eventResponse4
def eventResponse6:= if (defaultTime(stimulus6) >= timeNow) then Map.add(eventResponse5, 6, default(stimulus6, -1)) else eventResponse5
def eventResponse7:= if (defaultTime(stimulus7) >= timeNow) then Map.add(eventResponse6, 7, default(stimulus7, -1)) else eventResponse6
inputSynchronizationConstraintReset(eventResponse7, 7, tolerance, resetTime)
}
inputSynchronizationConstraintReset8(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int], stimulus8: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for eight stimulus streams.
resets a negative output and invalid state after resetTime
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraintReset8(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int],
stimulus8: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus1),
merge(time(stimulus2),
merge(time(stimulus3),
merge(time(stimulus4),
merge(time(stimulus5),
merge(time(stimulus6),
merge(time(stimulus7),
merge(time(stimulus8),
time(response)))))))))
def eventStimulus:= if (defaultTime(response) >= timeNow) then Map.add(Map.empty[Int, Int], 0, default(response, -1)) else Map.empty[Int, Int]
def eventResponse1:= if (defaultTime(stimulus1) >= timeNow) then Map.add(eventStimulus, 1, default(stimulus1, -1)) else eventStimulus
def eventResponse2:= if (defaultTime(stimulus2) >= timeNow) then Map.add(eventResponse1, 2, default(stimulus2, -1)) else eventResponse1
def eventResponse3:= if (defaultTime(stimulus3) >= timeNow) then Map.add(eventResponse2, 3, default(stimulus3, -1)) else eventResponse2
def eventResponse4:= if (defaultTime(stimulus4) >= timeNow) then Map.add(eventResponse3, 4, default(stimulus4, -1)) else eventResponse3
def eventResponse5:= if (defaultTime(stimulus5) >= timeNow) then Map.add(eventResponse4, 5, default(stimulus5, -1)) else eventResponse4
def eventResponse6:= if (defaultTime(stimulus6) >= timeNow) then Map.add(eventResponse5, 6, default(stimulus6, -1)) else eventResponse5
def eventResponse7:= if (defaultTime(stimulus7) >= timeNow) then Map.add(eventResponse6, 7, default(stimulus7, -1)) else eventResponse6
def eventResponse8:= if (defaultTime(stimulus8) >= timeNow) then Map.add(eventResponse7, 8, default(stimulus8, -1)) else eventResponse7
inputSynchronizationConstraintReset(eventResponse8, 8, tolerance, resetTime)
}
inputSynchronizationConstraintReset9(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int], stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int], stimulus8: Events[Int], stimulus9: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the InputSynchronizationConstraint for nine stimulus streams.
resets a negative output and invalid state after resetTime
See InputSynchronizationConstraint
for further information.
def inputSynchronizationConstraintReset9(stimulus1: Events[Int], stimulus2: Events[Int], stimulus3: Events[Int],
stimulus4: Events[Int], stimulus5: Events[Int], stimulus6: Events[Int], stimulus7: Events[Int],
stimulus8: Events[Int], stimulus9: Events[Int], response: Events[Int], tolerance: Int, resetTime: Int):
Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus1),
merge(time(stimulus2),
merge(time(stimulus3),
merge(time(stimulus4),
merge(time(stimulus5),
merge(time(stimulus6),
merge(time(stimulus7),
merge(time(stimulus8),
merge(time(stimulus9),
time(response))))))))))
def eventStimulus:= if (defaultTime(response) >= timeNow) then Map.add(Map.empty[Int, Int], 0, default(response, -1)) else Map.empty[Int, Int]
def eventResponse1:= if (defaultTime(stimulus1) >= timeNow) then Map.add(eventStimulus, 1, default(stimulus1, -1)) else eventStimulus
def eventResponse2:= if (defaultTime(stimulus2) >= timeNow) then Map.add(eventResponse1, 2, default(stimulus2, -1)) else eventResponse1
def eventResponse3:= if (defaultTime(stimulus3) >= timeNow) then Map.add(eventResponse2, 3, default(stimulus3, -1)) else eventResponse2
def eventResponse4:= if (defaultTime(stimulus4) >= timeNow) then Map.add(eventResponse3, 4, default(stimulus4, -1)) else eventResponse3
def eventResponse5:= if (defaultTime(stimulus5) >= timeNow) then Map.add(eventResponse4, 5, default(stimulus5, -1)) else eventResponse4
def eventResponse6:= if (defaultTime(stimulus6) >= timeNow) then Map.add(eventResponse5, 6, default(stimulus6, -1)) else eventResponse5
def eventResponse7:= if (defaultTime(stimulus7) >= timeNow) then Map.add(eventResponse6, 7, default(stimulus7, -1)) else eventResponse6
def eventResponse8:= if (defaultTime(stimulus8) >= timeNow) then Map.add(eventResponse7, 8, default(stimulus8, -1)) else eventResponse7
def eventResponse9:= if (defaultTime(stimulus9) >= timeNow) then Map.add(eventResponse8, 9, default(stimulus9, -1)) else eventResponse8
inputSynchronizationConstraintReset(eventResponse9, 9, tolerance, resetTime)
}
orderConstraint[A, B](source: Events[A], target: Events[B]): Events[fourValuedLogicValue]
Checks the OrderConstraint defined in TADL2.
The order Constraint that the ith target event must occur after the ith source event.
Usage Example
in source: Events[Unit]
in target: Events[Unit]
def constraint= TADL2.orderConstraint(source, target)
out constraint.value
out constraint.final
Trace Example
option timeDomain:[-1,50]
1: source
1: constraint.value = false
1: constraint.final = false
2: target
2: constraint.value = true
2: constraint.final = false
5: source
5: constraint.value = false
5: constraint.final = false
6: source
6: constraint.value = false
6: constraint.final = false
20: target
20: constraint.value = false
20: constraint.final = false
40: target
40: constraint.value = true
40: constraint.final = false
def orderConstraint[A, B](source: Events[A], target: Events[B]): Events[fourValuedLogicValue] :=
orderConstraintReset(source, target, pseudoInfty)
orderConstraintReset[A, B](source: Events[A], target: Events[B], resetTime: Int): Events[fourValuedLogicValue]
Checks the OrderConstraint defined in TADL2.
Resets a negative output after resetTime.
See orderConstraint
for more information.
def orderConstraintReset[A, B](source: Events[A], target: Events[B], resetTime: Int):
Events[fourValuedLogicValue] := {
# next timestamp after 'falling flank'
def failingTimeStamps: Events[Unit] =
filter(mergeUnit(source, target), last(result.final, mergeUnit(source, target)) &&
!(last(last(result.final, mergeUnit(source, target)), mergeUnit(source, target))))
#timestamps, in which the state of the monitor is resetted
def resets: Events[Unit]=
delay(const(resetTime, failingTimeStamps)-(time(mergeUnit(source, target)) -
prev(time(mergeUnit(source, target)))),
failingTimeStamps)
#reset count for both streams
def sourceCount: Events[Int] = resetCount2(source, resets)
def targetCount: Events[Int] = resetCount2(target, resets)
def result := stillFulfillableReset(
#number of events on both streams equal-> currently true
if sourceCount == targetCount then
if (defaultTime(source) == defaultTime(target) && defaultTime(source) != -1) then
{value= false, final= true}
else
{value= true, final= false}
else
# more source than target events-> currently false
if (sourceCount >= targetCount) then
{value= false, final= false}
else
# more target than source events-> false
{value= false, final= true},
resetTime)
#output
result
}
outputSynchronizationConstraint10(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int], response7: Events[Int], response8: Events[Int], response9: Events[Int], response10: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for ten streams.
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraint10(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int],
response7: Events[Int], response8: Events[Int], response9: Events[Int], response10: Events[Int],
tolerance: Int): Events[fourValuedLogicValue] :=
outputSynchronizationConstraintReset10(stimulus, response1, response2, response3, response4, response5,
response6, response7, response8, response9, response10, tolerance, pseudoInfty)
outputSynchronizationConstraint2(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for two streams.
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraint2(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
tolerance: Int): Events[fourValuedLogicValue] :=
outputSynchronizationConstraintReset2(stimulus, response1, response2, tolerance, pseudoInfty)
outputSynchronizationConstraint3(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for three streams.
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraint3(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], tolerance: Int): Events[fourValuedLogicValue] :=
outputSynchronizationConstraintReset3(stimulus, response1, response2, response3, tolerance, pseudoInfty)
outputSynchronizationConstraint4(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for four streams.
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraint4(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], tolerance: Int): Events[fourValuedLogicValue] :=
outputSynchronizationConstraintReset4(stimulus, response1, response2, response3, response4, tolerance,
pseudoInfty)
outputSynchronizationConstraint5(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for five streams.
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraint5(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], tolerance: Int):
Events[fourValuedLogicValue] :=
outputSynchronizationConstraintReset5(stimulus, response1, response2, response3, response4, response5,
tolerance, pseudoInfty)
outputSynchronizationConstraint6(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for six streams.
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraint6(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int],
tolerance: Int): Events[fourValuedLogicValue] :=
outputSynchronizationConstraintReset6(stimulus, response1, response2, response3, response4, response5,
response6, tolerance, pseudoInfty)
outputSynchronizationConstraint7(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int], response7: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for seven streams.
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraint7(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int],
response7: Events[Int], tolerance: Int): Events[fourValuedLogicValue] :=
outputSynchronizationConstraintReset7(stimulus, response1, response2, response3, response4, response5,
response6, response7, tolerance, pseudoInfty)
outputSynchronizationConstraint8(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int], response7: Events[Int], response8: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for eight streams.
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraint8(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int],
response7: Events[Int], response8: Events[Int], tolerance: Int): Events[fourValuedLogicValue] :=
outputSynchronizationConstraintReset8(stimulus, response1, response2, response3, response4, response5,
response6, response7, response8, tolerance, pseudoInfty)
outputSynchronizationConstraint9(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int], response7: Events[Int], response8: Events[Int], response9: Events[Int], tolerance: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for nine streams.
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraint9(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int],
response7: Events[Int], response8: Events[Int], response9: Events[Int], tolerance: Int):
Events[fourValuedLogicValue] :=
outputSynchronizationConstraintReset9(stimulus, response1, response2, response3, response4, response5,
response6, response7, response8, response9, tolerance, pseudoInfty)
outputSynchronizationConstraintReset(eventStreamIndices: Events[Map[Int, Int]], responseStreamCount: Int, tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint defined in TADL2.
In the OutputSynchronizationConstraint, there must be one synchronization cluster of the length tolerance for each stimulus event. Each response stream must have at least one event of the same color as the stimulus event in this cluster. A stream of maps must be created, representing the events of each timestamp. The key of each entry is the index of the stream (0 for the stimulus stream, 1, 2, … for the response streams), in which the event occurred and the value is the color of the event. The creation of this map is already implemented for up to 10 response streams, see outputSynchronizationConstraint2, … . The source code expects the colors of the streams to fulfill the correctness of event chain. See checkEventChain to check this.
A negative output and invalid state is reset after resetTime.
Usage Example
in stimulus: Events[Int]
in response1: Events[Int]
in response2: Events[Int]
in response3: Events[Int]
def tolerance = 2
def constraint= TADL2.outputSynchronizationConstraint3(stimulus, response1, response2, response3, tolerance)
out constraint.value
out constraint.final
Trace Example
option timeDomain:[-1,20]
1: stimulus = 1
1: constraint.value = false
1: constraint.final = false
5: response1 = 1
5: response2 = 1
5: constraint.value = false
5: constraint.final = false
6: response3 = 1
6: constraint.value = true
6: constraint.final = false
11: stimulus = 2
11: constraint.value = false
11: constraint.final = false
12: stimulus = 3
12: constraint.value = false
12: constraint.final = false
15: response1= 2
15: response2= 3
15: response3= 2
15: constraint.value = false
15: constraint.final = false
16: response1= 3
16: response2= 2
16: response3= 3
16: constraint.value = true
16: constraint.final = false
def outputSynchronizationConstraintReset(eventStreamIndices: Events[Map[Int, Int]],
responseStreamCount: Int, tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:= {
##### Help funtions #####
# add an empty cluster to storedClusters
def addNewCluster(storedClusters: Map[Int, outputSynchronizationCluster], newColor: Int, time: Int,
responseStreamCount: Int): Map[Int, outputSynchronizationCluster] :=
Map.add(storedClusters, newColor, buildOutputSynchronizationCluster(time, responseStreamCount))
#removes every entry of listToRemove from the given set
liftable def removeListFromSet[A](aSet: Set[A], listToRemove: List[A]): Set[A]:=
if (List.size(listToRemove) == 0) then
aSet
else
removeListFromSet(
if (Set.contains(aSet, List.head(listToRemove))) then
Set.remove(aSet, List.head(listToRemove))
else
aSet,
List.tail(listToRemove))
# build list from aMap with all keys given in remainingKeys
liftable def mapValuesToList[A, B](aMap: Map[A, B], remainingKeys: List[A]): List[B]:=
if List.size(remainingKeys) == 0 then
List.empty[B]
else
List.append(mapValuesToList(aMap, List.tail(remainingKeys)),
Map.get(aMap, List.head(remainingKeys)))
# removes map entries with key = 0
liftable def removeStimulusEvents(events: Map[Int, Int]): Map[Int, Int] :=
if (Map.contains(events, 0)) then
Map.remove(events, 0)
else
events
#updates the stored synchronization clusters by all events in this timestamp (update or creation of new cluster)
def updateSynchronizationClusters(storedClusters: Map[Int, outputSynchronizationCluster], events: Map[Int, Int],
eventKeys: List[Int], unmatchedStimulusColors: Set[Int], timeNow: Int):
Map[Int, outputSynchronizationCluster] := {
# set the given stream in cluster to true
def setStreamInSynchronizationCluster(cluster: outputSynchronizationCluster, stream: Int):
outputSynchronizationCluster = {
startTime = cluster.startTime,
fulfilledStreams = Map.add(cluster.fulfilledStreams, stream, true)
}
if List.size(eventKeys) == 0 then
storedClusters
else
updateSynchronizationClusters(
# set stream to fulfilled in Cluster
if (Map.contains(storedClusters, Map.get(events, List.head(eventKeys))) ||
Set.contains(unmatchedStimulusColors, Map.get(events, List.head(eventKeys)))) then
Map.add(storedClusters, Map.get(events, List.head(eventKeys)),
setStreamInSynchronizationCluster(
Map.get(
# add new cluster, if needed
if ((!Map.contains(storedClusters, Map.get(events, List.head(eventKeys)))) &&
Set.contains(unmatchedStimulusColors, Map.get(events, List.head(eventKeys)))) then
addNewCluster(storedClusters,
Map.get(events, List.head(eventKeys)), timeNow, responseStreamCount)
else
storedClusters,
Map.get(events, List.head(eventKeys))),
List.head(eventKeys)))
else
storedClusters,
events, List.tail(eventKeys), unmatchedStimulusColors, timeNow)
}
# check, if all streams are fulfilled in this cluster. Ignores timing
def clusterFulfilled(fulfilledStreams: Map[Int, Bool], keys: List[Int]): Bool :=
if (List.size(keys) == 0) then
true
else
if (Map.get(fulfilledStreams, List.head(keys))) then
clusterFulfilled(fulfilledStreams, List.tail(keys))
else
false
# searches for all fulfilled clusters in Map and returns their colors in a list
# storedClusters: Map with stored clusters (color -> cluster)
liftable def fulfilledClustersInMapRec(storedClusters: Map[Int, outputSynchronizationCluster], aList: List[Int],
keys: List[Int]): List[Int] :=
if (List.size(keys) == 0) then
aList
else
fulfilledClustersInMapRec(storedClusters,
if (clusterFulfilled(Map.get(storedClusters, List.head(keys)).fulfilledStreams,
Map.keys(Map.get(storedClusters, List.head(keys)).fulfilledStreams))) then
List.append(aList, List.head(keys))
else
aList, List.tail(keys))
# searches for all fulfilled clusters in Map and returns their colors in a list
# storedClusters: Map with stored clusters (color -> cluster)
liftable def fulfilledClustersInMap(storedClusters: Map[Int, outputSynchronizationCluster]): List[Int] :=
fulfilledClustersInMapRec(storedClusters, List.empty[Int], Map.keys(storedClusters))
#removes clusters from Map
def removeClusters(storedClusters: Map[Int, outputSynchronizationCluster], colorsToRemove: List[Int]):
Map[Int, outputSynchronizationCluster] :=
if (List.size(colorsToRemove) == 0) then
storedClusters
else
removeClusters(Map.remove(storedClusters, List.head(colorsToRemove)), List.tail(colorsToRemove))
liftable def startTimeOldestCluster(storedClustersBeforeRemove: Map[Int, outputSynchronizationCluster],
keys: List[Int]): Int :=
if (List.size(keys) == 0) then
pseudoInfty-tolerance
else
min(Map.get(storedClustersBeforeRemove, List.head(keys)).startTime,
startTimeOldestCluster(storedClustersBeforeRemove, List.tail(keys)))
# Stored Information #
#stimulus colors without matching target event
def unmatchedStimulusColors: Events[Set[Int]] :=
removeListFromSet(
if (Map.contains(eventStreamIndices, 0)) then
Set.add(default(last(unmatchedStimulusColors, eventStreamIndices), Set.empty[Int]),
Map.get(eventStreamIndices, 0))
else
default(last(unmatchedStimulusColors, eventStreamIndices), Set.empty[Int]),
mapValuesToList(removeStimulusEvents(eventStreamIndices), Map.keys(removeStimulusEvents(eventStreamIndices))))
# synchronization clusters with new stimulus events
def storedClustersBeforeRemove : Events[Map[Int, outputSynchronizationCluster]] :=
merge(slift5(last(storedClusters, time(eventStreamIndices)), removeStimulusEvents(eventStreamIndices),
Map.keys(removeStimulusEvents(eventStreamIndices)), prev(unmatchedStimulusColors),
time(eventStreamIndices), updateSynchronizationClusters),
Map.empty[Int, outputSynchronizationCluster])
# stored clusters after removing the clusters, which were fulfilled in this timestamp
def storedClusters: Events[Map[Int, outputSynchronizationCluster]] :=
merge(on(resets, Map.empty[Int, outputSynchronizationCluster]),
merge(slift(storedClustersBeforeRemove, slift1(storedClustersBeforeRemove, fulfilledClustersInMap),
removeClusters),
Map.empty[Int, outputSynchronizationCluster]))
# timestamps, in which the evaluation occurs
def evalTimes = time(mergeUnit(eventStreamIndices,
TADL2.safeDelay(slift(storedClusters,
Map.keys(storedClusters), startTimeOldestCluster) + tolerance - time(eventStreamIndices) + 1,
eventStreamIndices)))
# next timestamp after 'falling flank'
def failingTimeStamps: Events[Unit] =
filter(const((), eventStreamIndices), last(result.final, eventStreamIndices) &&
!(last(last(result.final, eventStreamIndices), eventStreamIndices)))
#timestamps, in which the state of the monitor is resetted
def resets: Events[Unit]=
delay(if (const(resetTime, failingTimeStamps)-(time(eventStreamIndices) - prev(time(eventStreamIndices))) > 0) then
const(resetTime, failingTimeStamps)-(time(eventStreamIndices) - prev(time(eventStreamIndices))) else 1,
failingTimeStamps)
#no unfinished synchronization clusters and no unmatched Stimulus colors
def result:=
TADL2.stillFulfillableReset(
if (Set.size(unmatchedStimulusColors) == 0 && Map.size(storedClusters) == 0) then
{value= true, final= false}
else
# unfulfilled stimulus colors exist, all clusters are still fulfillable-> current false
if startTimeOldestCluster(storedClusters, Map.keys(storedClusters)) + tolerance > evalTimes then
{value= false, final= false}
else
{value= false, final= true},
resetTime)
#output
result
}
outputSynchronizationConstraintReset10(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int], response7: Events[Int], response8: Events[Int], response9: Events[Int], response10: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for ten response streams.
resets a negative output and an invalid state after resetTime
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraintReset10(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int],
response7: Events[Int], response8: Events[Int], response9: Events[Int], response10: Events[Int],
tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus),
merge(time(response1),
merge(time(response2),
merge(time(response3),
merge(time(response4),
merge(time(response5),
merge(time(response6),
merge(time(response7),
merge(time(response8),
merge(time(response9),
time(response10)))))))))))
def eventStimulus:=
if (defaultTime(stimulus) >= timeNow) then
Map.add(Map.empty[Int, Int], 0, default(stimulus, -1))
else
Map.empty[Int, Int]
def eventResponse1:=
if (defaultTime(response1) >= timeNow) then
Map.add(eventStimulus, 1, default(response1, -1))
else
eventStimulus
def eventResponse2:=
if (defaultTime(response2) >= timeNow) then
Map.add(eventResponse1, 2, default(response2, -1))
else
eventResponse1
def eventResponse3:=
if (defaultTime(response3) >= timeNow) then
Map.add(eventResponse2, 3, default(response3, -1))
else
eventResponse2
def eventResponse4:=
if (defaultTime(response4) >= timeNow) then
Map.add(eventResponse3, 4, default(response4, -1))
else
eventResponse3
def eventResponse5:=
if (defaultTime(response5) >= timeNow) then
Map.add(eventResponse4, 5, default(response5, -1))
else
eventResponse4
def eventResponse6:=
if (defaultTime(response6) >= timeNow) then
Map.add(eventResponse5, 6, default(response6, -1))
else
eventResponse5
def eventResponse7:=
if (defaultTime(response7) >= timeNow) then
Map.add(eventResponse6, 7, default(response7, -1))
else
eventResponse6
def eventResponse8:=
if (defaultTime(response8) >= timeNow) then
Map.add(eventResponse7, 8, default(response8, -1))
else
eventResponse7
def eventResponse9:=
if (defaultTime(response9) >= timeNow) then
Map.add(eventResponse8, 9, default(response9, -1))
else
eventResponse8
def eventResponse10:=
if (defaultTime(response10) >= timeNow) then
Map.add(eventResponse9, 10, default(response10, -1))
else
eventResponse9
outputSynchronizationConstraintReset(eventResponse10, 10, tolerance, resetTime)
}
outputSynchronizationConstraintReset2(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for two streams.
resets a negative output and an invalid state after resetTime
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraintReset2(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus),
merge(time(response1),
(time(response2))))
def eventStimulus:=
if (defaultTime(stimulus) >= timeNow) then
Map.add(Map.empty[Int, Int], 0, default(stimulus, -1))
else
Map.empty[Int, Int]
def eventResponse1:=
if (defaultTime(response1) >= timeNow) then
Map.add(eventStimulus, 1, default(response1, -1))
else
eventStimulus
def eventResponse2:=
if (defaultTime(response2) >= timeNow) then
Map.add(eventResponse1, 2, default(response2, -1))
else
eventResponse1
outputSynchronizationConstraintReset(eventResponse2, 2, tolerance, resetTime)
}
outputSynchronizationConstraintReset3(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for three response streams.
resets a negative output and an invalid state after resetTime
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraintReset3(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus),
merge(time(response1),
merge(time(response2),
time(response3))))
def eventStimulus:=
if (defaultTime(stimulus) >= timeNow) then
Map.add(Map.empty[Int, Int], 0, default(stimulus, -1))
else
Map.empty[Int, Int]
def eventResponse1:=
if (defaultTime(response1) >= timeNow) then
Map.add(eventStimulus, 1, default(response1, -1))
else
eventStimulus
def eventResponse2:=
if (defaultTime(response2) >= timeNow) then
Map.add(eventResponse1, 2, default(response2, -1))
else
eventResponse1
def eventResponse3:=
if (defaultTime(response3) >= timeNow) then
Map.add(eventResponse2, 3, default(response3, -1))
else
eventResponse2
outputSynchronizationConstraintReset(eventResponse3, 3, tolerance, resetTime)
}
outputSynchronizationConstraintReset4(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for four response streams.
resets a negative output and an invalid state after resetTime
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraintReset4(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus),
merge(time(response1),
merge(time(response2),
merge(time(response3),
time(response4)))))
def eventStimulus:=
if (defaultTime(stimulus) >= timeNow) then
Map.add(Map.empty[Int, Int], 0, default(stimulus, -1))
else
Map.empty[Int, Int]
def eventResponse1:=
if (defaultTime(response1) >= timeNow) then
Map.add(eventStimulus, 1, default(response1, -1))
else
eventStimulus
def eventResponse2:=
if (defaultTime(response2) >= timeNow) then
Map.add(eventResponse1, 2, default(response2, -1))
else
eventResponse1
def eventResponse3:=
if (defaultTime(response3) >= timeNow) then
Map.add(eventResponse2, 3, default(response3, -1))
else
eventResponse2
def eventResponse4:=
if (defaultTime(response4) >= timeNow) then
Map.add(eventResponse3, 4, default(response4, -1))
else
eventResponse3
outputSynchronizationConstraintReset(eventResponse4, 4, tolerance, resetTime)
}
outputSynchronizationConstraintReset5(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for five response streams.
resets a negative output and an invalid state after resetTime
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraintReset5(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], tolerance: Int, resetTime: Int):
Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus),
merge(time(response1),
merge(time(response2),
merge(time(response3),
merge(time(response4),
time(response5))))))
def eventStimulus:=
if (defaultTime(stimulus) >= timeNow) then
Map.add(Map.empty[Int, Int], 0, default(stimulus, -1))
else
Map.empty[Int, Int]
def eventResponse1:=
if (defaultTime(response1) >= timeNow) then
Map.add(eventStimulus, 1, default(response1, -1))
else
eventStimulus
def eventResponse2:=
if (defaultTime(response2) >= timeNow) then
Map.add(eventResponse1, 2, default(response2, -1))
else
eventResponse1
def eventResponse3:=
if (defaultTime(response3) >= timeNow) then
Map.add(eventResponse2, 3, default(response3, -1))
else
eventResponse2
def eventResponse4:=
if (defaultTime(response4) >= timeNow) then
Map.add(eventResponse3, 4, default(response4, -1))
else
eventResponse3
def eventResponse5:=
if (defaultTime(response5) >= timeNow) then
Map.add(eventResponse4, 5, default(response5, -1))
else
eventResponse4
outputSynchronizationConstraintReset(eventResponse5, 5, tolerance, resetTime)
}
outputSynchronizationConstraintReset6(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for six response streams.
resets a negative output and an invalid state after resetTime
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraintReset6(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int],
tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus),
merge(time(response1),
merge(time(response2),
merge(time(response3),
merge(time(response4),
merge(time(response5),
time(response6)))))))
def eventStimulus:=
if (defaultTime(stimulus) >= timeNow) then
Map.add(Map.empty[Int, Int], 0, default(stimulus, -1))
else
Map.empty[Int, Int]
def eventResponse1:=
if (defaultTime(response1) >= timeNow) then
Map.add(eventStimulus, 1, default(response1, -1))
else
eventStimulus
def eventResponse2:=
if (defaultTime(response2) >= timeNow) then
Map.add(eventResponse1, 2, default(response2, -1))
else
eventResponse1
def eventResponse3:=
if (defaultTime(response3) >= timeNow) then
Map.add(eventResponse2, 3, default(response3, -1))
else
eventResponse2
def eventResponse4:=
if (defaultTime(response4) >= timeNow) then
Map.add(eventResponse3, 4, default(response4, -1))
else
eventResponse3
def eventResponse5:=
if (defaultTime(response5) >= timeNow) then
Map.add(eventResponse4, 5, default(response5, -1))
else
eventResponse4
def eventResponse6:=
if (defaultTime(response6) >= timeNow) then
Map.add(eventResponse5, 6, default(response6, -1))
else
eventResponse5
outputSynchronizationConstraintReset(eventResponse6, 6, tolerance, resetTime)
}
outputSynchronizationConstraintReset7(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int], response7: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for seven response streams.
resets a negative output and an invalid state after resetTime
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraintReset7(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int],
response7: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus),
merge(time(response1),
merge(time(response2),
merge(time(response3),
merge(time(response4),
merge(time(response5),
merge(time(response6),
time(response7))))))))
def eventStimulus:=
if (defaultTime(stimulus) >= timeNow) then
Map.add(Map.empty[Int, Int], 0, default(stimulus, -1))
else
Map.empty[Int, Int]
def eventResponse1:=
if (defaultTime(response1) >= timeNow) then
Map.add(eventStimulus, 1, default(response1, -1))
else
eventStimulus
def eventResponse2:=
if (defaultTime(response2) >= timeNow) then
Map.add(eventResponse1, 2, default(response2, -1))
else
eventResponse1
def eventResponse3:=
if (defaultTime(response3) >= timeNow) then
Map.add(eventResponse2, 3, default(response3, -1))
else
eventResponse2
def eventResponse4:=
if (defaultTime(response4) >= timeNow) then
Map.add(eventResponse3, 4, default(response4, -1))
else
eventResponse3
def eventResponse5:=
if (defaultTime(response5) >= timeNow) then
Map.add(eventResponse4, 5, default(response5, -1))
else
eventResponse4
def eventResponse6:=
if (defaultTime(response6) >= timeNow) then
Map.add(eventResponse5, 6, default(response6, -1))
else
eventResponse5
def eventResponse7:=
if (defaultTime(response7) >= timeNow) then
Map.add(eventResponse6, 7, default(response7, -1))
else
eventResponse6
outputSynchronizationConstraintReset(eventResponse7, 7, tolerance, resetTime)
}
outputSynchronizationConstraintReset8(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int], response7: Events[Int], response8: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for eight response streams.
resets a negative output and an invalid state after resetTime
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraintReset8(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int],
response7: Events[Int], response8: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus),
merge(time(response1),
merge(time(response2),
merge(time(response3),
merge(time(response4),
merge(time(response5),
merge(time(response6),
merge(time(response7),
time(response8)))))))))
def eventStimulus:=
if (defaultTime(stimulus) >= timeNow) then
Map.add(Map.empty[Int, Int], 0, default(stimulus, -1))
else
Map.empty[Int, Int]
def eventResponse1:=
if (defaultTime(response1) >= timeNow) then
Map.add(eventStimulus, 1, default(response1, -1))
else
eventStimulus
def eventResponse2:=
if (defaultTime(response2) >= timeNow) then
Map.add(eventResponse1, 2, default(response2, -1))
else
eventResponse1
def eventResponse3:=
if (defaultTime(response3) >= timeNow) then
Map.add(eventResponse2, 3, default(response3, -1))
else
eventResponse2
def eventResponse4:=
if (defaultTime(response4) >= timeNow) then
Map.add(eventResponse3, 4, default(response4, -1))
else
eventResponse3
def eventResponse5:=
if (defaultTime(response5) >= timeNow) then
Map.add(eventResponse4, 5, default(response5, -1))
else
eventResponse4
def eventResponse6:=
if (defaultTime(response6) >= timeNow) then
Map.add(eventResponse5, 6, default(response6, -1))
else
eventResponse5
def eventResponse7:=
if (defaultTime(response7) >= timeNow) then
Map.add(eventResponse6, 7, default(response7, -1))
else
eventResponse6
def eventResponse8:=
if (defaultTime(response8) >= timeNow) then
Map.add(eventResponse7, 8, default(response8, -1))
else
eventResponse7
outputSynchronizationConstraintReset(eventResponse8, 8, tolerance, resetTime)
}
outputSynchronizationConstraintReset9(stimulus: Events[Int], response1: Events[Int], response2: Events[Int], response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int], response7: Events[Int], response8: Events[Int], response9: Events[Int], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the OutputSynchronizationConstraint for nine response streams.
resets a negative output and an invalid state after resetTime
See OutputSynchronizationConstraint
for further information.
def outputSynchronizationConstraintReset9(stimulus: Events[Int], response1: Events[Int], response2: Events[Int],
response3: Events[Int], response4: Events[Int], response5: Events[Int], response6: Events[Int],
response7: Events[Int], response8: Events[Int], response9: Events[Int], tolerance: Int, resetTime: Int):
Events[fourValuedLogicValue] := {
def timeNow =
merge(time(stimulus),
merge(time(response1),
merge(time(response2),
merge(time(response3),
merge(time(response4),
merge(time(response5),
merge(time(response6),
merge(time(response7),
merge(time(response8),
time(response9))))))))))
def eventStimulus:=
if (defaultTime(stimulus) >= timeNow) then
Map.add(Map.empty[Int, Int], 0, default(stimulus, -1))
else
Map.empty[Int, Int]
def eventResponse1:=
if (defaultTime(response1) >= timeNow) then
Map.add(eventStimulus, 1, default(response1, -1))
else
eventStimulus
def eventResponse2:=
if (defaultTime(response2) >= timeNow) then
Map.add(eventResponse1, 2, default(response2, -1))
else
eventResponse1
def eventResponse3:=
if (defaultTime(response3) >= timeNow) then
Map.add(eventResponse2, 3, default(response3, -1))
else
eventResponse2
def eventResponse4:=
if (defaultTime(response4) >= timeNow) then
Map.add(eventResponse3, 4, default(response4, -1))
else
eventResponse3
def eventResponse5:=
if (defaultTime(response5) >= timeNow) then
Map.add(eventResponse4, 5, default(response5, -1))
else
eventResponse4
def eventResponse6:=
if (defaultTime(response6) >= timeNow) then
Map.add(eventResponse5, 6, default(response6, -1))
else
eventResponse5
def eventResponse7:=
if (defaultTime(response7) >= timeNow) then
Map.add(eventResponse6, 7, default(response7, -1))
else
eventResponse6
def eventResponse8:=
if (defaultTime(response8) >= timeNow) then
Map.add(eventResponse7, 8, default(response8, -1))
else
eventResponse7
def eventResponse9:=
if (defaultTime(response9) >= timeNow) then
Map.add(eventResponse8, 9, default(response9, -1))
else
eventResponse8
outputSynchronizationConstraintReset(eventResponse9, 9, tolerance, resetTime)
}
patternConstraint[A](e: Events[A], periodX: Int, offset: Map[Int, Int], jitter: Int, minDist: Int): Events[fourValuedLogicValue]
Checks the patternConstraint defined in TADL2.
The PatternConstraint decribes periodic patterns, in which the events must occur. The events must occur in a pattern defined by the offset parameter, which is repeated after periodX timestamps. A deviation from these offsets can be allowed by the jitter parameter, while the minimal distance between subsequent events can be defined using the minDist parameter. The offsets must be given in a map, which keys are subsequent indices, with the offsets as values.
Usage Example
in event: Events[Unit]
def periodX = 20
def offset: Map[Int, Int] := Map.add(Map.add(Map.add(Map.empty[Int, Int], 0, 0), 1, 3), 2, 6)
def jitter = 1
def minDist = 0
def constraint:= TADL2.patternConstraint(event, periodX, offset, jitter, minDist)
out constraint.value
out constraint.final
Trace Example
10: event = ()
10: constraint.value = true
10: constraint.final = false
13: event = ()
13: constraint.value = true
13: constraint.final = false
16: event = ()
16: constraint.value = true
16: constraint.final = false
31: event = ()
31: constraint.value = true
31: constraint.final = false
33: event = ()
33: constraint.value = true
33: constraint.final = false
36: event = ()
36: constraint.value = true
36: constraint.final = false
50: event = ()
50: constraint.value = true
50: constraint.final = false
53: event = ()
53: constraint.value = true
53: constraint.final = false
57: event = ()
57: constraint.value = true
57: constraint.final = false
def patternConstraint[A](e: Events[A], periodX: Int, offset: Map[Int, Int], jitter: Int, minDist: Int) :
Events[fourValuedLogicValue] :=
patternConstraintReset(e, periodX, offset, jitter, minDist, pseudoInfty)
patternConstraintReset[A](e: Events[A], periodX: Int, offset: Map[Int, Int], jitter: Int, minDist: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the patternConstraint defined in TADL2.
resets a negative output after resetTime.
See patternConstraint
for more information.
def patternConstraintReset[A](e: Events[A], periodX: Int, offset: Map[Int, Int], jitter: Int,
minDist: Int, resetTime: Int) : Events[fourValuedLogicValue] := {
liftable def aModuloBOr1if1(a: Int, b: Int): Int:=
if b == 1 then 1 else a % b;
# lower bound for latest x
def lowerBoundX: Events[Int] :=
if (last(res, e).final) then
on(e, 0)
else
merge (
# increase by period and adjust by offset and jitter
if (aModuloBOr1if1(resetCount2(e, filter(e, last(res, e).final)), Map.size(offset))== 1 && !isFirst(e)) then
max(last(lowerBoundX, e) + periodX,
time(e) - Map.get(offset,
(resetCount2(e, filter(e, last(res, e).final))-1) % Map.size(offset))-jitter)
#adjust by offset and jitter
else
max(last(lowerBoundX, e),
time(e) - Map.get(offset,
(resetCount2(e, filter(e, last(res, e).final))-1) % Map.size(offset))-jitter),
time(e) - Map.get(offset, (resetCount2(e, filter(e, last(res, e).final))-1) % Map.size(offset)) - jitter)
# lower bound for latest x
def upperBoundX: Events[Int] :=
if (last(res, e).final) then
on(e, pseudoInfty)
else
merge (
# increase by period and adjust by offset and jitter
if (aModuloBOr1if1(resetCount2(e, filter(e, last(res, e).final)), Map.size(offset))== 1 && !isFirst(e)) then
min(last(upperBoundX, e) + periodX,
time(e) - Map.get(offset, (resetCount2(e, filter(e, last(res, e).final))-1) % Map.size(offset)))
else
# adjust by offset and jitter
min(last(upperBoundX, e),
time(e) - Map.get(offset, (resetCount2(e, filter(e, last(res, e).final))-1) % Map.size(offset))),
time(e) - Map.get(offset, (resetCount2(e, filter(e, last(res, e).final))-1) % Map.size(offset)))
# timestamps, in which the evaluation occurs
def evaluateTimes=
mergeUnit(e,
TADL2.safeDelay(upperBoundX + (if resetCount2(e, filter(e, last(res, e).final)) % Map.size(offset) == 0 then
periodX
else
0) +
Map.get(offset, resetCount2(e, filter(e, last(res, e).final)) % Map.size(offset)) + jitter - time(e) + 1, e))
#evaluation
def res: Events[fourValuedLogicValue]= TADL2.stillFulfillableReset(default(TADL2.fourValuedConjunction(
# distance to x is correct-> current true, false otherwise
if (lowerBoundX +
Map.get(offset, (resetCount2(e, filter(e, last(res, e).final))-1) % Map.size(offset)) <=
time(evaluateTimes) &&
time(evaluateTimes) <= upperBoundX +
Map.get(offset, (resetCount2(e, filter(e, last(res, e).final))-1) % Map.size(offset)) + jitter) then
{value= true, final= false}
else
{value= false, final= true},
TADL2.repeatConstraintReset(e, minDist, pseudoInfty, 1, resetTime)),
{final= false, value = true}), resetTime)
res
}
periodicConstraint[A](events: Events[A], period: Int, jitter: Int, minDist: Int)
Checks the PeriodicConstraint defined in TADL2.
The events occur in a periodic pattern with an allowed deviation of upper and a minimal distance of minDist.
Usage Example
in event: Events[Unit]
def period = 10
def jitter = 2
def minDist = 9
def constraint= TADL2.periodicConstraint(event, period, jitter, minDist)
out constraint.value
out constraint.final
Trace Example
5: event = ()
5: constraint.value = true
5: constraint.final = false
17: event = ()
17: constraint.value = true
17: constraint.final = false
26: event = ()
26: constraint.value = true
26: constraint.final = false
35: event = ()
35: constraint.value = true
35: constraint.final = false
47: event = ()
47: constraint.value = true
47: constraint.final = false
56: event = ()
56: constraint.value = true
56: constraint.final = false
65: event = ()
65: constraint.value = true
65: constraint.final = false
def periodicConstraint[A](events: Events[A], period: Int, jitter: Int, minDist: Int) :=
sporadicConstraint(events, period, period, jitter, minDist)
periodicConstraintReset[A](events: Events[A], period: Int, jitter: Int, minDist: Int, resetTime: Int)
Checks the PeriodicConstraint defined in TADL2. Resets a negative output after resetTime
See periodicConstraint
for more information.
def periodicConstraintReset[A](events: Events[A], period: Int, jitter: Int, minDist: Int, resetTime: Int) :=
sporadicConstraintReset(events, period, period, jitter, minDist, resetTime)
reactionConstraint(stimulus: Events[Int], response: Events[Int], minTimeDiff: Int, maxTimeDiff: Int): Events[fourValuedLogicValue]
Checks the ReactionConstraint defined in TADL2.
For each stimulus event on stimulus, there must be an reponse event of the same color in response in the given time distance after the stimulus event. The color attribute is represented as integer. The source code expects the colors of the streams to fulfill the correctness of event chain. See checkEventChain to check this.
Usage Example
in stimulus: Events[Int]
in response: Events[Int]
def minTimeDiff = 5
def maxTimeDiff = 5
def constraint= TADL2.reactionConstraintReset(stimulus, response, minTimeDiff, maxTimeDiff)
out constraint.value
out constraint.final
Trace Example
option timeDomain:[-1,25]
1: stimulus = 1
1: constraint.value = false
1: constraint.final = false
6: response = 1
6: constraint.value = true
6: constraint.final = false
8: response = 4
8: constraint.value = true
8: constraint.final = false
10: stimulus = 2
10: constraint.value = false
10: constraint.final = false
13: stimulus = 3
13: constraint.value = false
13: constraint.final = false
15: response = 2
15: constraint.value = false
15: constraint.final = false
18: response = 3
18: constraint.value = true
18: constraint.final = false
def reactionConstraint(stimulus: Events[Int], response: Events[Int], minTimeDiff: Int, maxTimeDiff: Int):
Events[fourValuedLogicValue] :=
reactionConstraintReset(stimulus, response, minTimeDiff, maxTimeDiff, pseudoInfty)
reactionConstraintReset(stimulus: Events[Int], response: Events[Int], minTimeDiff: Int, maxTimeDiff: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the ReactionConstraint defined in TADL2.
Any state that leads to a final negative answer is resetted after resetTime.
See reactionConstraint
for more information.
def reactionConstraintReset(stimulus: Events[Int], response: Events[Int], minTimeDiff: Int,
maxTimeDiff: Int, resetTime: Int): Events[fourValuedLogicValue] := {
# Map with unmatched stimulus events after stimulus (color->timestamp)
def unmatchedStimulusEventsNewStimulus : Events[Map[Int, Int]]:= merge(
if defaultTime(stimulus) >= defaultTime(response) &&
!Map.contains(last(unmatchedStimulusEvents, merge(stimulus, response)), stimulus) then
Map.add(last(unmatchedStimulusEvents, merge(stimulus, response)), stimulus, defaultTime(stimulus))
else
last(unmatchedStimulusEvents, merge(stimulus, response)),
Map.empty[Int, Int])
def unmatchedStimulusEventsRemoveReset: Events[Map[Int, Int]]:=
default(
removeEventsAfterReset(unmatchedStimulusEventsNewStimulus,
Map.keys(unmatchedStimulusEventsNewStimulus),
time(mergeUnit(stimulus, response)),
resetTime),
Map.empty[Int, Int])
# Map with unmatched stimulus events after response
def unmatchedStimulusEvents := merge (
if (defaultTime(stimulus) <= defaultTime(response) &&
Map.contains(unmatchedStimulusEventsRemoveReset, merge(response, -1)) &&
Map.get(unmatchedStimulusEventsRemoveReset, merge(response, -1)) + minTimeDiff <=
defaultTime(response) &&
Map.get(unmatchedStimulusEventsRemoveReset, merge(response, -1)) + maxTimeDiff >=
defaultTime(response)) then
Map.remove(unmatchedStimulusEventsRemoveReset, response)
else
unmatchedStimulusEventsRemoveReset,
unmatchedStimulusEventsRemoveReset)
# timestamps, in which the evaluation occurs
def evaluateTimes = mergeUnit(mergeUnit(stimulus, response),
safeDelay(slift1(unmatchedStimulusEvents, mapMinimumValue) + maxTimeDiff -
time(mergeUnit(stimulus, response)) + 1,
mergeUnit(stimulus, response)))
#evaluation
# no unmatched stimulus events-> currently true
stillFulfillableReset(if (Map.size(unmatchedStimulusEvents) == 0) then
{value= true, final= false}
else
# all unmatched stimulus events can still be matched-> currently false
if (slift1(unmatchedStimulusEvents, mapMinimumValue) + maxTimeDiff >= time(evaluateTimes)) then
{value= false, final= false}
else
{value= false, final= true}, resetTime)
}
repeatConstraint[A](e: Events[A], lower: Int, upper: Int, span: Int): Events[fourValuedLogicValue]
Checks the RepeatConstraint defined in TADL2.
The events are repeating with distances between lower and upper. The parameter span defines overlaps of repetitions. (no overlaps: span=1, one overlap: span=2,…)
Usage Example
in event: Events[Unit]
def lower = 20
def upper = 20
def span = 2
def constraint:= TADL2.repeatConstraint(event, lower, upper, span)
out constraint.value
out constraint.final
Trace Example
5: event = ()
5: constraint.value = true
5: constraint.final = false
7: event = ()
7: constraint.value = true
7: constraint.final = false
25: event = ()
25: constraint.value = true
25: constraint.final = false
27: event = ()
27: constraint.value = true
27: constraint.final = false
45: event = ()
45: constraint.value = true
45: constraint.final = false
47: event = ()
47: constraint.value = true
47: constraint.final = false
def repeatConstraint[A](e: Events[A], lower: Int, upper: Int, span: Int): Events[fourValuedLogicValue] :=
repeatConstraintReset(e, lower, upper, span, pseudoInfty)
repeatConstraintReset[A](e: Events[A], lower: Int, upper: Int, span: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the RepeatConstraint defined in TADL2.
Resets a negative output after resetTime. See RepeatConstraint for more information.
See repeatConstraint
for more information.
def repeatConstraintReset[A](e: Events[A], lower: Int, upper: Int, span: Int, resetTime: Int):
Events[fourValuedLogicValue] := {
#stored state
def latestSpanEventTimes: Events[List[Int]]:=
if TADL2.defaultTime(e) == 0 then
List.append(List.empty[Int], TADL2.defaultTime(e))
else
default(
List.append(
if (List.size(last(latestSpanEventTimes, e)) > span) then
List.tail(last(latestSpanEventTimes, TADL2.defaultTime(e)))
else
last(latestSpanEventTimes, e),
TADL2.defaultTime(e)),
List.empty[Int])
# timestamps, in which the evaluation occurs
def delayPeriod :=
if (upper == pseudoInfty || upper < 0) then
-1
else
if (defaultTime(e) == defaultTime(firstEvent(e))) then
List.head(latestSpanEventTimes) + upper - time(e) + 1
else
List.head(List.tail(latestSpanEventTimes)) + upper - time(e) + 1
def evaluateTimes :=
mergeUnit(e, safeDelay(delayPeriod, e))
stillFulfillableReset(
# more than span events occured-> distance to span-1^th event is relevant
if (List.size(latestSpanEventTimes) > span) then
if List.head(latestSpanEventTimes) + lower <= time(evaluateTimes) &&
(upper == pseudoInfty || List.head(latestSpanEventTimes) + upper >= time(evaluateTimes)) then
{value= true, final= false}
else
{value= false, final= true}
else
# less than span events occurred-> first event must be younger than upper
if (upper == pseudoInfty || List.head(latestSpanEventTimes) + upper >= time(evaluateTimes)) then
{value= true, final= false}
else
{value= false, final= true},
resetTime)
}
repetitionConstraint[A](e: Events[A], lower: Int, upper: Int, span: Int, jitter: Int): Events[fourValuedLogicValue]
Checks the RepetitionConstraint defined in TADL2.
The RepetitionConstraint is similar to the RepeatConstraint, but the parameter jitter allows to define further deviations from the repetitions.
Usage Example
in event: Events[Unit]
def lower = 30
def upper = 30
def span = 2
def jitter = 2
def constraint= TADL2.repetitionConstraint(event, lower, upper, span, jitter)
out constraint.value
out constraint.final
Trace Example
5: event = ()
5: constraint.value = true
5: constraint.final = false
10: event = ()
10: constraint.value = true
10: constraint.final = false
35: event = ()
35: constraint.value = true
35: constraint.final = false
38: event = ()
38: constraint.value = true
38: constraint.final = false
67: event = ()
67: constraint.value = true
67: constraint.final = false
70: event = ()
70: constraint.value = true
70: constraint.final = false
def repetitionConstraint[A](e: Events[A], lower: Int, upper: Int, span: Int, jitter: Int):
Events[fourValuedLogicValue] := {
repetitionConstraintReset(e, lower, upper, span, jitter, pseudoInfty)
}
repetitionConstraintReset[A](events: Events[A], lower: Int, upper: Int, span: Int, jitter: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the RepetitionConstraint defined in TADL2.
Resets a negative output after resetTime.
See repetitionConstrin
for more information.
def repetitionConstraintReset[A](events: Events[A], lower: Int, upper: Int, span: Int, jitter: Int,
resetTime: Int): Events[fourValuedLogicValue] := {
# lower bound for current x
def lowerBoundXNow: Events[Int] =
if (List.size(last(LowerBoundX, events)) < span) then
time(events)-jitter
else
max(List.head(last(LowerBoundX, events)), time(events)-jitter)
# upper bound for current x
def upperBoundXNow: Events[Int] =
if (List.size(last(UpperBoundX, events)) < span) then
time(events)
else
min(List.head(last(UpperBoundX, events)), time(events))
# lower bound for span next x
def LowerBoundX: Events[List[Int]]:= merge(
if (last(res, events).final) then
List.empty[Int]
else
if (List.size(last(LowerBoundX, events)) < span) then
List.append(last(LowerBoundX, events), lowerBoundXNow + lower)
else
List.append(last(List.tail(LowerBoundX), events), lowerBoundXNow + lower),
List.empty[Int]
)
# upper bound for span next x
def UpperBoundX: Events[List[Int]]:= merge(
if (last(res, events).final) then
List.empty[Int]
else
if (List.size(last(UpperBoundX, events)) < span) then
List.append(last(UpperBoundX, events), upperBoundXNow+upper)
else
List.append(last(List.tail(UpperBoundX), events), upperBoundXNow + upper),
List.empty[Int]
)
# timestamps, in which the evaluation occurs
def evaluateTimes = mergeUnit(events,
TADL2.safeDelay((if (List.size(UpperBoundX) == 0) then 0 else List.head(UpperBoundX)) +
jitter - time(events)+1, events))
# Evaluation
def res:= TADL2.stillFulfillableReset(
#first event or correct distance to X
if (List.size(LowerBoundX) == 0 && List.size(UpperBoundX) == 0) ||
lowerBoundXNow <= time(evaluateTimes) &&
upperBoundXNow + jitter >= time(evaluateTimes) then
{value= true, final= false}
else
{value= false, final= true},
resetTime)
res
}
resetCount2[A, B](events: Events[A], reset: Events[B]): Events[Int]
See resetCount
for more informations. This implementations also works with events in timestamp 0.
def resetCount2[A, B](events: Events[A], reset: Events[B]): Events[Int] = {
def minusStream: Events[Int]=
merge(
if default((time(reset) >= time(events)), false) then
if default((time(reset) == time(events)), false) then
count(events)-1
else
count(events)
else
last(minusStream, mergeUnit(events, reset)),
0)
count(events) - minusStream
}
sporadicConstraint[A](e: Events[A], lower: Int, upper: Int, jitter: Int, minDist: Int): Events[fourValuedLogicValue]
Checks the SporadicConstraint defined in TADL2.
The SporadicConstraint describes sporadic event occurrences, constraint by the minimal distance between subsequent events (minimum), the distance between subsequent events (lower, upper) and a deviation from that pattern (jitter). The SporadicConstraint is similar to the RepetitionConstraint, but additionally check the minimal distance of Events.
Usage Example
in event: Events[Unit]
def lower = 10
def upper = 15
def jitter = 0
def minDist = 11
def constraint= TADL2.sporadicConstraint(event, lower, upper, jitter, minDist)
out constraint.value
out constraint.final
Trace Example
option timeDomain:[-1,50]
5: event = ()
5: constraint.value = true
5: constraint.final = false
20: event = ()
20: constraint.value = true
20: constraint.final = false
31: event = ()
31: constraint.value = true
31: constraint.final = false
45: event = ()
45: constraint.value = true
45: constraint.final = false
def sporadicConstraint[A](e: Events[A], lower: Int, upper: Int, jitter: Int, minDist: Int):
Events[fourValuedLogicValue]:=
# application of repeat and repetititonConstraint
fourValuedConjunction(repetitionConstraint(e, lower, upper, 1, jitter),
repeatConstraint(e, minDist, pseudoInfty, 1))
sporadicConstraintReset[A](e: Events[A], lower: Int, upper: Int, jitter: Int, minDist: Int, ResetTime: Int): Events[fourValuedLogicValue]
Checks the SporadicConstraint defined in TADL2.
Resets negative output after resetTime. The SporadicConstraint is a conjunction of the
RepetitionConstraint and the RepeatConstraint and the reset is handled by them individually.
See sporadicConstraint
for more information.
def sporadicConstraintReset[A](e: Events[A], lower: Int, upper: Int, jitter: Int, minDist: Int,
ResetTime: Int): Events[fourValuedLogicValue]:=
# application of repeat and repetititonConstraint
fourValuedConjunction(repetitionConstraintReset(e, lower, upper, 1, jitter, ResetTime),
repeatConstraintReset(e, minDist, pseudoInfty, 1, ResetTime))
stillFulfillable(events: Events[fourValuedLogicValue]): Events[fourValuedLogicValue]
Ensures that a four valued logic value, which is {value= false, final= true}, stays {value= false, final= true}.
def stillFulfillable(events: Events[fourValuedLogicValue]): Events[fourValuedLogicValue] :={
def storage: Events[Bool] :=
default(last(storage, events), true) && events != {value= false, final= true}
if storage then
events
else
{value= false, final= true}
}
stillFulfillableReset(events: Events[fourValuedLogicValue], resetTime: Int): Events[fourValuedLogicValue]
Ensures that a four valued logic value, which is {value= false, final= true}, stays {value= false, final= true}. reset to {value= false, final= true} after resetTime
def stillFulfillableReset(events: Events[fourValuedLogicValue], resetTime: Int): Events[fourValuedLogicValue] :={
# is the value currently final false?
def isFinalFalse: Events[Bool] =
default(last(isFinalFalseReset, events) || (events.final == true && events.value == false), false)
# since which timestamp is the value final false?
def finalFalseSince: Events[Int] =
default(
if (events.final && !events.value) && !prev(isFinalFalse) then
time(events)
else
last(finalFalseSince, isFinalFalse),
pseudoInfty)
def isFinalFalseReset: Events[Bool] =
merge(
if (finalFalseSince + resetTime < time (events)) then
false
else
isFinalFalse,
isFinalFalse)
#output
if (isFinalFalseReset) then
{value= false, final= true}
else
events
}
strongDelayConstraint[A, B](source: Events[A], target: Events[B], lower: Int, upper: Int)
Checks the StrongDelayConstraint defined in TADL2 Each source event must be followed by one target event, which occurs within a time distance between lower and upper. Additional target events are not allowed.
Usage Example
in source: Events[Unit]
in target: Events[Unit]
def lower = 15
def upper = 25
def constraint= TADL2.strongDelayConstraint(source, target, lower, upper)
out constraint.value
out constraint.final
Trace Example
10: source = ()
10: constraint.value = false
10: constraint.final = false
25: target = ()
25: constraint.value = true
25: constraint.final = false
50: source = ()
50: constraint.value = false
50: constraint.final = false
65: target = ()
65: constraint.value = true
65: constraint.final = false
75: target = ()
75: constraint.value = false
75: constraint.final = true
def strongDelayConstraint[A, B](source: Events[A], target: Events[B], lower: Int, upper: Int) :=
strongDelayConstraintReset(source, target, lower, upper, pseudoInfty)
strongDelayConstraintReset[A, B](source: Events[A], target: Events[B], lower: Int, upper: Int, resetTime: Int)
checks the StrongDelayConstraint defined in TADL2, resets a negative output after resetTime
See strongDelayConstraint
for more information.
def strongDelayConstraintReset[A, B](source: Events[A], target: Events[B], lower: Int, upper: Int,
resetTime: Int) :={
# timestamps of source events, which did not have matching target event yet,
# including the timestamps, which matches in this this timestamp
def unfinishedSourceTimesNewSource:=
#current timeStamp has source event
if (TADL2.defaultTime(source) >= TADL2.defaultTime(target)) then
# append timestamp to list
List.append(default(last(unfinishedSourceTimes, mergeUnit(source, target)), List.empty[Int]),
time(source))
else
default(last(unfinishedSourceTimes, mergeUnit(source, target)), List.empty[Int])
# remove events that are older than resetTime
def unfinishedSourceTimesAfterReset:=
if List.size(unfinishedSourceTimesNewSource) != 0 then
if (List.head(unfinishedSourceTimesNewSource) + resetTime < time(mergeUnit(source, target))) then
TADL2.removeItemsSmallerThanAFromListFront(unfinishedSourceTimesNewSource,
time(mergeUnit(source, target)) - upper)
else
unfinishedSourceTimesNewSource
else
List.empty[Int]
# timestamps of source events, which did not have matching target event yet
def unfinishedSourceTimes: Events[List[Int]]:=
#current timeStamp has target event
if (defaultTime(source) <= defaultTime(target)) then
# removing possible-> remove
if List.size(unfinishedSourceTimesAfterReset) != 0 then
# if matching time distance to oldest stored event
if (List.head(unfinishedSourceTimesAfterReset) + lower <= defaultTime(target) &&
List.head(unfinishedSourceTimesAfterReset) + upper >= defaultTime(target)) then
# just keep tail
List.tail(unfinishedSourceTimesAfterReset)
else
# return unchanged
unfinishedSourceTimesAfterReset
else
# removing not possible-> insert event, that triggers {value= false, final= true}
List.append(List.empty[Int], -pseudoInfty)
else
unfinishedSourceTimesAfterReset
# timestamps, in which the evaluation occurs
def evaluateTimes = mergeUnit(mergeUnit(source, target),
safeDelay(if (List.size(unfinishedSourceTimes) == 0) then
-1
else
List.head(unfinishedSourceTimes) + upper - time(mergeUnit(source, target))+1,
mergeUnit(source, target)))
# output
stillFulfillableReset(
# no unmatched source event-> current true
if (List.size(unfinishedSourceTimes) == 0) then
{value= true, final= false}
else
# target event, but no stored source event-> false
if (List.size(unfinishedSourceTimesAfterReset) == 0) then
{value= false, final= true}
else
# # current timestamp has target event
if (TADL2.defaultTime(target) >= time(evaluateTimes)) then
# correct distance-> current false
if (List.head(unfinishedSourceTimesAfterReset) + lower <= TADL2.defaultTime(target) &&
List.head(unfinishedSourceTimesAfterReset) + upper >= TADL2.defaultTime(target)) then
{value= false, final= false}
else
{value= false, final= true}
else
# distance must only be smaller than upper
if List.head(unfinishedSourceTimesAfterReset) + upper >= TADL2.defaultTime(evaluateTimes) then
{value= false, final= false}
else
{value= false, final= true},
resetTime)
}
StrongSynchronizationConstraint10[A, B, C, D, E, F, G, H, I, J](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], events9: Events[I], events10: Events[J], tolerance: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for ten streams.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraint10[A, B, C, D, E, F, G, H, I, J](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
events8: Events[H], events9: Events[I], events10: Events[J], tolerance: Int): Events[fourValuedLogicValue]:=
StrongSynchronizationConstraintReset10(events1, events2, events3, events4, events5, events6, events7,
events8, events9, events10, tolerance, pseudoInfty)
StrongSynchronizationConstraint2[A, B](events1: Events[A], events2: Events[B], tolerance: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for two streams.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraint2[A, B](events1: Events[A], events2: Events[B], tolerance: Int):
Events[fourValuedLogicValue]:=
StrongSynchronizationConstraintReset2(events1, events2, tolerance, pseudoInfty)
StrongSynchronizationConstraint3[A, B, C](events1: Events[A], events2: Events[B], events3: Events[C], tolerance: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for three streams.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraint3[A, B, C](events1: Events[A], events2: Events[B], events3: Events[C],
tolerance: Int): Events[fourValuedLogicValue]:=
StrongSynchronizationConstraintReset3(events1, events2, events3, tolerance, pseudoInfty)
StrongSynchronizationConstraint4[A, B, C, D](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], tolerance: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for four streams.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraint4[A, B, C, D](events1: Events[A], events2: Events[B], events3: Events[C],
events4: Events[D], tolerance: Int): Events[fourValuedLogicValue]:=
StrongSynchronizationConstraintReset4(events1, events2, events3, events4, tolerance, pseudoInfty)
StrongSynchronizationConstraint5[A, B, C, D, E](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], tolerance: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for five streams.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraint5[A, B, C, D, E](events1: Events[A], events2: Events[B], events3: Events[C],
events4: Events[D], events5: Events[E], tolerance: Int): Events[fourValuedLogicValue]:=
StrongSynchronizationConstraintReset5(events1, events2, events3, events4, events5, tolerance,
pseudoInfty)
StrongSynchronizationConstraint6[A, B, C, D, E, F](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], tolerance: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for six streams.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraint6[A, B, C, D, E, F](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], tolerance: Int):
Events[fourValuedLogicValue]:=
StrongSynchronizationConstraintReset6(events1, events2, events3, events4, events5, events6, tolerance,
pseudoInfty)
StrongSynchronizationConstraint7[A, B, C, D, E, F, G](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], tolerance: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for seven streams.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraint7[A, B, C, D, E, F, G](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
tolerance: Int): Events[fourValuedLogicValue]:=
StrongSynchronizationConstraintReset7(events1, events2, events3, events4, events5, events6, events7,
tolerance, pseudoInfty)
StrongSynchronizationConstraint8[A, B, C, D, E, F, G, H](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], tolerance: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for eight streams.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraint8[A, B, C, D, E, F, G, H](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
events8: Events[H], tolerance: Int): Events[fourValuedLogicValue]:=
StrongSynchronizationConstraintReset8(events1, events2, events3, events4, events5, events6, events7,
events8, tolerance, pseudoInfty)
StrongSynchronizationConstraint9[A, B, C, D, E, F, G, H, I](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], events9: Events[I], tolerance: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for nine streams.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraint9[A, B, C, D, E, F, G, H, I](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
events8: Events[H], events9: Events[I], tolerance: Int): Events[fourValuedLogicValue]:=
StrongSynchronizationConstraintReset9(events1, events2, events3, events4, events5, events6, events7,
events8, events9, tolerance, pseudoInfty)
StrongSynchronizationConstraintReset(eventIndices: Events[List[Int]], streamCount: Int, tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint defined in TADL2.
The StrongSynchronizationConstraint describes groups of streams, which events occur in common clusters. Each of these streams must have exactly one event in each of these intervals. Any events that lay outside of these intervals are prohibited. Overlaps of clusters are allowed. The events of each input timestamp must be placed into an integer list, which contains the index (starting at 1) of all streams, which have an event in this timestamp. This list is then used as a parameter for the implementation. The creation of this list is already implemented for up to 10 streams. See synchronizationConstraint2, … .
A negative output and invalid state is reseted after resetTime
Usage Example
in event1: Events[Unit]
in event2: Events[Unit]
in event3: Events[Unit]
def tolerance = 2
def resetTime= TADL2.pseudoInfty
def constraint= TADL2.StrongSynchronizationConstraintReset3(event1, event2, event3, tolerance, resetTime)
out constraint.value
out constraint.final
Trace Example
5: event1 = ()
5: event2 = ()
5: event3 = ()
5: constraint.value = true
5: constraint.final = false
15: event1 = ()
15: event2 = ()
15: event3 = ()
15: constraint.value = true
15: constraint.final = false
24: event1 = ()
24: constraint.value = false
24: constraint.final = false
25: event2 = ()
25: constraint.value = false
25: constraint.final = false
26: event3 = ()
26: constraint.value = true
26: constraint.final = false
34: event2 = ()
34: constraint.value = false
34: constraint.final = false
35: event3 = ()
35: constraint.value = false
35: constraint.final = false
36: event1 = ()
36: constraint.value = true
36: constraint.final = false
def StrongSynchronizationConstraintReset(eventIndices: Events[List[Int]], streamCount: Int, tolerance: Int,
resetTime: Int): Events[fourValuedLogicValue]:= {
# inserts one events to the active clusters. Creates new cluster, if needed.
# insertes only, if cluster not too old
# runtime: list.length(activeClusters)
liftable def insertEvent(activeClusters: List[synchronizationCluster], eventIndex: Int, timeNow: Int):
List[synchronizationCluster] :=
# no more clusters to check -> create new cluster
if (List.size(activeClusters) == 0) then
List.append(activeClusters, {startTime= timeNow,
fulfilledStreams= Map.add(TADL2.buildMap(streamCount, false), eventIndex, true)})
else
# stream index already was in head cluster or too old-> check next one
if (Map.get(List.head(activeClusters).fulfilledStreams, eventIndex) ||
List.head(activeClusters).startTime + tolerance < timeNow) then
List.prepend(List.head(activeClusters), insertEvent(List.tail(activeClusters), eventIndex, timeNow))
#found matching cluster-> set stream in this cluster to true
else
List.prepend({startTime= List.head(activeClusters).startTime,
fulfilledStreams= Map.add(List.head(activeClusters).fulfilledStreams, eventIndex, true)},
List.tail(activeClusters))
# inserts all events from eventIndices to the active clusters.
# runtime: List.length(eventIndices) * list.length(activeClusters)
liftable def insertEventsList(activeClusters: List[synchronizationCluster], eventIndices: List[Int],
timeNow: Int): List[synchronizationCluster] :=
if (List.size(eventIndices) == 0) then
activeClusters
else
insertEventsList(insertEvent(activeClusters, List.head(eventIndices), timeNow),
List.tail(eventIndices), timeNow)
# runtime: min(tolerance, List.length(eventIndices) * list.length(activeClusters))
liftable def removeFulfilledClusters(activeClusters: List[synchronizationCluster]):
List[synchronizationCluster]:=
#head of list is fulfilled-> remove and check next list entry
if (List.size(activeClusters) != 0 && TADL2.mapAllTrue(List.head(activeClusters).fulfilledStreams)) then
removeFulfilledClusters(List.tail(activeClusters))
# head of list is unfulfilled-> don't remove, rest can't be fulfilled either
else
activeClusters
# delete clusters which were created before lastestAllowedTime
liftable def removeOldClusters(activeClusters: List[synchronizationCluster], latestAllowedTime: Int):
List[synchronizationCluster] =
if (List.size(activeClusters) == 0) then
activeClusters
else
if (List.head(activeClusters).startTime < latestAllowedTime) then
removeOldClusters(List.tail(activeClusters), latestAllowedTime)
else
List.prepend(List.head(activeClusters),
removeOldClusters(List.tail(activeClusters), latestAllowedTime))
#state
def activeClustersResetted: Events[List[synchronizationCluster]]:=
merge(merge(on(resets, removeOldClusters(last(activeClustersState, resets), time(resets) - tolerance)),
last(activeClustersState, mergeUnit(resets, eventIndices))),
List.empty[synchronizationCluster])
# list of active clusters
def activeClustersState: Events[List[synchronizationCluster]]:=
merge(removeFulfilledClusters(
if (TADL2.defaultTime(resets) > TADL2.defaultTime(eventIndices) && TADL2.defaultTime(resets) != -1) then
activeClustersResetted
else
insertEventsList(activeClustersResetted, eventIndices, time(eventIndices))),
List.empty[synchronizationCluster])
#delay
def evalTimes:=
time(mergeUnit(eventIndices,
TADL2.safeDelay(if (List.size(activeClustersState) != 0) then
List.head(activeClustersState).startTime+ tolerance - time(eventIndices)+1
else
-1, eventIndices)))
# next timestamp after 'falling flank'
def failingTimeStamps: Events[Unit] =
filter(const((), eventIndices), last(result.final, eventIndices) &&
!(last(last(result.final, eventIndices), eventIndices)))
#timestamps, in which the state of the monitor is resetted
def resets: Events[Unit]=
delay(if (const(resetTime, failingTimeStamps)-(time(eventIndices) - prev(time(eventIndices))) > 0) then
const(resetTime, failingTimeStamps)-(time(eventIndices) - prev(time(eventIndices))) else 1,
failingTimeStamps)
#no unfulfilled clusters-> currently true
def result:= TADL2.stillFulfillableReset(
if List.size(activeClustersState) == 0 then
{value= true, final= false}
else
# unfulfilled clusters exists, but not too old-> current false
if (List.head(activeClustersState).startTime + tolerance > evalTimes) then
{value= false, final= false}
else
# unfulfilled clusters are too old-> def. false
{value= false, final= true},
resetTime)
#output
result
}
StrongSynchronizationConstraintReset10[A, B, C, D, E, F, G, H, I, J](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], events9: Events[I], events10: Events[J], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for ten streams.
Resets a negative output and invalid state after resetTime.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraintReset10[A, B, C, D, E, F, G, H, I, J](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
events8: Events[H], events9: Events[I], events10: Events[J], tolerance: Int, resetTime: Int):
Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
mergeUnit(events1, events2), events3), events4), events5), events6), events7), events8), events9), events10))
def eventList10:=
if (defaultTime(events10) >= timeNow) then
List.prepend(10, List.empty[Int])
else
List.empty[Int]
def eventList9:=
if (defaultTime(events9) >= timeNow) then
List.prepend(9, eventList10)
else
eventList10
def eventList8:=
if (defaultTime(events8) >= timeNow) then
List.prepend(8, eventList9)
else
eventList9
def eventList7:=
if (defaultTime(events7) >= timeNow) then
List.prepend(7, eventList8)
else
eventList8
def eventList6:=
if (defaultTime(events6) >= timeNow) then
List.prepend(6, eventList7)
else
eventList7
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, eventList6)
else
eventList6
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
StrongSynchronizationConstraintReset(eventList, 10, tolerance, resetTime)
}
StrongSynchronizationConstraintReset2[A, B](events1: Events[A], events2: Events[B], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for two streams.
Resets a negative output and invalid state after resetTime.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraintReset2[A, B](events1: Events[A], events2: Events[B],
tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(events1, events2))
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, List.empty[Int])
else
List.empty[Int]
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
StrongSynchronizationConstraintReset(eventList, 2, tolerance, resetTime)
}
StrongSynchronizationConstraintReset3[A, B, C](events1: Events[A], events2: Events[B], events3: Events[C], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for three streams.
Resets a negative output and invalid state after resetTime.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraintReset3[A, B, C](events1: Events[A], events2: Events[B], events3: Events[C],
tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(events1, events2), events3))
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, List.empty[Int])
else
List.empty[Int]
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
StrongSynchronizationConstraintReset(eventList, 3, tolerance, resetTime)
}
StrongSynchronizationConstraintReset4[A, B, C, D](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for four streams.
Resets a negative output and invalid state after resetTime.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraintReset4[A, B, C, D](events1: Events[A], events2: Events[B], events3: Events[C],
events4: Events[D], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(events1, events2), events3), events4))
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, List.empty[Int])
else
List.empty[Int]
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
StrongSynchronizationConstraintReset(eventList, 4, tolerance, resetTime)
}
StrongSynchronizationConstraintReset5[A, B, C, D, E](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for five streams.
Resets a negative output and invalid state after resetTime.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraintReset5[A, B, C, D, E](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], tolerance: Int, resetTime: Int):
Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
events1, events2), events3), events4), events5))
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, List.empty[Int])
else
List.empty[Int]
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
StrongSynchronizationConstraintReset(eventList, 5, tolerance, resetTime)
}
StrongSynchronizationConstraintReset6[A, B, C, D, E, F](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for six streams.
Resets a negative output and invalid state after resetTime.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraintReset6[A, B, C, D, E, F](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], tolerance: Int,
resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
events1, events2), events3), events4), events5), events6))
def eventList6:=
if (defaultTime(events6) >= timeNow) then
List.prepend(6, List.empty[Int])
else
List.empty[Int]
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, eventList6)
else
eventList6
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
StrongSynchronizationConstraintReset(eventList, 6, tolerance, resetTime)
}
StrongSynchronizationConstraintReset7[A, B, C, D, E, F, G](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for seven streams.
Resets a negative output and invalid state after resetTime.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraintReset7[A, B, C, D, E, F, G](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
events1, events2), events3), events4), events5), events6), events7))
def eventList7:=
if (defaultTime(events7) >= timeNow) then
List.prepend(7, List.empty[Int])
else
List.empty[Int]
def eventList6:=
if (defaultTime(events6) >= timeNow) then
List.prepend(6, eventList7)
else
eventList7
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, eventList6)
else
eventList6
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
StrongSynchronizationConstraintReset(eventList, 7, tolerance, resetTime)
}
StrongSynchronizationConstraintReset8[A, B, C, D, E, F, G, H](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for eight streams.
Resets a negative output and invalid state after resetTime.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraintReset8[A, B, C, D, E, F, G, H](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
events8: Events[H], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
events1, events2), events3), events4), events5), events6), events7), events8))
def eventList8:=
if (defaultTime(events8) >= timeNow) then
List.prepend(8, List.empty[Int])
else
List.empty[Int]
def eventList7:=
if (defaultTime(events7) >= timeNow) then
List.prepend(7, eventList8)
else
eventList8
def eventList6:=
if (defaultTime(events6) >= timeNow) then
List.prepend(6, eventList7)
else
eventList7
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, eventList6)
else
eventList6
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
StrongSynchronizationConstraintReset(eventList, 8, tolerance, resetTime)
}
StrongSynchronizationConstraintReset9[A, B, C, D, E, F, G, H, I](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], events9: Events[I], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the StrongSynchronizationConstraint for nine streams.
Resets a negative output and invalid state after resetTime.
See StrongSynchronizationConstraint
for further information.
def StrongSynchronizationConstraintReset9[A, B, C, D, E, F, G, H, I](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
events8: Events[H], events9: Events[I], tolerance: Int, resetTime: Int):
Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
events1, events2), events3), events4), events5), events6), events7), events8), events9))
def eventList9:=
if (defaultTime(events9) >= timeNow) then
List.prepend(9, List.empty[Int])
else
List.empty[Int]
def eventList8:=
if (defaultTime(events8) >= timeNow) then
List.prepend(8, eventList9)
else
eventList9
def eventList7:=
if (defaultTime(events7) >= timeNow) then
List.prepend(7, eventList8)
else
eventList8
def eventList6:=
if (defaultTime(events6) >= timeNow) then
List.prepend(6, eventList7)
else
eventList7
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, eventList6)
else
eventList6
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
StrongSynchronizationConstraintReset(eventList, 9, tolerance, resetTime)
}
synchronizationConstraint10[A, B, C, D, E, F, G, H, I, J](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], events9: Events[I], events10: Events[J], tolerance: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for ten streams.
See SynchronizationConstraint
for further information.
def synchronizationConstraint10[A, B, C, D, E, F, G, H, I, J](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
events8: Events[H], events9: Events[I], events10: Events[J], tolerance: Int): Events[fourValuedLogicValue]:=
synchronizationConstraintReset10(events1, events2, events3, events4, events5, events6, events7, events8,
events9, events10, tolerance, pseudoInfty)
synchronizationConstraint2[A, B](events1: Events[A], events2: Events[B], tolerance: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for two streams.
See SynchronizationConstraint
for further information.
def synchronizationConstraint2[A, B](events1: Events[A], events2: Events[B], tolerance: Int
): Events[fourValuedLogicValue]:=
synchronizationConstraint2Reset(events1, events2, tolerance, pseudoInfty)
synchronizationConstraint2Reset[A, B](events1: Events[A], events2: Events[B], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for two streams.
Resets a negative output after ResetTime
See SynchronizationConstraint
for further information.
def synchronizationConstraint2Reset[A, B](events1: Events[A], events2: Events[B], tolerance: Int,
resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(events1, events2))
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, List.empty[Int])
else
List.empty[Int]
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
synchronizationConstraintReset(eventList, 2, tolerance, resetTime)
}
synchronizationConstraint3[A, B, C](events1: Events[A], events2: Events[B], events3: Events[C], tolerance: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for three streams.
See SynchronizationConstraint
for further information.
def synchronizationConstraint3[A, B, C](events1: Events[A], events2: Events[B], events3: Events[C],
tolerance: Int): Events[fourValuedLogicValue]:=
synchronizationConstraintReset3(events1, events2, events3, tolerance, pseudoInfty)
synchronizationConstraint4[A, B, C, D](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], tolerance: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for four streams.
See SynchronizationConstraint
for further information.
def synchronizationConstraint4[A, B, C, D](events1: Events[A], events2: Events[B], events3: Events[C],
events4: Events[D], tolerance: Int): Events[fourValuedLogicValue]:=
synchronizationConstraintReset4(events1, events2, events3, events4, tolerance, pseudoInfty)
synchronizationConstraint5[A, B, C, D, E](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], tolerance: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for five streams.
See SynchronizationConstraint
for further information.
def synchronizationConstraint5[A, B, C, D, E](events1: Events[A], events2: Events[B], events3: Events[C],
events4: Events[D], events5: Events[E], tolerance: Int): Events[fourValuedLogicValue]:=
synchronizationConstraintReset5(events1, events2, events3, events4, events5, tolerance, pseudoInfty)
synchronizationConstraint6[A, B, C, D, E, F](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], tolerance: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for six streams.
See SynchronizationConstraint
for further information.
def synchronizationConstraint6[A, B, C, D, E, F](events1: Events[A], events2: Events[B], events3: Events[C],
events4: Events[D], events5: Events[E], events6: Events[F], tolerance: Int):
Events[fourValuedLogicValue]:=
synchronizationConstraintReset6(events1, events2, events3, events4, events5, events6, tolerance,
pseudoInfty)
synchronizationConstraint7[A, B](events1: Events[A], events2: Events[B], events3: Events[B], events4: Events[B], events5: Events[B], events6: Events[B], events7: Events[B], tolerance: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for seven streams.
See SynchronizationConstraint
for further information.
def synchronizationConstraint7[A, B](events1: Events[A], events2: Events[B], events3: Events[B],
events4: Events[B], events5: Events[B], events6: Events[B], events7: Events[B], tolerance: Int):
Events[fourValuedLogicValue]:=
synchronizationConstraintReset7(events1, events2, events3, events4, events5, events6, events7,
tolerance, pseudoInfty)
synchronizationConstraint8[A, B, C, D, E, F, G, H](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], tolerance: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for eight streams.
See SynchronizationConstraint
for further information.
def synchronizationConstraint8[A, B, C, D, E, F, G, H](events1: Events[A], events2: Events[B], events3: Events[C],
events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H],
tolerance: Int): Events[fourValuedLogicValue]:=
synchronizationConstraintReset8(events1, events2, events3, events4, events5, events6, events7, events8,
tolerance, pseudoInfty)
synchronizationConstraint9[A, B, C, D, E, F, G, H, I](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], events9: Events[I], tolerance: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for nine streams.
See SynchronizationConstraint
for further information.
def synchronizationConstraint9[A, B, C, D, E, F, G, H, I](events1: Events[A], events2: Events[B], events3: Events[C],
events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H],
events9: Events[I], tolerance: Int): Events[fourValuedLogicValue]:=
synchronizationConstraintReset9(events1, events2, events3, events4, events5, events6, events7, events8,
events9, tolerance, pseudoInfty)
synchronizationConstraintReset(eventIndices: Events[List[Int]], streamCount: Int, tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint defined in TADL2.
The SynchronizationConstraint describes groups of streams, which events occur in common clusters. Each of these streams must have at least one event in each of these intervals. Any events that lay outside of these intervals are prohibited. Overlaps of clusters are allowed. The events of each input timestamp must be placed into an integer list, which contains the index (starting at 1) of all streams, which have an event in this timestamp. This list is then used as a parameter for the implementation. The creation of this list is already implemented for up to 10 streams. See synchronizationConstraint2, … .
A negative output and an invalid state is resetted after resetTime.
Usage Example
in event1: Events[Unit]
in event2: Events[Unit]
in event3: Events[Unit]
def tolerance = 2
def constraint= TADL2.synchronizationConstraint3(event1, event2, event3, tolerance)
out constraint.value
out constraint.final
Trace Example
option timeDomain:[-1,50]
5: event1 = ()
5: event2 = ()
5: event3 = ()
5: constraint.value = true
5: constraint.final = false
15: event1 = ()
15: event2 = ()
15: event3 = ()
15: constraint.value = true
15: constraint.final = false
24: event1 = ()
24: constraint.value = false
24: constraint.final = false
25: event2 = ()
25: constraint.value = false
25: constraint.final = false
26: event3 = ()
26: constraint.value = true
26: constraint.final = false
34: event2 = ()
34: constraint.value = false
34: constraint.final = false
35: event3 = ()
35: constraint.value = false
35: constraint.final = false
36: event1 = ()
36: constraint.value = true
36: constraint.final = false
def synchronizationConstraintReset(eventIndices: Events[List[Int]], streamCount: Int, tolerance: Int,
resetTime: Int): Events[fourValuedLogicValue]:= {
def buildSynchronizationEventInfo(streamInd: Int, evtTime: Int, flflld: Bool) : SynchronizationEventInfo:=
{streamIndex= streamInd, eventTime= evtTime, fulfilled= flflld}
# add events from one timestamp to the state
# O(|events|)
def addEvents(existingEvents: List[SynchronizationEventInfo], newEventStreamIndices: List[Int], timeNow: Int) :
List[SynchronizationEventInfo]:=
if (List.size(newEventStreamIndices) == 0) then
existingEvents
else
addEvents(List.append(existingEvents,
buildSynchronizationEventInfo(List.head(newEventStreamIndices), timeNow, false)),
List.tail(newEventStreamIndices), timeNow)
# checks, if the events between timeNow and (timeNow-tolerance) fulfills the cluster
# O(List_length)= O(tolerance*|events|)
def clusterFulfilled(events: List[SynchronizationEventInfo], timeNow: Int, tolerance: Int,
streamCount: Int): Bool := {
# creates a set with [1, 2, ..., size]
def fillSet(count: Int): Set[Int]:=
if count == 0 then
Set.empty[Int]
else
Set.add(fillSet(count-1), count)
def checkCluster(events: List[SynchronizationEventInfo], timeNow: Int, tolerance: Int,
reaminingIndices: Set[Int]):Bool:=
if Set.size(reaminingIndices) == 0 then
true
else
if (List.size(events) == 0) then
false
else
if (List.head(events).eventTime + tolerance >= timeNow) &&
(Set.contains(reaminingIndices, List.head(events).streamIndex)) then
checkCluster(List.tail(events), timeNow, tolerance,
Set.remove(reaminingIndices, List.head(events).streamIndex))
else
checkCluster(List.tail(events), timeNow, tolerance, reaminingIndices)
checkCluster(events, timeNow, tolerance, fillSet(streamCount))
}
# sets all Events in list to fulfilled, if not too old
def setEventsToFulfilled(events: List[SynchronizationEventInfo], timeNow: Int, tolerance: Int,
streamCount: Int): List[SynchronizationEventInfo] :=
if (List.size(events) == 0) then
events
else
# set List.head to fulfilled, if not too old
List.prepend(
if (List.head(events).eventTime + tolerance >= timeNow) then
buildSynchronizationEventInfo(List.head(events).streamIndex,
List.head(events).eventTime, true)
else
List.head(events),
setEventsToFulfilled(List.tail(events), timeNow, tolerance, streamCount))
#set fulfilled state of events to true, if fulfilled
def updateFullfilledEvents(events: List[SynchronizationEventInfo], timeNow: Int, tolerance: Int,
streamCount: Int): List[SynchronizationEventInfo]:=
if (clusterFulfilled(events, timeNow, tolerance, streamCount)) then
setEventsToFulfilled(events, timeNow, tolerance, streamCount)
else
events
# creates a List with all events, that are older than tolerance
def eventsToRemove(events: List[SynchronizationEventInfo], timeNow: Int, tolerance: Int):
List[SynchronizationEventInfo] :=
if (List.size(events) == 0) then
events
else
# head of List too old
if(timeNow - List.head(events).eventTime > tolerance) then
# add head of list to return list
List.append(eventsToRemove(List.tail(events), timeNow, tolerance), List.head(events))
else
# rest of list can't be older-> return empty
List.empty[SynchronizationEventInfo]
# removes all events, that are older than tolerance
def removeEvents(events: List[SynchronizationEventInfo], timeNow: Int, tolerance: Int):
List[SynchronizationEventInfo] :=
if (List.size(events) == 0) then
events
else
# head of List too old
if(timeNow - List.head(events).eventTime > tolerance) then
removeEvents(List.tail(events), timeNow, tolerance)
else
# rest of list can't be older-> return unchanged
events
def noUnfulfilledRemoved(removedEvents: List[SynchronizationEventInfo]) : Bool :=
if (List.size(removedEvents) == 0) then
true
else
List.head(removedEvents).fulfilled &&
noUnfulfilledRemoved(List.tail(removedEvents))
# insert new events and set cluster to fulfilled, if possible
def storedEventsBeforeRemove: Events[List[SynchronizationEventInfo]] :=
slift4(slift3(default(last(storedEvents, eventIndices), List.empty[SynchronizationEventInfo]),
eventIndices, time(eventIndices), addEvents),
time(eventIndices), tolerance, streamCount, updateFullfilledEvents)
# remove old events from list
def storedEvents: Events[List[SynchronizationEventInfo]] :=
slift3(storedEventsBeforeRemove, time(eventIndices), tolerance, removeEvents)
def timeOldestUnfulfilledEvent(storedEvents: List[SynchronizationEventInfo]): Int :=
if (List.size(storedEvents) == 0) then
pseudoInfty
else
if !List.head(storedEvents).fulfilled then
List.head(storedEvents).eventTime
else
timeOldestUnfulfilledEvent(List.tail(storedEvents))
# timestamps, in which the evaluation occurs
def evaluateTimes = mergeUnit(eventIndices,
safeDelay(slift1(storedEvents, timeOldestUnfulfilledEvent) + tolerance - time(eventIndices)+1, eventIndices))
def failingTimeStamps: Events[Unit] =
filter(evaluateTimes, last(result.final, evaluateTimes) &&
!(last(last(result.final, evaluateTimes), evaluateTimes)))
#timestamps, in which the state of the monitor is resetted
def resets: Events[Unit]=
delay(const(resetTime, failingTimeStamps)-(time(evaluateTimes) -
prev(time(evaluateTimes))),
failingTimeStamps)
#Evaluation
#no unfullfilled event-> current true
def result := stillFulfillableReset(
if (slift1(storedEvents, timeOldestUnfulfilledEvent) == pseudoInfty) then
{value= true, final= false}
else
#check, if all removed events are fulfilled(had a cluster)-> current false, but not final
if (slift1(storedEventsBeforeRemove, timeOldestUnfulfilledEvent) >= time(evaluateTimes) - tolerance) then
{value= false, final= false}
else
{value= false, final= true},
resetTime)
result
}
synchronizationConstraintReset10[A, B, C, D, E, F, G, H, I, J](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], events9: Events[I], events10: Events[J], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for ten streams.
Resets a negative output ten ResetTime
See SynchronizationConstraint
for further information.
def synchronizationConstraintReset10[A, B, C, D, E, F, G, H, I, J](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
events8: Events[H], events9: Events[I], events10: Events[J], tolerance: Int, resetTime: Int):
Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
events1, events2), events3), events4), events5), events6), events7), events8), events9), events10))
def eventList10:=
if (defaultTime(events10) >= timeNow) then
List.prepend(10, List.empty[Int])
else
List.empty[Int]
def eventList9:=
if (defaultTime(events9) >= timeNow) then
List.prepend(9, eventList10)
else
eventList10
def eventList8:=
if (defaultTime(events8) >= timeNow) then
List.prepend(8, eventList9)
else
eventList9
def eventList7:=
if (defaultTime(events7) >= timeNow) then
List.prepend(7, eventList8)
else
eventList8
def eventList6:=
if (defaultTime(events6) >= timeNow) then
List.prepend(6, eventList7)
else
eventList7
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, eventList6)
else
eventList6
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
synchronizationConstraintReset(eventList, 10, tolerance, resetTime)
}
synchronizationConstraintReset3[A, B, C](events1: Events[A], events2: Events[B], events3: Events[C], tolerance: Int, ResetTime: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for three streams.
Resets a negative output after ResetTime
See SynchronizationConstraint
for further information.
def synchronizationConstraintReset3[A, B, C](events1: Events[A], events2: Events[B], events3: Events[C],
tolerance: Int, ResetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(events1, events2), events3))
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, List.empty[Int])
else
List.empty[Int]
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
synchronizationConstraintReset(eventList, 3, tolerance, ResetTime)
}
synchronizationConstraintReset4[A, B, C, D](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for four streams.
Resets a negative output after ResetTime
See SynchronizationConstraint
for further information.
def synchronizationConstraintReset4[A, B, C, D](events1: Events[A], events2: Events[B], events3: Events[C],
events4: Events[D], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(events1, events2), events3), events4))
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, List.empty[Int])
else
List.empty[Int]
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
synchronizationConstraintReset(eventList, 4, tolerance, resetTime)
}
synchronizationConstraintReset5[A, B, C, D, E](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for five streams.
Resets a negative output after ResetTime
See SynchronizationConstraint
for further information.
def synchronizationConstraintReset5[A, B, C, D, E](events1: Events[A], events2: Events[B], events3: Events[C],
events4: Events[D], events5: Events[E], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
events1, events2), events3), events4), events5))
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, List.empty[Int])
else
List.empty[Int]
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
synchronizationConstraintReset(eventList, 5, tolerance, resetTime)
}
synchronizationConstraintReset6[A, B, C, D, E, F](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for six streams.
Resets a negative output after ResetTime
See SynchronizationConstraint
for further information.
def synchronizationConstraintReset6[A, B, C, D, E, F](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], tolerance: Int,
resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
events1, events2), events3), events4), events5), events6))
def eventList6:=
if (defaultTime(events6) >= timeNow) then
List.prepend(6, List.empty[Int])
else
List.empty[Int]
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, eventList6)
else
eventList6
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
synchronizationConstraintReset(eventList, 6, tolerance, resetTime)
}
synchronizationConstraintReset7[A, B, C, D, E, F, G](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for seven streams.
Resets a negative output after ResetTime
See SynchronizationConstraint
for further information.
def synchronizationConstraintReset7[A, B, C, D, E, F, G](events1: Events[A], events2: Events[B], events3:
Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
events1, events2), events3), events4), events5), events6), events7))
def eventList7:=
if (defaultTime(events7) >= timeNow) then
List.prepend(7, List.empty[Int])
else
List.empty[Int]
def eventList6:=
if (defaultTime(events6) >= timeNow) then
List.prepend(6, eventList7)
else
eventList7
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, eventList6)
else
eventList6
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
synchronizationConstraintReset(eventList, 7, tolerance, resetTime)
}
synchronizationConstraintReset8[A, B, C, D, E, F, G, H](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for eight streams.
Resets a negative output after ResetTime
See SynchronizationConstraint
for further information.
def synchronizationConstraintReset8[A, B, C, D, E, F, G, H](events1: Events[A], events2: Events[B], events3:
Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8:
Events[H], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
events1, events2), events3), events4), events5), events6), events7), events8))
def eventList8:=
if (defaultTime(events8) >= timeNow) then
List.prepend(8, List.empty[Int])
else
List.empty[Int]
def eventList7:=
if (defaultTime(events7) >= timeNow) then
List.prepend(7, eventList8)
else
eventList8
def eventList6:=
if (defaultTime(events6) >= timeNow) then
List.prepend(6, eventList7)
else
eventList7
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, eventList6)
else
eventList6
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
synchronizationConstraintReset(eventList, 8, tolerance, resetTime)
}
synchronizationConstraintReset9[A, B, C, D, E, F, G, H, I](events1: Events[A], events2: Events[B], events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G], events8: Events[H], events9: Events[I], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]
Checks the SynchronizationConstraint for nine streams.
Resets a negative output after ResetTime
See SynchronizationConstraint
for further information.
def synchronizationConstraintReset9[A, B, C, D, E, F, G, H, I](events1: Events[A], events2: Events[B],
events3: Events[C], events4: Events[D], events5: Events[E], events6: Events[F], events7: Events[G],
events8: Events[H], events9: Events[I], tolerance: Int, resetTime: Int): Events[fourValuedLogicValue]:={
def timeNow: Events[Int] := time(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(mergeUnit(
events1, events2), events3), events4), events5), events6), events7), events8), events9))
def eventList9:=
if (defaultTime(events9) >= timeNow) then
List.prepend(9, List.empty[Int])
else
List.empty[Int]
def eventList8:=
if (defaultTime(events8) >= timeNow) then
List.prepend(8, eventList9)
else
eventList9
def eventList7:=
if (defaultTime(events7) >= timeNow) then
List.prepend(7, eventList8)
else
eventList8
def eventList6:=
if (defaultTime(events6) >= timeNow) then
List.prepend(6, eventList7)
else
eventList7
def eventList5:=
if (defaultTime(events5) >= timeNow) then
List.prepend(5, eventList6)
else
eventList6
def eventList4:=
if (defaultTime(events4) >= timeNow) then
List.prepend(4, eventList5)
else
eventList5
def eventList3:=
if (defaultTime(events3) >= timeNow) then
List.prepend(3, eventList4)
else
eventList4
def eventList2:=
if (defaultTime(events2) >= timeNow) then
List.prepend(2, eventList3)
else
eventList3
def eventList:=
if (defaultTime(events1) >= timeNow) then
List.prepend(1, eventList2)
else
eventList2
synchronizationConstraintReset(eventList, 9, tolerance, resetTime)
}