Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions All.sln
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{92C02EAF-93FB-4A2C-A235-8541D893163C}"
ProjectSection(SolutionItems) = preProject
scripts\macos\generate_grpc_models.sh = scripts\macos\generate_grpc_models.sh
scripts\windows\generate_grpc_models.ps1 = scripts\windows\generate_grpc_models.ps1
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "misc", "misc", "{2918C7E3-3FC8-48A5-ADDF-8358E888B40C}"
Expand Down
2 changes: 1 addition & 1 deletion Ficus/docker/run/Run.RustFicusBackend.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM rust:1.92.0 as build
FROM rust:1.93.0 as build

RUN apt update -y && apt upgrade -y
RUN apt-get update -y
Expand Down
2 changes: 1 addition & 1 deletion Ficus/docker/tests/Tests.Rust.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM rust:1.92.0 as build
FROM rust:1.93.0 as build

RUN apt update -y && apt upgrade -y
RUN apt-get update -y
Expand Down
6 changes: 5 additions & 1 deletion Ficus/src/python/infra/generate_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ def generate_models():

os.mkdir(models_dir)

python = '/usr/local/bin/python3'
if os.name == 'nt':
python = 'python'
else:
python = '/usr/local/bin/python3'

os.popen(f'{python} -m pip install grpcio-tools').read()
packages = []

Expand Down
13 changes: 2 additions & 11 deletions Ficus/src/rust/ficus/src/event_log/xes/xes_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,14 @@ use crate::{
},
};
use chrono::{DateTime, Utc};
use std::{
collections::HashMap,
fmt::{Debug, Formatter},
sync::Arc,
};
use std::{collections::HashMap, fmt::Debug, sync::Arc};

#[derive(Debug)]
pub struct XesEventImpl {
event_base: EventBase,
payload: Option<HashMap<Arc<str>, EventPayloadValue>>,
}

impl Debug for XesEventImpl {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(self.name_pointer())
}
}

