[1]:
import warnings
warnings.filterwarnings("ignore", category=UserWarning)

Conformance Checking with a LTLf model

The class ProcessMiningTasks.ConformanceChecking.LTLAnalyzer.LTLAnalyzer provides a way to check if the log conforms to a Linear Temporal Logic on finite traces (LTLf) formula. The formula can be a provided by the user as a string, note that we adopted the LTLf syntax here. In addition, we also provide the following set of LTLf templates:

  1. eventually_a;

  2. next_a;

  3. eventually_a_and_eventually_b;

  4. eventually_a_then_b;

  5. eventually_a_or_b;

  6. eventually_a_next_b;

  7. eventually_a_then_b_then_c;

  8. eventually_a_next_b_next_c;

the following set of LTLf templates called Is First (Last):

  1. is_first_state_a;

  2. is_second_state_a;

  3. is_third_state_a;

  4. last;

  5. second_last;

  6. third_last;

  7. is_last_state_a;

  8. is_second_last_state_a;

  9. is_third_last_state_a;

the following set of LTLf templates with multiple attributes:

  1. p_does_a;

  2. a_is_done_by_p_and_q;

  3. p_does_a_and_b;

  4. p_does_a_and_then_b;

  5. p_does_a_and_eventually_b;

  6. p_does_a_a_not_b;

  7. a_done_by_p_p_not_q;

and the following Target-Branched DECLARE templates:

  1. precedence;

  2. chain_precedence;

  3. responded_existence;

  4. chain_response;

  5. not_chain_precedence;

  6. not_chain_response;

  7. response;

  8. not_precedence;

  9. not_response;

  10. not_responded_existence;

  11. alternate_response;

  12. alternate_precedence.

First of all, an event log has to be imported.

[2]:
import os
from Declare4Py.D4PyEventLog import D4PyEventLog

log_path = os.path.join("../../../", "tests", "test_logs","Sepsis Cases.xes.gz")
event_log = D4PyEventLog()
event_log.parse_xes_log(log_path)

The next step is to create an LTLModel from an input LTLf formula in string format with the class ProcessModels.LTLModel.LTLModel and pass it to the LTL conformance checker implemented in the src.Declare4Py.ProcessMiningTasks.ConformanceChecking.LTLAnalyzer.LTLAnalyzer class. The corresponding method run will do the conformance checking and return a Pandas dataframe. This dataframe contains the traces ids in the first column and the results of the conformance checking in the second column. The run method transforms the LTLf formula into a Deterministic Finite state Automaton (DFA) and checks whether a trace in a log is accepted. This transformation is performed by using two backends:

  • Lydia, C++ backend that needs to be installed with Docker, more details here;

  • LTLf2DFA, that needs to be installed with pip install git+https://github.com/whitemech/LTLf2DFA.git@develop#egg=ltlf2dfa. More details here.

As explained in the tutorial regarding process models, it is possible to switch the backends of the LTLf model with the to_ltlf2dfa_backend and to_lydia_backend methods. The default backend is Lydia.

For speeding up the computation, the run method takes as input the integer parameter jobs that sets the number of processes to run in parallel. Each process considers a portion of the input event log. The default value of the number of jobs is 1. Note that, with small logs (i.e., with a small number of events) the performance with multiple jobs can be comparable with the ones of a single job.

We show an example of LTLf conformance checking with the F(ER Triage) formula.

[3]:
from Declare4Py.ProcessModels.LTLModel import LTLModel
from Declare4Py.ProcessMiningTasks.ConformanceChecking.LTLAnalyzer import LTLAnalyzer

model = LTLModel()
model.parse_from_string("F(CRP)")

analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run(jobs=2)
conf_check_res_df
[3]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA False
1047 JNA False
1048 KNA False
1049 LNA False

1050 rows × 2 columns

Conformance Checking with LTLf Templates

Declare4Py offers some LTLf templates in the src.Declare4Py.ProcessModels.LTLModel.LTLTemplate class. You just need to instantiate a single template by passing the template name to the LTLTemplate class and then filling the template with some proper activities to obtain an LTLModel and run the LTL checker.

The LTLTemplate’s function fill_template expects a list with the parameters equal to those expected by the template and a list of attribute types and returns an LTLModel object containing the parsed formula of the template and the list of attribute types. The LTLf formula of the template can be retrieved by accessing the formula attribute of the LTLModel object.

