TeSSLa Autosar Timex/TADL 2 extension

module TADL2

ANCHOR Type fourValuedLogicValue

fourValuedLogicValue

Four valued logic value

  • fourValuedLogicValue.value: current logical value
  • fourValuedLogicValue.final: is the current value final? -> will not change in future

ANCHOR ageConstraint

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)

ANCHOR ageConstraintReset

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)
    }

ANCHOR arbitraryConstraint

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)

ANCHOR arbitraryConstraintReset

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)

ANCHOR burstConstraint

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)

ANCHOR burstConstraintReset

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))

ANCHOR checkEventChain

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)

ANCHOR checkEventChainReset

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
	}

ANCHOR delayConstraint

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)
}

ANCHOR delayConstraintReset

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)
}

ANCHOR executionTimeConstraint

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)
}

ANCHOR executionTimeConstraintReset

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)
    }

ANCHOR fourValuedConjunction

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}

ANCHOR inputSynchronizationConstraint10

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)

ANCHOR inputSynchronizationConstraint2

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)

ANCHOR inputSynchronizationConstraint3

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)

ANCHOR inputSynchronizationConstraint4

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)

ANCHOR inputSynchronizationConstraint5

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)

ANCHOR inputSynchronizationConstraint6

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)

ANCHOR inputSynchronizationConstraint7

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)

ANCHOR inputSynchronizationConstraint8

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)

ANCHOR inputSynchronizationConstraint9

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)

ANCHOR inputSynchronizationConstraintReset

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)

}

ANCHOR inputSynchronizationConstraintReset10

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)
}

ANCHOR inputSynchronizationConstraintReset2

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)
}

ANCHOR inputSynchronizationConstraintReset3

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)
}

ANCHOR inputSynchronizationConstraintReset4

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)
}

ANCHOR inputSynchronizationConstraintReset5

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)
    }

ANCHOR inputSynchronizationConstraintReset6

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)
}

ANCHOR inputSynchronizationConstraintReset7

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)
}

ANCHOR inputSynchronizationConstraintReset8

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)
}

ANCHOR inputSynchronizationConstraintReset9

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)
}

ANCHOR orderConstraint

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)

ANCHOR orderConstraintReset

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
	}

ANCHOR outputSynchronizationConstraint10

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)

ANCHOR outputSynchronizationConstraint2

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)

ANCHOR outputSynchronizationConstraint3

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)

ANCHOR outputSynchronizationConstraint4

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)

ANCHOR outputSynchronizationConstraint5

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)

ANCHOR outputSynchronizationConstraint6

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)

ANCHOR outputSynchronizationConstraint7

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)

ANCHOR outputSynchronizationConstraint8

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)

ANCHOR outputSynchronizationConstraint9

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)

ANCHOR outputSynchronizationConstraintReset

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

}

ANCHOR outputSynchronizationConstraintReset10

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)
}

ANCHOR outputSynchronizationConstraintReset2

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)
}

ANCHOR outputSynchronizationConstraintReset3

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)
}

ANCHOR outputSynchronizationConstraintReset4

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)
}

ANCHOR outputSynchronizationConstraintReset5

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)
}

ANCHOR outputSynchronizationConstraintReset6

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)
}

ANCHOR outputSynchronizationConstraintReset7

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)
}

ANCHOR outputSynchronizationConstraintReset8

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)
}

ANCHOR outputSynchronizationConstraintReset9

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)
}

ANCHOR patternConstraint

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)

ANCHOR patternConstraintReset

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
   }

ANCHOR periodicConstraint

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)

ANCHOR periodicConstraintReset

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)

ANCHOR reactionConstraint

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)

ANCHOR reactionConstraintReset

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)
	}

ANCHOR repeatConstraint

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)

ANCHOR repeatConstraintReset

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)

    }

ANCHOR repetitionConstraint

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)
	}

ANCHOR repetitionConstraintReset

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
    }

ANCHOR resetCount2

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
	}

ANCHOR sporadicConstraint

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))

ANCHOR sporadicConstraintReset

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))

ANCHOR stillFulfillable

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}
}

ANCHOR stillFulfillableReset

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
	}

ANCHOR strongDelayConstraint

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)

ANCHOR strongDelayConstraintReset

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)

}

ANCHOR StrongSynchronizationConstraint10

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)

ANCHOR StrongSynchronizationConstraint2

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)

ANCHOR StrongSynchronizationConstraint3

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)

ANCHOR StrongSynchronizationConstraint4

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)

ANCHOR StrongSynchronizationConstraint5

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)

ANCHOR StrongSynchronizationConstraint6

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)

ANCHOR StrongSynchronizationConstraint7

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)

ANCHOR StrongSynchronizationConstraint8

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)

ANCHOR StrongSynchronizationConstraint9

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)

ANCHOR StrongSynchronizationConstraintReset

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
    }

ANCHOR StrongSynchronizationConstraintReset10

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)
    }

ANCHOR StrongSynchronizationConstraintReset2

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)
    }

ANCHOR StrongSynchronizationConstraintReset3

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)
    }

ANCHOR StrongSynchronizationConstraintReset4

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)
    }

ANCHOR StrongSynchronizationConstraintReset5

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)
    }

ANCHOR StrongSynchronizationConstraintReset6

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)
    }

ANCHOR StrongSynchronizationConstraintReset7

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)
    }

ANCHOR StrongSynchronizationConstraintReset8

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)
    }

ANCHOR StrongSynchronizationConstraintReset9

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)
    }

ANCHOR synchronizationConstraint10

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)

ANCHOR synchronizationConstraint2

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)

ANCHOR synchronizationConstraint2Reset

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)
}

ANCHOR synchronizationConstraint3

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)

ANCHOR synchronizationConstraint4

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)

ANCHOR synchronizationConstraint5

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)

ANCHOR synchronizationConstraint6

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)

ANCHOR synchronizationConstraint7

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)

ANCHOR synchronizationConstraint8

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)

ANCHOR synchronizationConstraint9

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)

ANCHOR synchronizationConstraintReset

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
    }

ANCHOR synchronizationConstraintReset10

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)
}

ANCHOR synchronizationConstraintReset3

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)
    }

ANCHOR synchronizationConstraintReset4

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)
}

ANCHOR synchronizationConstraintReset5

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)
}

ANCHOR synchronizationConstraintReset6

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)
}

ANCHOR synchronizationConstraintReset7

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)
}

ANCHOR synchronizationConstraintReset8

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)
}

ANCHOR synchronizationConstraintReset9

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)
}