Path: blob/main/GeneratingDiagonalsViaShift/operadic_tree_nestings.py
1017 views
import sys1from itertools import permutations, chain, combinations, product2from copy import deepcopy34from diagonals_via_shift import SU_diag, LA_diag56class Tree:7def __init__(self, data = None, children = []):8self.data = data9self.children = children1011#https://stackoverflow.com/questions/20242479/printing-a-tree-data-structure-in-python12def __str__(self, level=0):13ret = "\t"*level+repr(self.data)+"\n"14for child in self.children:15ret += child.__str__(level+1)16return ret1718def __repr__(self):19return '<tree node representation>'2021def non_empty_powerset(iterable):22s = list(iterable)23return chain.from_iterable(combinations(s, r) for r in range(1,len(s)+1))2425def increment_tree(t,v):26'''Update the data of all vertices of t to data += v.'''27base = t28t.data = t.data + v29for child in t.children:30increment_tree(child,v)3132return base3334def PT(n):35'''The set of planar trees with n non-root vertices labelled under infix order.3637Exploiting catalan recurrence for generation.38C = 1 + z C^239'''40if n == 0:41return [Tree(0)]4243trees = []44for k in range(n):45rec_1 = PT(k)46rec_2 = PT(n-1-k)47for t1 in rec_1:48for t2 in rec_2:49t = deepcopy(t1)50t.children.append(increment_tree(deepcopy(t2),k+1))51trees.append(t)5253return trees5455def connected_to_root(t):56'''Returns a set of all subtrees of t which are connected to root.'''57if t.children == []:58return [] #If no children then have no sub-trees59#Recurse60connected_to_children = []61for child in t.children:62child_and_edge_to_root = [[child.data]] #the edge to child is a trivial subtree63for x in connected_to_root(child):64x.append(child.data)65child_and_edge_to_root.append(x) #the edge to child, and each subtree of child is a subtree66connected_to_children.append(child_and_edge_to_root)6768#Combine69all_conn_to_root = []70#Choose a non-emptyset of children to be connected to71for choose_conn_children in non_empty_powerset(connected_to_children):72#Construct the product of all sub-trees from this choice.73for p in product(*choose_conn_children):74sub = []75for e in p:76sub += e77all_conn_to_root.append(sub)7879return all_conn_to_root8081def compute_nests(t):82'''Computes all nests of a tree.83This is equivalent to computing all connected subtrees of t,84which is equivalent to the union of all vertices in t,85subtrees of t connected to root86'''87#base case88nests = connected_to_root(t)89#recursion90for child in t.children:91sub_nests = compute_nests(child)92if sub_nests != []:93nests += sub_nests94return nests9596def check_nesting_of_tree(d,t):97'''98Checks that sigma, tau is a nesting of tree t.99100By construction meets compatibility, and trivial nest.101So just need to check each element is a nest.102'''103sigma,tau = d104N = compute_nests(t)105N = [sorted(x) for x in N]106N.sort()107108#Manipulate into sigma_1 | sigma_1 \cup sigma_2|...109sigma_nests = []110for i in range(1,len(sigma)+1):111sigma_nests.append(sorted(list(chain(*sigma[:i]))))112113#check114for block in sigma_nests:115if block not in N:116return False117118#repeat119tau_nests = []120for i in range(1,len(tau)+1):121tau_nests.append(sorted(list(chain(*tau[:i]))))122for block in tau_nests:123if block not in N:124return False125126return True127128def proj_nesting(sigma,t):129'''130Given an ordered partition sigma, projects it onto a tree t.131132Ex tree from email:133134'''135proj = []136N = compute_nests(t)137N = [sorted(x) for x in N]138N.sort()139140print(N)141142#Manipulate into sigma_1 | sigma_1 \cup sigma_2|...143merged = []144for i in range(1,len(sigma)+1):145merged.append(sorted(list(chain(*sigma[:i]))))146147for block in merged:148if block in N:149proj.append(block)150151def construct_tree_nesting_dict(n, diag = "SU"):152if diag == "SU":153computed_diag = SU_diag(n)154elif diag == "LA":155computed_diag = LA_diag(n)156157pt = PT(n)158tree_nesting_dict = {}159for t in pt:160#Use strings to uniquely identify trees161s = str(t)162tree_nesting_dict[s] = []163#Incredibly weird bug, can only iterate through computed diag once...164#Maybe did something weired with iterators, can't remember.165#Fine as is, but finicky.166for d in computed_diag:167sigma,tau = d168for t in pt:169if (not check_proj_nesting(sigma,t)) or (not check_proj_nesting(tau,t)):170continue171s = str(t)172tree_nesting_dict[s].append(d)173174return tree_nesting_dict175176def check_proj_nesting(sigma,t):177''''''178return len(sigma) == len(proj_nesting(sigma,t))179180def proj_nesting(sigma,t):181'''182Given an ordered partition sigma, projects it onto a tree t.183Ex tree from email:184'''185proj = []186N = compute_nests(t)187N = [sorted(x) for x in N]188N.sort()189190#Manipulate into sigma_1 | sigma_1 \cup sigma_2|...191merged = []192for i in range(1,len(sigma)+1):193merged.append(sorted(list(chain(*sigma[:i]))))194195#print(N)196#print(sigma)197#print(merged)198#print("loop")199200#Break each merged block into minimal nests201min_nesting = []202for block in merged:203#print("block",block)204min_nests_block = []205206start = 0207for i in range(1,len(block)+1):208#print(block[start:i],block[start:i] in N)209if block[start:i] in N:210continue211else:212#print("found", i, block[start:(i-1)])213min_nests_block.append(block[start:(i-1)])214start=i-1215#Wrap up216if start<len(block)+1:217min_nests_block.append(block[start:])218#inefficient219for m in min_nests_block:220if m not in min_nesting:221min_nesting.append(m)222#print("min_nesting",min_nesting)223#print("\n")224return min_nesting225226if __name__ == '__main__':227228orig_stdout = sys.stdout229f = open('bijection_check.txt', 'w')230sys.stdout = f231232233n = 5234pt = PT(n)235'''236t = pt[0]237print(t)238print(proj_nesting([[1, 4], [2, 3]],t))239print(check_proj_nesting([[1, 4], [2, 3]],t))240print(proj_nesting([[1, 4], [2], [3]],t))241print(check_proj_nesting([[1, 4], [2], [3]],t))242print(proj_nesting([[3, 4], [2], [1]],t))243print(check_proj_nesting([[3, 4], [2], [1]],t))244245print(proj_nesting([[1, 3], [2], [4]],t))246print(check_proj_nesting([[1, 3], [2], [4]],t))247248exit()249250251nesting_dict_SU = construct_tree_nesting_dict(n, diag = "SU")252nesting_dict_LA = construct_tree_nesting_dict(n, diag = "LA")253t = pt[33]254s = str(t)255print(s)256print("countLA",len(nesting_dict_LA[s]))257print("countSU",len(nesting_dict_SU[s]))258diffLA = []259diffSU = []260for x in nesting_dict_LA[s]:261if x not in nesting_dict_SU[s]:262diffLA.append(x)263for x in nesting_dict_SU[s]:264if x not in nesting_dict_LA[s]:265diffSU.append(x)266print("in LA but not in SU",len(diffLA))267print("in SU but not in LA",len(diffSU))268269sortedLA = [[sorted(x[0]),sorted(x[1])] for x in nesting_dict_LA[s]]270sortedSU = [[sorted(x[0]),sorted(x[1])] for x in nesting_dict_SU[s]]271272print("In SU and reordering of blocks is not in LA")273for i in range(len(nesting_dict_SU[s])):274if sortedSU[i] not in sortedLA:275print(nesting_dict_SU[s][i])276print("In LA and reordering of blocks is not in SU")277for i in range(len(nesting_dict_LA[s])):278if sortedLA[i] not in sortedSU:279print(nesting_dict_LA[s][i])280281print("\n")282print("All LA")283for x in nesting_dict_LA[s]:284print(x)285286print("\n")287print("All SU")288for x in nesting_dict_LA[s]:289print(x)290291exit()292'''293294for n in range(3,5+1):295print("For n=",n)296nesting_dict_SU = construct_tree_nesting_dict(n, diag = "SU")297nesting_dict_LA = construct_tree_nesting_dict(n, diag = "LA")298trees = PT(n)299for i in range(len(trees)):300t = trees[i]301s = str(t)302303if len(nesting_dict_SU[s]) != len(nesting_dict_LA[s]):304print("Tree:")305print(s)306#print(compute_nests(t))307print("SU Count:",len(nesting_dict_SU[s]))308print("LA Count:",len(nesting_dict_LA[s]))309310diffLA = []311diffSU = []312for x in nesting_dict_LA[s]:313if x not in nesting_dict_SU[s]:314diffLA.append(x)315for x in nesting_dict_SU[s]:316if x not in nesting_dict_LA[s]:317diffSU.append(x)318319print("disjoint",len(diffLA),len(diffSU))320321else:322print("For tree i=",i+1,"shared count=",len(nesting_dict_SU[s]))323324325sys.stdout = orig_stdout326f.close()327328