impl XesEventImpl {
pub fn new_all_fields(name: Arc<str>, timestamp: DateTime<Utc>, payload: Option<HashMap<Arc<str>, EventPayloadValue>>) -> Self {
Self {
Expand Down
20 changes: 3 additions & 17 deletions Ficus/src/rust/ficus/src/features/clustering/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use crate::{
pipelines::errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError},
utils::dataset::dataset::LabeledDataset,
};
use std::fmt::Display;

pub type ClusteringResult = Result<LabeledDataset, ClusteringError>;

#[derive(Debug)]
pub enum ClusteringError {
NoRepeatSet,
FailedToCreateNdArray,
Expand All @@ -14,21 +14,7 @@ pub enum ClusteringError {
}

impl From<ClusteringError> for PipelinePartExecutionError {
fn from(val: ClusteringError) -> Self {
PipelinePartExecutionError::Raw(RawPartExecutionError::new(val.to_string()))
}
}

impl Display for ClusteringError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(
match self {
Self::NoRepeatSet => "NoRepeatSet".to_owned(),
Self::FailedToCreateNdArray => "FailedToCreateNdArray".to_owned(),
Self::FailedToCalculateSilhouetteScore => "FailedToCalculateSilhouetteScore".to_owned(),
Self::RawError(message) => message.clone(),
}
.as_str(),
)
fn from(err: ClusteringError) -> Self {
PipelinePartExecutionError::Raw(RawPartExecutionError::new(format!("{err:?}")))
}
}
8 changes: 2 additions & 6 deletions Ficus/src/rust/ficus/src/features/discovery/alpha/alpha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,7 @@ fn add_one_length_loops(provider: &impl AlphaPlusRelationsProvider, original_log
}
}

let id = petri_net.add_transition(Transition::empty(
transition_name.to_owned(),
false,
Some(transition_name.to_owned()),
));
let id = petri_net.add_transition(Transition::empty(transition_name.to_owned(), Some(transition_name.to_owned())));

let place_id = match petri_net.find_place_id_by_name(alpha_set.to_string().as_str()) {
Some(found_place_id) => found_place_id,
Expand Down Expand Up @@ -196,7 +192,7 @@ fn create_petri_net(info: &dyn EventLogInfo, alpha_sets: Vec<&AlphaSet>) -> Defa
let mut petri_net = PetriNet::default();
let mut event_classes_to_transition_ids = HashMap::new();
for class in info.all_event_classes() {
let id = petri_net.add_transition(Transition::empty(class.to_owned(), false, Some(class.to_owned())));
let id = petri_net.add_transition(Transition::empty(class.to_owned(), Some(class.to_owned())));
event_classes_to_transition_ids.insert(class.as_ref(), id);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ pub fn discover_petri_net_alpha_plus_plus_nfc<TLog: EventLog>(log: &TLog) -> Def
let mut resulting_net = DefaultPetriNet::default();
let mut transitions_to_ids = HashMap::new();
for transition in info.all_event_classes().iter().copied().chain(one_length_loop_transitions.iter()) {
let id = resulting_net.add_transition(Transition::empty((*transition).to_owned(), false, Some((*transition).to_owned())));
let id = resulting_net.add_transition(Transition::empty((*transition).to_owned(), Some((*transition).to_owned())));
transitions_to_ids.insert(transition, id);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ fn connect_added_merged_node_to_graph(nodes_ids: &NeededNodesIds, added_node: &u
added_node,
NodesConnectionData::new(None, start_node_edge_weight, None),
);

graph.connect_nodes(
added_node,
&nodes_ids.end_node,
Expand Down
1 change: 1 addition & 0 deletions Ficus/src/rust/ficus/src/features/discovery/ecfg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ pub mod discovery_xes;
pub mod log_prepare;
pub mod models;
pub mod root_sequence;
pub mod to_petri_net;
42 changes: 42 additions & 0 deletions Ficus/src/rust/ficus/src/features/discovery/ecfg/to_petri_net.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::{
features::discovery::petri_net::{petri_net::DefaultPetriNet, place::Place, transition::Transition},
utils::graph::graph::DefaultGraph,
};
use std::{collections::HashMap, sync::Arc};

pub fn convert_to_petri_net(graph: &DefaultGraph) -> Result<DefaultPetriNet, ()> {
if graph.all_nodes().is_empty() {
return Ok(Default::default());
}

let mut petri_net = DefaultPetriNet::default();

let mut next_place_id = 0;
let mut nodes_data = HashMap::new();

for node in graph.all_nodes() {
let name = Arc::clone(node.data.as_ref().expect("must have name for all transitions"));
let t_id = petri_net.add_transition(Transition::empty(name.clone(), Some(name.clone())));

let in_place = petri_net.add_place(Place::with_name(format!("{next_place_id}")));
let out_place = petri_net.add_place(Place::with_name(format!("{}", next_place_id + 1)));

petri_net.connect_place_to_transition(&in_place, &t_id, None);
petri_net.connect_transition_to_place(&t_id, &out_place, None);

nodes_data.insert(node.id, (in_place, out_place));
next_place_id += 2;
}

for edge in graph.all_edges() {
let from_place = nodes_data[edge.from_node()].1;
let to_place = nodes_data[edge.to_node()].0;

let s_t = petri_net.add_transition(Transition::silent());

petri_net.connect_place_to_transition(&from_place, &s_t, None);
petri_net.connect_transition_to_place(&s_t, &to_place, None);
}

Ok(petri_net)
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn discover_petri_net_heuristic(
fn construct_heuristic_petri_net(provider: &HeuristicMinerRelationsProvider, petri_net: &mut DefaultPetriNet) {
let mut classes_to_ids = HashMap::new();
for class in provider.log_info().all_event_classes() {
let id = petri_net.add_transition(Transition::empty(class.to_owned(), false, Some(class.to_owned())));
let id = petri_net.add_transition(Transition::empty(class.to_owned(), Some(class.to_owned())));
classes_to_ids.insert(class.to_owned(), id);
}

Expand Down Expand Up @@ -92,8 +92,7 @@ fn construct_heuristic_petri_net(provider: &HeuristicMinerRelationsProvider, pet
petri_net.connect_transition_to_place(classes_to_ids.get(first_class).unwrap(), &post_place_id, None);

for group in &parallel_groups {
let name = Arc::<str>::from(format!("silent_start_{first_class}"));
let id = petri_net.add_transition(Transition::empty(name.to_owned(), true, Some(name.to_owned())));
let id = petri_net.add_transition(Transition::silent());
petri_net.connect_place_to_transition(&post_place_id, &id, None);

for el in group.set().iter() {
Expand All @@ -103,7 +102,7 @@ fn construct_heuristic_petri_net(provider: &HeuristicMinerRelationsProvider, pet

used.insert(*el);
}
}
};

for follower in &followers {
if !used.contains(follower) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ struct PlaceTransitions {
outgoing_transitions: Vec<u64>,
}

pub const EMPTY_PLACE_TRANSITIONS: &PlaceTransitions = &PlaceTransitions {
incoming_transitions: vec![],
outgoing_transitions: vec![],
};

#[derive(Debug, Default)]
pub struct PetriNet<TTransitionData, TArcData>
where
Expand Down Expand Up @@ -50,10 +55,10 @@ where
id
}

pub fn connect_place_to_transition(&mut self, from_place_id: &u64, to_transition_index: &u64, arc_data: Option<TArcData>) {
pub fn connect_place_to_transition(&mut self, from_place_id: &u64, to_transition_id: &u64, arc_data: Option<TArcData>) {
self
.transitions
.get_mut(to_transition_index)
.get_mut(to_transition_id)
.unwrap()
.add_incoming_arc(from_place_id, arc_data);

Expand All @@ -63,7 +68,7 @@ where
.get_mut(from_place_id)
.unwrap()
.outgoing_transitions
.push(*to_transition_index);
.push(*to_transition_id);
}

fn init_places_transitions(&mut self, place_id: &u64) {
Expand Down Expand Up @@ -160,7 +165,7 @@ where
}

fn get_place_transitions(&self, place_id: &u64) -> &PlaceTransitions {
self.places_to_transitions.get(place_id).unwrap()
self.places_to_transitions.get(place_id).unwrap_or(EMPTY_PLACE_TRANSITIONS)
}

fn map_transitions(&self, ids: &[u64]) -> Vec<&Transition<TTransitionData, TArcData>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
features::discovery::petri_net::{arc::PetriNetArc, petri_net::PetriNet, place::Place, transition::Transition},
utils::xml_utils::{StartEndElementCookie, XmlWriteError},
};
use log::trace;
use quick_xml::{
Writer,
events::{BytesText, Event},
Expand All @@ -16,6 +17,14 @@ const NET_TAG_NAME: &str = "net";
const TEXT_TAG_NAME: &str = "text";
const NAME_TAG_NAME: &str = "name";

const TOOL_SPECIFIC_TAG_NAME: &str = "toolspecific";
const TOOL_ATTR_NAME: &str = "tool";
const PROM_VALUE: &str = "ProM";
const VERSION_ATTR_NAME: &str = "version";
const VERSION_VALUE: &str = "6.4";
const ACTIVITY_ATTR_NAME: &str = "activity";
const SILENT_ACTIVITY: &str = "$invisible$";

const ID_ATTR_NAME: &str = "id";
const SOURCE_ATTR_NAME: &str = "source";
const TARGET_ATTR_NAME: &str = "target";
Expand Down Expand Up @@ -116,6 +125,18 @@ where
drop(name);
}

if transition.is_silent() {
let _ = StartEndElementCookie::new_with_attrs(
writer,
TOOL_SPECIFIC_TAG_NAME,
&vec![
(TOOL_ATTR_NAME, PROM_VALUE),
(VERSION_ATTR_NAME, VERSION_VALUE),
(ACTIVITY_ATTR_NAME, SILENT_ACTIVITY),
],
);
}

drop(cookie)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,32 @@ where
}
}

impl Transition<Arc<str>, ()> {
pub fn silent() -> Self {
const NAME: &str = "tau";

Self {
id: next_id(),
name: Arc::from(NAME),
silent_transition: true,
incoming_arcs: vec![],
outgoing_arcs: vec![],
data: Some(Arc::from(NAME)),
}
}
}

impl<TTransitionData, TArcData> Transition<TTransitionData, TArcData>
where
TTransitionData: ToString,
{
pub fn empty(name: Arc<str>, silent_transition: bool, data: Option<TTransitionData>) -> Self {
pub fn empty(name: Arc<str>, data: Option<TTransitionData>) -> Self {
Self {
id: next_id(),
name,
silent_transition,
incoming_arcs: Vec::new(),
outgoing_arcs: Vec::new(),
silent_transition: false,
incoming_arcs: vec![],
outgoing_arcs: vec![],
data,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use getset::{Getters, MutGetters};
use std::{
cell::RefCell,
collections::HashMap,
error::Error,
fmt::{Debug, Display, Formatter},
ops::Deref,
rc::Rc,
Expand Down Expand Up @@ -74,16 +73,11 @@ pub struct TraceThreadEvent {
stamp: i64,
}

#[derive(Debug)]
pub enum LogThreadsDiagramError {
NotSupportedEventStamp,
}

impl Debug for LogThreadsDiagramError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(self, f)
}
}

impl Display for LogThreadsDiagramError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Expand All @@ -92,8 +86,6 @@ impl Display for LogThreadsDiagramError {
}
}

impl Error for LogThreadsDiagramError {}

impl From<LogThreadsDiagramError> for PipelinePartExecutionError {
fn from(val: LogThreadsDiagramError) -> Self {
PipelinePartExecutionError::Raw(RawPartExecutionError::new(val.to_string()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::{
};
use std::{
cell::RefCell,
error::Error,
fmt::{Debug, Display, Formatter},
rc::Rc,
str::FromStr,
Expand All @@ -28,8 +27,6 @@ impl Display for SoftwareDataExtractionError {
}
}

impl Error for SoftwareDataExtractionError {}

pub trait EventGroupSoftwareDataExtractor {
fn extract(&self, software_data: &mut SoftwareData, event_group: &EventGroup) -> Result<(), SoftwareDataExtractionError> {
let events = event_group
Expand Down
Loading
Loading