Order Management is a simulated OCEL 2.0 log of a company that handles orders: 21,008 events and 10,840 objects of six types (orders, items, products, customers, employees, packages). This example discovers object-centric constraints, checks which hold least well, and then looks at one object type with classic tools.
import r4pm
# 1. Load the OCEL.
ocel = r4pm.import_item("SlimLinkedOCEL", "data/order-management.xml.gz")
tables = r4pm.item_to_df(ocel)
print(tables["events"].height, "events,", tables["objects"].height, "objects")
# 2. Discover OC-DECLARE constraints (default options).
arcs = r4pm.bindings.discover_oc_declare(ocel)
print(len(arcs), "constraints")
# 3. Score every constraint and show the weakest ones (ties by name, so the output is stable).
scores = sorted(
(r4pm.bindings.oc_declare_conformance(ocel, arc), f"{arc['arc_type']}({arc['from']}, {arc['to']})")
for arc in arcs
)
for share, text in scores[:3]:
print(f" {share:.1%} {text}")
# 4. Flatten on orders and analyze them case-centrically.
orders = r4pm.bindings.flatten_ocel_on(ocel, "orders")
projection = r4pm.bindings.log_to_activity_projection(orders)
net = r4pm.bindings.discover_alphaplusplusplus(projection)
fitness = r4pm.bindings.compute_fitness(r4pm.bindings.align_variants(net, projection), net)
print(r4pm.bindings.get_num_cases(projection), "orders, log fitness", f"{fitness['log_fitness']:.3f}")21008 events, 10840 objects
116 constraints
81.0% DF(send package, package delivered)
81.0% DP(package delivered, send package)
81.8% EP(create package, reorder item)
2000 orders, log fitness 1.000Python and Rust print the same lines. Constraints with the same score are sorted by name, because the discovery order can differ between runs. Alpha+++ also prints about 20 lines of progress information, which the output above leaves out.
Reading the result
116 constraints. With the default noise threshold of 0.2, every discovered constraint holds for at least 80% of the relevant events. Scoring them with oc_declare_conformance and sorting shows the weakest ones, which are the most interesting to look at.
The weakest constraints. DF(send package, package delivered) holds for 81.0% of events: For about one in five sent packages, the next event involving that package is not the delivery. The log has 311 failed delivery events for 1,128 sent packages, and a failed delivery between sending and delivery breaks the constraint.
One object type at a time. Flattening on orders gives one trace per order (2,000 traces). Their life cycle is simple, so Alpha+++ with default settings finds a model that fits every order perfectly. The complex behavior of this process is in how orders, items and packages interact, which is exactly what the object-centric constraints capture and the flattened log loses.
Next steps
- Analyze object-centric data explains the OC-DECLARE notation and arc types.
- Flatten on
itemsorpackagesinstead ofordersand compare the fitness. - Load the same file in Propel to explore the OCEL interactively.
- OCPQ queries and analyzes OCEL 2.0 logs like this one interactively.