diff -r 64e584348a5b -r 5b3e1c4569e6 PLCGenerator.py --- a/PLCGenerator.py Wed Aug 27 13:33:08 2008 +0200 +++ b/PLCGenerator.py Wed Aug 27 16:55:16 2008 +0200 @@ -714,14 +714,9 @@ elif body_type == "LD": for instance in body.getcontentInstances(): if isinstance(instance, plcopen.ldObjects_coil): - paths = self.GenerateLDPaths(instance.connectionPointIn.getconnections(), body) - if len(paths) > 0: - paths = tuple(paths) - else: - paths = paths[0] + expression = self.ComputeLDExpression(body, instance.connectionPointIn.getconnections()) coil_info = (self.TagName, "coil", instance.getlocalId()) variable = self.ExtractModifier(instance, [(instance.getvariable(), coil_info + ("reference",))], coil_info) - expression = self.ComputeLDExpression(paths, True) self.Program += [(self.CurrentIndent, ())] + variable self.Program += [(" := ", ())] + expression + [(";\n", ())] elif body_type == "SFC": @@ -770,6 +765,28 @@ return expression raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name) + def FactorizeLDPaths(self, paths): + same_paths = {} + uncomputed_index = range(len(paths)) + factorized_paths = [] + for num, path in enumerate(paths): + if type(path) == ListType: + for i in xrange(1, len(path)): + str_path = str(path[i:]) + same_paths.setdefault(str_path, []) + same_paths[str_path].append((path[:i], num)) + else: + factorized_paths.append(path) + uncomputed_index.remove(num) + for same_path, elements in same_paths.items(): + if len(elements) > 1: + factorized_paths.append([tuple([path for path, num in elements])] + eval(same_path)) + for path, num in elements: + uncomputed_index.remove(num) + for num in uncomputed_index: + factorized_paths.append(paths[num]) + return factorized_paths + def GenerateLDPaths(self, connections, body): paths = [] for connection in connections: @@ -787,31 +804,47 @@ variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info)) result = self.GenerateLDPaths(next.connectionPointIn.getconnections(), body) if len(result) > 1: - paths.append([variable, tuple(result)]) + factorized_paths = self.FactorizeLDPaths(result) + if len(factorized_paths) > 1: + paths.append([variable, tuple(factorized_paths)]) + else: + paths.append([variable] + factorized_paths) elif type(result[0]) == ListType: paths.append([variable] + result[0]) - elif result[0]: + elif result[0] is not None: paths.append([variable, result[0]]) else: paths.append(variable) return paths - def ComputeLDExpression(self, paths, first = False): + def ComputeLDPaths(self, paths, first = False): if type(paths) == TupleType: if None in paths: return [("TRUE", ())] else: - vars = [self.ComputeLDExpression(path) for path in paths] + vars = [self.ComputeLDPaths(path) for path in paths] if first: return JoinList([(" OR ", ())], vars) else: return [("(", ())] + JoinList([(" OR ", ())], vars) + [(")", ())] elif type(paths) == ListType: - vars = [self.ComputeLDExpression(path) for path in paths] + vars = [self.ComputeLDPaths(path) for path in paths] return JoinList([(" AND ", ())], vars) else: return eval(paths) + def ComputeLDExpression(self, body, connections): + paths = self.GenerateLDPaths(connections, body) + if len(paths) > 1: + factorized_paths = self.FactorizeLDPaths(paths) + if len(factorized_paths) > 1: + paths = tuple(factorized_paths) + else: + paths = factorized_paths[0] + else: + paths = paths[0] + return self.ComputeLDPaths(paths, True) + def ExtractModifier(self, variable, expression, var_info): if variable.getnegated(): return [("NOT(", var_info + ("negated",))] + expression + [(")", ())] @@ -1003,8 +1036,7 @@ elif transitionType == "LD": for instance in transitionBody.getcontentInstances(): if isinstance(instance, plcopen.ldObjects_coil): - paths = self.GenerateLDPaths(instance.connectionPointIn.getconnections(), transitionBody) - expression = self.ComputeLDExpression(paths, True) + expression = self.ComputeLDExpression(transitionBody, instance.connectionPointIn.getconnections()) transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] self.SFCComputedBlocks += self.Program self.Program = [] @@ -1016,8 +1048,7 @@ if network_type == None: raise PLCGenException, "Type of network connected to transition impossible to define in \"%s\" POU"%self.Name if len(connections) > 1 or network_type == "LD": - paths = self.GenerateLDPaths(connections, body) - expression = self.ComputeLDExpression(paths, True) + expression = self.ComputeLDExpression(body, connections) else: expression = self.ComputeFBDExpression(body, connections[0]) transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())]