eventually_a

This is a unary template taking one activity as input. The corresponding LTLf formula is F(a).

[4]:
from Declare4Py.ProcessModels.LTLModel import LTLTemplate

template: LTLTemplate = LTLTemplate('eventually_a')
model: LTLModel = template.fill_template(['CRP'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_crp)
[4]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA False
1047 JNA False
1048 KNA True
1049 LNA False

1050 rows × 2 columns

next_a

This is a unary template taking one activity as input. The corresponding LTLf formula is X(a).

[5]:
template = LTLTemplate('next_a')
model = template.fill_template(['ER Triage'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: X[!](con_ertriage)
[5]:
case:concept:name accepted
0 A False
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA True
1047 JNA True
1048 KNA True
1049 LNA True

1050 rows × 2 columns

eventually_a_and_eventually_b

This is a binary template taking two activities as input. The corresponding LTLf formula is F(a) && F(b).

[6]:
template = LTLTemplate('eventually_a_and_eventually_b')
model = template.fill_template(['Leucocytes', 'CRP'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_leucocytes)  && F(con_crp)
[6]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA False
1047 JNA False
1048 KNA True
1049 LNA False

1050 rows × 2 columns

eventually_a_then_b

This is a binary template taking two activities as input. The corresponding LTLf formula is F(a && F(b)).

[7]:
template = LTLTemplate('eventually_a_then_b')
model = template.fill_template(['Leucocytes', 'CRP'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_leucocytes  && F(con_crp))
[7]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D True
4 E False
... ... ...
1045 HNA True
1046 INA False
1047 JNA False
1048 KNA True
1049 LNA False

1050 rows × 2 columns

eventually_a_or_b

This is a binary template taking two activities as input. The corresponding LTLf formula is F(a) || F(b).

[8]:
template = LTLTemplate('eventually_a_or_b')
model = template.fill_template(['Leucocytes', 'CRP'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_leucocytes) || F(con_crp)
[8]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA False
1047 JNA False
1048 KNA True
1049 LNA False

1050 rows × 2 columns

eventually_a_next_b

This is a binary template taking two activities as input. The corresponding LTLf formula is F(a && X(b)).

[9]:
template = LTLTemplate('eventually_a_next_b')
model = template.fill_template(['Leucocytes', 'CRP'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_leucocytes  && X[!](con_crp))
[9]:
case:concept:name accepted
0 A True
1 B False
2 C True
3 D True
4 E False
... ... ...
1045 HNA True
1046 INA False
1047 JNA False
1048 KNA True
1049 LNA False

1050 rows × 2 columns

eventually_a_then_b_then_c

This is a ternary template taking three activities as input. The corresponding LTLf formula is F(a && F(b && F(c))).

[10]:
template = LTLTemplate('eventually_a_then_b_then_c')
model = template.fill_template(['ER Registration', 'Leucocytes', 'CRP'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_erregistration  && F(con_leucocytes  && F(con_crp)))
[10]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D True
4 E False
... ... ...
1045 HNA True
1046 INA False
1047 JNA False
1048 KNA True
1049 LNA False

1050 rows × 2 columns

eventually_a_next_b_next_c

This is a ternary template taking three activities as input. The corresponding LTLf formula is F(a && X(b && X(c))).

[11]:
template = LTLTemplate('eventually_a_next_b_next_c')
model = template.fill_template(['ER Registration', 'CRP', 'Leucocytes'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_erregistration  && X[!](con_crp  && X[!](con_leucocytes)))
[11]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA False
1047 JNA False
1048 KNA False
1049 LNA False

1050 rows × 2 columns

Conformance Checking with LTLf Templates Is First (Last)

These templates follow the same structure as the one used for simple LTLf templates. The fill_template method takes a list of generic attributes and a list of attribute types that match the type of the attributes in the first list. If the type of the attribute is ‘concept:name’ then the second list can be omitted.

is_first_state_a

This formula identifies all traces where attribute A is performed in the first event.

[12]:
template: LTLTemplate = LTLTemplate('is_first_state_a')
model : LTLModel = template.fill_template(['ER Registration'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: con_erregistration
[12]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA True
1047 JNA True
1048 KNA True
1049 LNA True

1050 rows × 2 columns

is_second_state_a

This formula identifies all traces where attribute A is performed in the second event.

[13]:
template: LTLTemplate = LTLTemplate('is_second_state_a')
model : LTLModel = template.fill_template(['ER Triage'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: X[!](con_ertriage)
[13]:
case:concept:name accepted
0 A False
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA True
1047 JNA True
1048 KNA True
1049 LNA True

1050 rows × 2 columns

is_third_state_a

This formula identifies all traces where attribute A is performed in the third event.

[14]:
template: LTLTemplate = LTLTemplate('is_third_state_a')
model : LTLModel = template.fill_template(['ER Sepsis Triage'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: X[!](X[!](con_ersepsistriage))
[14]:
case:concept:name accepted
0 A False
1 B False
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA True
1047 JNA True
1048 KNA True
1049 LNA True

1050 rows × 2 columns

last

This formula identifies all traces where the attribute is guaranteed to change in the very next event. This formula takes an empty list as parameter.

[15]:
template: LTLTemplate = LTLTemplate('last')
model : LTLModel = template.fill_template([])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: !(X[!](true))
[15]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA False
1047 JNA False
1048 KNA False
1049 LNA False

1050 rows × 2 columns

second_last

This formula identifies all traces where at some point, there will be a change in the activity, indicating that it is not always equal to its previous event. This formula takes an empty list as parameter.

[16]:
template: LTLTemplate = LTLTemplate('second_last')
model : LTLModel = template.fill_template([])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: X[!](!(X[!](true)))
[16]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA False
1047 JNA False
1048 KNA False
1049 LNA False

1050 rows × 2 columns

third_last

This formula identifies all traces where there will be a change in the activity in the very next time step and that this change will persist at least once more in the future. This formula takes an empty list as parameter.

[17]:
template: LTLTemplate = LTLTemplate('third_last')
model : LTLModel = template.fill_template([])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: X[!](X[!](!(X[!](true))))
[17]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA True
1047 JNA True
1048 KNA False
1049 LNA True

1050 rows × 2 columns

is_last_state_a

This formula identifies all traces where attribute A is performed in the last event.

[18]:
template: LTLTemplate = LTLTemplate('is_last_state_a')
model : LTLModel = template.fill_template(['Release A'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_releasea  &&  !(X[!](true)))
[18]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D False
4 E False
... ... ...
1045 HNA True
1046 INA False
1047 JNA False
1048 KNA True
1049 LNA False

1050 rows × 2 columns

is_second_last_state_a

This formula identifies all traces where attribute A is performed in the penultimate event.

[19]:
template: LTLTemplate = LTLTemplate('is_second_last_state_a')
model : LTLModel = template.fill_template(['Leucocytes'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_leucocytes  && X[!](!(X[!](true))))
[19]:
case:concept:name accepted
0 A True
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA False
1047 JNA False
1048 KNA False
1049 LNA False

1050 rows × 2 columns

is_third_last_state_a

This formula identifies all traces where attribute A is performed in the third-last event.

[20]:
template: LTLTemplate = LTLTemplate('is_third_last_state_a')
model : LTLModel = template.fill_template(['CRP'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_crp  && X[!](X[!](!(X[!](true)))))
[20]:
case:concept:name accepted
0 A True
1 B True
2 C False
3 D True
4 E False
... ... ...
1045 HNA False
1046 INA False
1047 JNA False
1048 KNA False
1049 LNA False

1050 rows × 2 columns

Conformance Checking with LTLf Templates with multiple attributes

For these templates, the fill_template method takes a list of generic attributes (in string format) and a list of attribute types (also strings) as parameters. The order of the elements of these two lists is important. For each template, the instantiated template formula and its corresponding checking in the input log will be computed.

p_does_a

[21]:
template: LTLTemplate = LTLTemplate('p_does_a')
model : LTLModel = template.fill_template(['A', 'ER Registration'], attr_type=['org:group', 'concept:name'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(org_a  && con_erregistration)
[21]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA True
1047 JNA True
1048 KNA True
1049 LNA False

1050 rows × 2 columns

a_is_done_by_p_and_q

[22]:
template: LTLTemplate = LTLTemplate('a_is_done_by_p_and_q')
model : LTLModel = template.fill_template(['A', 'B', 'ER Registration'], attr_type=['org:group', 'concept:name'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: (F(F(org_a  && con_erregistration))  && F(F(org_b  && con_erregistration)))
[22]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA False
1047 JNA False
1048 KNA False
1049 LNA False

1050 rows × 2 columns

p_does_a_and_b

[23]:
template: LTLTemplate = LTLTemplate('p_does_a_and_b')
model : LTLModel = template.fill_template(['A', 'ER Registration', 'Leucocytes'], attr_type=['org:group', 'concept:name'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: (F(F(org_a  &&  con_erregistration))  && F(F(org_a  &&  con_leucocytes)))
[23]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA False
1047 JNA False
1048 KNA False
1049 LNA False

1050 rows × 2 columns

p_does_a_and_then_b

[24]:
template: LTLTemplate = LTLTemplate('p_does_a_and_then_b')
model : LTLModel = template.fill_template(['A', 'ER Registration', 'Leucocytes'], attr_type=['org:group', 'concept:name'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F((F(org_a  && con_erregistration)  && X[!](F(org_a  && con_leucocytes))))
[24]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA False
1047 JNA False
1048 KNA False
1049 LNA False

1050 rows × 2 columns

p_does_a_and_eventually_b

[25]:
template: LTLTemplate = LTLTemplate('p_does_a_and_eventually_b')
model : LTLModel = template.fill_template(['A', 'ER Registration', 'Leucocytes'], attr_type=['org:group', 'concept:name'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F((F(org_a  && con_erregistration)  && F(F(org_a  && con_leucocytes))))
[25]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA False
1047 JNA False
1048 KNA False
1049 LNA False

1050 rows × 2 columns

p_does_a_a_not_b

[26]:
template: LTLTemplate = LTLTemplate('p_does_a_a_not_b')
model : LTLModel = template.fill_template(['A', 'ER Registration', 'Leucocytes'], attr_type=['org:group', 'concept:name'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F((con_erregistration  &&  (!con_leucocytes  && org_a)))
[26]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA True
1047 JNA True
1048 KNA True
1049 LNA False

1050 rows × 2 columns

a_done_by_p_p_not_q

[27]:
template = LTLTemplate('a_done_by_p_p_not_q')
model = template.fill_template(['A', 'B', 'ER Registration'], attr_type=['org:group', 'concept:name'])
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F((org_a  &&   (!org_b  && con_erregistration)))
[27]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA True
1047 JNA True
1048 KNA True
1049 LNA False

1050 rows × 2 columns

Conformance Checking with Target-Branched DECLARE templates

For these binary templates, the fill_template method takes two lists of activities (in string format) as parameters. For each template, the instantiated template formula and its corresponding checking in the input log will be computed.

precedence

[28]:
template = LTLTemplate('precedence')
activities_a = ["ER Triage", "CRP"]
activities_b = ["Leucocytes", "Admission NC", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: ((!(con_leucocytes || con_admissionnc || con_releasea))U(con_ertriage || con_crp)) || G(!(con_leucocytes || con_admissionnc || con_releasea))
[28]:
case:concept:name accepted
0 A False
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA True
1047 JNA True
1048 KNA True
1049 LNA True

1050 rows × 2 columns

chain_precedence

[29]:
template = LTLTemplate('chain_precedence')
activities_a = ["ER Triage", "CRP", "Leucocytes"]
activities_b = ["Leucocytes", "Admission NC", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: G(X[!](con_leucocytes || con_admissionnc || con_releasea) ->  (con_ertriage || con_crp || con_leucocytes))
[29]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E True
... ... ...
1045 HNA False
1046 INA True
1047 JNA True
1048 KNA False
1049 LNA True

1050 rows × 2 columns

responded_existence

[30]:
template = LTLTemplate('responded_existence')
activities_a = ["ER Triage", "CRP", "Leucocytes"]
activities_b = ["Leucocytes", "Admission NC", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_ertriage || con_crp || con_leucocytes) -> F(con_leucocytes || con_admissionnc || con_releasea)
[30]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA False
1047 JNA False
1048 KNA True
1049 LNA False

1050 rows × 2 columns

chain_response

[31]:
template = LTLTemplate('chain_response')
activities_a = ["ER Registration", "CRP"]
activities_b = ["ER Triage", "Leucocytes", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: G((con_erregistration  || con_crp) -> X[!](con_ertriage || con_leucocytes || con_releasea))
[31]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E True
... ... ...
1045 HNA False
1046 INA True
1047 JNA True
1048 KNA False
1049 LNA True

1050 rows × 2 columns

not_chain_precedence

[32]:
template = LTLTemplate('not_chain_precedence')
activities_a = ["ER Triage", "CRP", "Leucocytes"]
activities_b = ["Leucocytes", "Admission NC", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: G(X[!](con_leucocytes || con_admissionnc || con_releasea) ->  !(con_ertriage || con_crp || con_leucocytes))
[32]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA True
1047 JNA True
1048 KNA False
1049 LNA True

1050 rows × 2 columns

not_chain_response

[33]:
template = LTLTemplate('not_chain_response')
activities_a = ["ER Triage", "CRP", "Leucocytes"]
activities_b = ["Leucocytes", "Admission NC", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: G((con_ertriage || con_crp || con_leucocytes) -> X[!](!(con_leucocytes || con_admissionnc || con_releasea)))
[33]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA True
1047 JNA True
1048 KNA False
1049 LNA True

1050 rows × 2 columns

response

[34]:
template = LTLTemplate('response')
activities_a = ["ER Triage", "CRP", "Leucocytes"]
activities_b = ["Leucocytes", "Admission NC", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: G((con_ertriage || con_crp || con_leucocytes) -> F(con_leucocytes || con_admissionnc || con_releasea))
[34]:
case:concept:name accepted
0 A True
1 B True
2 C True
3 D True
4 E True
... ... ...
1045 HNA True
1046 INA False
1047 JNA False
1048 KNA True
1049 LNA False

1050 rows × 2 columns

not_precedence

[35]:
template = LTLTemplate('not_precedence')
activities_a = ["ER Triage", "CRP", "Leucocytes"]
activities_b = ["Leucocytes", "Admission NC", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: G(F(con_leucocytes || con_admissionnc || con_releasea) -> !(con_ertriage || con_crp || con_leucocytes))
[35]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA True
1047 JNA True
1048 KNA False
1049 LNA True

1050 rows × 2 columns

not_response

[36]:
template = LTLTemplate('not_response')
activities_a = ["ER Triage", "CRP", "Leucocytes"]
activities_b = ["Leucocytes", "Admission NC", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: G((con_ertriage || con_crp || con_leucocytes) ->  !(F(con_leucocytes || con_admissionnc || con_releasea)))
[36]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA True
1047 JNA True
1048 KNA False
1049 LNA True

1050 rows × 2 columns

not_responded_existence

[37]:
template = LTLTemplate('not_responded_existence')
activities_a = ["ER Triage", "CRP", "Leucocytes"]
activities_b = ["Leucocytes", "Admission NC", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: F(con_ertriage || con_crp || con_leucocytes) ->  !(F(con_leucocytes || con_admissionnc || con_releasea))
[37]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA True
1047 JNA True
1048 KNA False
1049 LNA True

1050 rows × 2 columns

alternate_response

[38]:
template = LTLTemplate('alternate_response')
activities_a = ["ER Triage", "CRP", "Leucocytes"]
activities_b = ["Leucocytes", "Admission NC", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: G((con_ertriage || con_crp || con_leucocytes) -> X[!]((!(con_ertriage || con_crp || con_leucocytes)U(con_leucocytes || con_admissionnc || con_releasea))))
[38]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA False
1047 JNA False
1048 KNA False
1049 LNA False

1050 rows × 2 columns

alternate_precedence

[39]:
template = LTLTemplate('alternate_precedence')
activities_a = ["ER Triage", "CRP", "Leucocytes"]
activities_b = ["Leucocytes", "Admission NC", "Release A"]
model = template.fill_template(activities_a, activities_b)
print(f"Formula: {model.formula}")
analyzer = LTLAnalyzer(event_log, model)
conf_check_res_df = analyzer.run()
conf_check_res_df
Formula: ((!(con_leucocytes || con_admissionnc || con_releasea))U(con_ertriage || con_crp || con_leucocytes))  && G((con_leucocytes || con_admissionnc || con_releasea) -> X[!]((!(con_leucocytes || con_admissionnc || con_releasea))U(con_ertriage || con_crp || con_leucocytes)) || G(!(con_leucocytes || con_admissionnc || con_releasea)))
[39]:
case:concept:name accepted
0 A False
1 B False
2 C False
3 D False
4 E False
... ... ...
1045 HNA False
1046 INA True
1047 JNA True
1048 KNA False
1049 LNA True

1050 rows × 2 columns