Skip to content

Commit

Permalink
merge from latest
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Burke committed Jun 28, 2024
2 parents 40c9306 + 5f8e4ce commit 2f72b33
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 21 deletions.
3 changes: 2 additions & 1 deletion pmkoalas/_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def wrapped(*args, **kwargs):
# a tuple of the names of the parameters that func accepts
func_params = func.__code__.co_varnames[:func.__code__.co_argcount]
# grab all of the kwargs that are not accepted by func
old_level = get_logger().level
extra = set(kwargs.keys()) - set(func_params)
debug = kwargs.pop("debug",False)
level = kwargs.pop("debug_level", logging.INFO)
Expand All @@ -84,7 +85,7 @@ def wrapped(*args, **kwargs):
# run function as intended
val = func(*args, **kwargs)
# reset logger
get_logger().setLevel(logging.ERROR)
get_logger().setLevel(old_level)
# pass value back if needed
return val

Expand Down
108 changes: 104 additions & 4 deletions pmkoalas/directly.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,37 @@ class DirectlyFollowPair():
two process activities seen in a language.
"""

def __init__(self,left:str,right:str,freq:int) -> None:
def __init__(self,left:str,right:str,freq:int,
preceeding:Set[str]=None,
proceeding:Set[str]=None) -> None:
self._left = left.replace("\n","")
self._right = right.replace("\n","")
self._hash = hash((self._left,self._right))
self._freq = freq
if preceeding == None:
self._preced = set()
else:
self._preced = deepcopy(preceeding)
if proceeding == None:
self._proced = set()
else:
self._proced = deepcopy(proceeding)

def preceding(self) -> Set[str]:
"Returns the directly preceeding activities, as a set."
return self._preced

def add_to_preceding(self, activity:str) -> None:
"Adds activity as a directly preceeding activity of this pair."
self._preced.add(activity)

def proceeding(self) -> Set[str]:
"Returns the directly proceeding activities, as a set"
return self._proced

def add_to_proceeding(self, activity:str) -> None:
"Adds an activity as a directly proceeding activity of this pair"
self._proced.add(activity)

def left(self) -> str:
"Source process activity"
Expand All @@ -47,17 +73,19 @@ def decre(self,count:int=1) -> None:
self._freq -= count

def copy(self) -> 'DirectlyFollowPair':
return DirectlyFollowPair(self._left, self._right, self._freq)
return DirectlyFollowPair(self._left, self._right, self._freq,
self._preced, self._proced)

# data model functions
def __str__(self) -> str:
return f"({self._left} -> {self._right})^{self._freq}"
return f"B:{self.preceding()} ({self._left} -> {self._right})^{self._freq} A:{self.proceeding()}"

def __repr__(self) -> str:
left = self._left.replace("'","\\'")
right = self._right.replace("'","\\'")
return f"DirectlyFlowsPair(left='{left}'"+ \
f",right='{right}',freq={self._freq})"
f",right='{right}',freq={self._freq},"+ \
f"preceeding={self._preced},proceeding={self._proced})"

def __hash__(self) -> int:
return self._hash
Expand All @@ -66,6 +94,68 @@ def __eq__(self, __o: object) -> bool:
if (isinstance(__o, DirectlyFollowPair)):
return self.__hash__() == __o.__hash__()
return False

def extract_df_pairs(variant:Iterable[str], prepend_start:bool=True,
append_end:bool=True, freq:int=1) -> List[DirectlyFollowPair]:
"""
Extracts the directly flow pairs from a variant (sequence of activities or
a simplifed trace). By default prepends a start and appends an end to the
variant.
"""
if prepend_start:
variant = [DIRECTLY_SOURCE] + variant
if append_end:
variant = variant + [DIRECTLY_END]
curr = 1
pairs = []
while curr < len(variant):
# extract a pair based on the current index
if variant[curr-1] == DIRECTLY_SOURCE:
# extraction for source
proceed = set()
if curr+1 < len(variant):
proceed = set([variant[curr+1]])
pairs.append(
DirectlyFollowPair(
variant[curr-1],
variant[curr],
freq=freq,
proceeding=proceed
)
)
elif variant[curr] == DIRECTLY_END:
# extraction for end
preced = set()
if curr-2 < len(variant) and curr-2 > -1:
preced = set([variant[curr-2]])
pairs.append(
DirectlyFollowPair(
variant[curr-1],
variant[curr],
freq=freq,
preceeding=preced
)
)
else:
# extraction for body
preced = set()
if curr-2 < len(variant) and curr-2 > -1:
preced = set([variant[curr-2]])
proceed = set()
if curr+1 < len(variant):
proceed = set([variant[curr+1]])
pairs.append(
DirectlyFollowPair(
variant[curr-1],
variant[curr],
freq=freq,
preceeding=preced,
proceeding=proceed
)
)
curr += 1
return pairs


class DirectlyFollowWalk():
"""
Expand Down Expand Up @@ -218,6 +308,10 @@ def _update_state(self, pair:DirectlyFollowPair, state:Dict,
if (val != None):
newval = val.copy()
newval.incre(pair.frequency())
for prec in pair.preceding():
newval.add_to_preceding(prec)
for proc in pair.proceeding():
newval.add_to_proceeding(proc)
debug(f"{state_name} :: update : {val}")
state[newval] = newval
else:
Expand All @@ -231,6 +325,12 @@ def starts(self) -> List[DirectlyFollowPair]:
def ends(self) -> List[DirectlyFollowPair]:
"Returns all ending directly flow pairs."
return list(self._ends.values())

def pairs(self) -> List[DirectlyFollowPair]:
"""
Returns all the pairs in the language.
"""
return list(self._relations.values())

def get(self, target:str) -> List[DirectlyFollowPair]:
"Returns all pairs with left as target."
Expand Down
25 changes: 9 additions & 16 deletions pmkoalas/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from pmkoalas._logging import info, debug, enable_logging
from pmkoalas.directly import DirectlyFollowPair,FollowLanguage
from pmkoalas.directly import DIRECTLY_SOURCE,DIRECTLY_END
from pmkoalas.directly import extract_df_pairs

class Trace():
"""
Expand Down Expand Up @@ -134,27 +135,19 @@ def directly_follow_relations(self) -> FollowLanguage:
start = time()
computed_times = []
info("Starting computation of relations")
starts = {}
ends = {}
for tid,(trace,freq) in enumerate(self._freqset.items()):
if (len(trace) < 1):
continue
compute_time = time()
relations = []
# build initial flow
debug(f"{trace=} @ {freq=}")
debug(f"{DIRECTLY_SOURCE} to {trace[0]=} @ {freq}")
relations.append(DirectlyFollowPair(left=DIRECTLY_SOURCE,
right=trace[0], freq=freq))

# build body flows
for src,trg in zip(trace[:-1],trace[1:]):
debug(f"{src=} to {trg=} @ {freq=}")
relations.append(DirectlyFollowPair(left=src,
right=trg, freq=freq))

# build exit flow
debug(f"{trace[-1]=} to {DIRECTLY_END} @ {freq}")
relations.append(DirectlyFollowPair(left=trace[-1],
right=DIRECTLY_END, freq=freq))
info(f"working on :: {trace=} @ {freq=}")
relations = extract_df_pairs(list(trace), freq=freq)
info(f"starting pair :: {relations[0]}")
for pair in relations[1:-1]:
info(f"pair :: {pair}")
info(f"ending with :: {relations[-1]}")

# update lang
self._relations = self._relations + \
Expand Down

0 comments on commit 2f72b33

Please sign in to comment.