From b59041227d31e000e4f72a4e343a377b2891caec Mon Sep 17 00:00:00 2001 From: George Marchment <georgemarchment@yahoo.fr> Date: Wed, 19 Feb 2025 15:13:21 +0100 Subject: [PATCH] Added single to multi line condition + added multiple analysis when rewriting (to check if this is usefull) --- src/code_.py | 12 ++++++ src/workflow.py | 105 +++++++++++++++++++++++++++--------------------- 2 files changed, 71 insertions(+), 46 deletions(-) diff --git a/src/code_.py b/src/code_.py index 3fd7bd3..b43c9c5 100644 --- a/src/code_.py +++ b/src/code_.py @@ -20,6 +20,7 @@ class Code: self.code_wo_comments = re.sub(constant.DOUBLE_BACKSLAPSH_JUMP, ' ', self.code_wo_comments) self.code_wo_comments = re.sub(constant.BACKSLAPSH_JUMP, ' ', self.code_wo_comments) self.code_wo_comments = self.code_wo_comments.replace("||", "$OR$") + self.code_wo_comments = self.turn_single_condition_into_multiline(self.code_wo_comments) def check_its_nextflow(self): @@ -29,6 +30,17 @@ class Code: raise BioFlowInsightError(f"The presence of '{bit_of_code}' is detected{self.get_string_line(bit_of_code)}.", num = 1,origin=self) + def turn_single_condition_into_multiline(self, code): + to_replace = [] + for match in re.finditer(r"if *\((.+)\) *([^{\n]+)\n", code): + old = match.group(0) + new = f"if ({match.group(1)}) {{\n{match.group(2)}\n}}\n" + to_replace.append((old, new)) + for r in to_replace: + old, new = r + code = code.replace(old, new) + return code + def get_line(self, bit_of_code): code = remove_comments(self.code) index = code.find(bit_of_code) diff --git a/src/workflow.py b/src/workflow.py index eaae290..83906e3 100644 --- a/src/workflow.py +++ b/src/workflow.py @@ -565,7 +565,10 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen if(takes.get_code()!=param.get_code(get_OG = True)): new_header+=f"{takes.get_code()} = {param.get_code(get_OG = True)}" + temp_code = code code = code.replace(OG_call.get_code(get_OG = True), f"{new_header}\n\n{OG_body}", 1) + if(temp_code==code): + raise Exception("Something went wrong: The code hasn't changed") #REPLACE THE EMITS #TODO admittedly this code below is very moche -> but it's functionnal -> update it @@ -575,20 +578,23 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen for exe in all_executors: #We don't need to check the case call since the workflow has already been rewriteen -> emits only appear in operations if(exe.get_type()=="Operation"): - emited = exe.get_origins() - if(len(emited)==1): - emited = emited[0] + for emited in exe.get_origins(): if(emited.get_type()=="Emitted"): if(emited.get_emitted_by().get_first_element_called()==subworklfow): if(emited.get_emits() not in emits): raise Exception("This shoudn't happen -> since it is the actual subworkflow") - to_replace.append((exe.get_code(get_OG = True), f"{exe.get_gives()[0].get_code()} = {emited.get_emits().get_origins()[0].get_code()}")) + new = exe.get_code(get_OG = True).replace(emited.get_code(), emited.get_emits().get_origins()[0].get_code()) + #to_replace.append((exe.get_code(get_OG = True), f"{exe.get_gives()[0].get_code()} = {emited.get_emits().get_origins()[0].get_code()}")) + to_replace.append((exe.get_code(get_OG = True), new)) for r in to_replace: old, new = r - #Case of channel == channel + temp_code = code + #Case of channel = channel if(new.split("=")[0].strip()==new.split("=")[1].strip()): new = '' code = code.replace(old, new) + if(temp_code==code): + raise Exception("Something went wrong: The code hasn't changed") return code @@ -662,38 +668,39 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen code = self.simplify_workflow_code() self.rewrite_and_initialise(code) - #Get the clusters and the code - self.check_relevant_processes_in_workflow(relevant_processes) - self.generate_user_view(relevant_processes = relevant_processes, processes_2_remove = []) - clusters = self.graph.get_clusters_from_user_view() + #DETERMING WHICH SUBWORKFLOWS ARE BROKEN WITH THE CLUSTER - #Creating the clusters with calls instead of processes or subworkflows - set_clusters_with_calls = [] - for c in clusters: - tab = [] - for ele in c: - if(ele.get_type()=="Operation"): - if(ele.get_artificial_status()==False): - tab.append(ele) - else: - call = ele.get_call() - tab.append(call) - set_clusters_with_calls.append(set(tab)) + def get_clusters_with_calls(clusters): + #Creating the clusters with calls instead of processes or subworkflows + set_clusters_with_calls = [] + for c in clusters: + tab = [] + for ele in c: + if(ele.get_type()=="Operation"): + if(ele.get_artificial_status()==False): + tab.append(ele) + else: + call = ele.get_call() + tab.append(call) + set_clusters_with_calls.append(set(tab)) + return set_clusters_with_calls #Getting subworkflows to executors - subworkflow_2_executors = {} - for sub in self.get_subworkflows_called(): - executors = sub.get_all_executors_in_workflow() - subworkflow_2_executors[sub] = [] - for ele in executors: - #Cannot add calls to subworkflows -> they are already present by definition - if(ele.get_type()=="Call" and ele.get_first_element_called().get_type()=="Subworkflow"): - None - #We don't add it - else: - subworkflow_2_executors[sub].append(ele) + def get_subworkflow_2_executors(): + subworkflow_2_executors = {} + for sub in self.get_subworkflows_called(): + executors = sub.get_all_executors_in_workflow() + subworkflow_2_executors[sub] = [] + for ele in executors: + #Cannot add calls to subworkflows -> they are already present by definition + if(ele.get_type()=="Call" and ele.get_first_element_called().get_type()=="Subworkflow"): + None + #We don't add it + else: + subworkflow_2_executors[sub].append(ele) + return subworkflow_2_executors #subworkflow_2_executors[sub.get_name()] = set(list(dico.keys())) #TODO -> write tests to test this function @@ -719,18 +726,27 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen broken_subworkflows.append(sub) return broken_subworkflows - broken_subworkflows = get_workflows_broken(subworkflow_2_executors, set_clusters_with_calls) - - - #Rewrite broken subworkflows - for sub in broken_subworkflows: - code = self.rewrite_subworkflow_call(code, sub) - - #TODO -> this needs to be optimised - self.rewrite_and_initialise(code) #Get the clusters and the code + self.check_relevant_processes_in_workflow(relevant_processes) self.generate_user_view(relevant_processes = relevant_processes, processes_2_remove = []) clusters = self.graph.get_clusters_from_user_view() + broken_subworkflows = get_workflows_broken(get_subworkflow_2_executors(), get_clusters_with_calls(clusters)) + #While there still are broken workflows -> need to redo the analysis + while(len(broken_subworkflows)>0): + #Rewrite broken subworkflows + sub = broken_subworkflows[0] + code = self.rewrite_subworkflow_call(code, sub) + self.rewrite_and_initialise(code) + #Get the clusters and the code + self.generate_all_graphs() + self.generate_user_view(relevant_processes = relevant_processes, processes_2_remove = []) + clusters = self.graph.get_clusters_from_user_view() + broken_subworkflows = get_workflows_broken(get_subworkflow_2_executors(), get_clusters_with_calls(clusters)) + + + + + #Get the clsuters with the corresponding operations inside @@ -959,7 +975,6 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen subworkflow_cluster_calls_to_add.append(subworkfow_call) index_cluster+=1 - #TODO -> rmoving the conditions which are problematic #This might not be the probleme -> when rerunnung the analysis isn't totally robust @@ -982,10 +997,8 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen break if(still_simplifying_conditions): code = code.replace(to_replace, f"{anker1}\n{anker2}") - - - + #Replace the ankers by the calls of the subworkflows for i in range(len(subworkflow_clusters_to_add)): #Extracting the conditions in the code @@ -1005,7 +1018,7 @@ George Marchment, Bryan Brancotte, Marie Schmit, Frédéric Lemoine, Sarah Cohen subworkflow_call = f"\n}}\n{subworkflow_call}\nif({c}){{\n" code = code.replace(anker, subworkflow_call) - + for old, new in channels_to_replace_outside_of_cluster: pattern= fr"[ \(,]({re.escape(old)})" code = replace_group1(code, pattern, new) -- GitLab