from sys import argv from pathlib import Path from common import printc, replaceContent # Increase if the diagram becomes too clobbered HEIGHT_SEPARATOR = 1 # For manual usage via stdin def getRels(relations=None): if relations == None: relations = input("Write the relations in the following format: ab ac ad bc cd ...\n") relations = (tuple(list(x)) for x in relations.split(' ')) return set(relations) # Generate divisibility graph by range def divisibility_graph(n): E = set() for dst in range(n): for src in range( 1, dst ): if dst % src == 0: E.add( ( src, dst ) ) return E def hasse_diagram(E): E2 = set() for e0 in E: for e1 in E: if e0[1] == e1[0]: E2.add( ( e0[0], e1[1] ) ) return E - E2 def latex_hasse(hasse): min_el = set(a for a,b in hasse if a not in list(zip(*hasse))[1]) keys = set(item for tup in hasse for item in tup) y_pos = dict.fromkeys(keys, 0) i = 0 while len(next_row := [val for key,val in hasse if key in [x for x,y in y_pos.items() if y == i] ]) != 0: for item in next_row: y_pos[item] = i + 1 i += 1 inv_ypos = dict() for key in set(y_pos.values()): inv_ypos[key] = [x for x,y in y_pos.items() if y == key] output = [] for y in inv_ypos.keys(): for i, n in enumerate(inv_ypos[y]): output.append(f'\\node ({n}) at ({i - len(inv_ypos[y])/2}, {y * HEIGHT_SEPARATOR}) {{${n}$}};') output.append('') for x,y in hasse: output.append(f'\\draw ({x}) -- ({y});') printc(f"Minimal elements: $\{{ {', '.join(str(e) for e in min_el)} \}}$ \\\\") max_el = set(v for k,v in hasse if v not in (x for x,_ in hasse)) printc(f"Maximal elements: $\{{ {', '.join(str(e) for e in max_el)} \}}$" ) return '\n'.join(output) def processFileContent(raw): rels = getRels(raw) content = latex_hasse(hasse_diagram(rels)) return replaceContent(content, 'Hasse') if __name__ == '__main__': pass