def _assure_length(self, l): if l in self.permutations: return if l == 0: self.permutations[0] = [Permutation()] else: self._assure_length(l - 1) here = set() for p in self.permutations[l - 1]: for i in range(l): q = p[:i] + (l, ) + p[i:] if Permutation(q).avoids(*self.avoid): here.add(q) self.permutations[l] = list(here)
def add_rule(self, rule): self.total_rules += 1 bs = 0 curcnt = 0 empty = True for l in range(self.settings.perm_bound+1): curlevel = [] for perm in rule.generate_of_length(l, self.settings.sinput.permutations): if not self.settings.sinput.contains(perm): # the rule generated something that doesn't satisfy perm_prop self.death_by_perm_prop += 1 return RuleDeath.PERM_PROP curlevel.append(perm) cur = sorted(curlevel) for a,b in zip(cur, cur[1:]): if a == b: # the rule generated something more than once (i.e. there is overlap) self.death_by_overlap += 1 return RuleDeath.OVERLAP i = 0 j = 0 while i < len(cur) and j < len(self.permset[l]): if self.permset[l][j] < Permutation(cur[i]): j += 1 curcnt += 1 elif Permutation(cur[i]) == self.permset[l][j]: bs |= 1 << curcnt i += 1 j += 1 curcnt += 1 empty = False else: assert False assert i == len(cur) curcnt += len(self.permset[l]) - j if empty: assert False self.rules.setdefault(bs, []) self.rules[bs].append(rule) return RuleDeath.ALIVE
def _assure_length(self, l): if l in self.permutations: return if l == 0: self.permutations[0] = [] maybe = Permutation([]) if maybe.avoids(*self.avoidance): self.permutations[0].append(maybe) else: self._assure_length(l - 1) here = set() for p in self.permutations[l - 1]: for i in range(l): q = Permutation(p[:i] + (l, ) + p[i:]) if q.avoids(*self.avoidance): here.add(q) self.permutations[l] = here
def generate_of_length(self, n, input): rule = list(self.rule.items()) h = max(k[0] for k, v in rule) + 1 if rule else 1 w = max(k[1] for k, v in rule) + 1 if rule else 1 def permute(arr, perm): res = [None] * len(arr) for i in range(len(arr)): res[i] = arr[perm[i] - 1] return res def count_assignments(at, left): if at == len(rule): if left == 0: yield [] elif type(rule[at][1]) is PointPermutationSet: # this doesn't need to be handled separately, # it's just an optimization if left > 0: for ass in count_assignments(at + 1, left - 1): yield [1] + ass else: for cur in range(left + 1): for ass in count_assignments(at + 1, left - cur): yield [cur] + ass for count_ass in count_assignments(0, n): for perm_ass in product(*[ s[1].generate_of_length(cnt, input) for cnt, s in zip(count_ass, rule) ]): arr = [[[] for j in range(w)] for i in range(h)] for i, perm in enumerate(perm_ass): arr[rule[i][0][0]][rule[i][0][1]] = perm rowcnt = [ sum(len(arr[row][col]) for col in range(w)) for row in range(h) ] colcnt = [ sum(len(arr[row][col]) for row in range(h)) for col in range(w) ] for colpart in product(*[ ordered_set_partitions( range(colcnt[col]), [len(arr[row][col]) for row in range(h)]) for col in range(w) ]): for rowpart in product(*[ ordered_set_partitions( range(rowcnt[row]), [len(arr[row][col]) for col in range(w)]) for row in range(h) ]): ok = True for idxs, perm_set in self.overlay: res = [[None] * colcnt[col] for col in range(w)] cumul = 1 for row in range(h - 1, -1, -1): for col in range(w): if (row, col) in idxs: for idx, val in zip( sorted(colpart[col][row]), permute( sorted(rowpart[row][col]), arr[row][col])): res[col][idx] = cumul + val cumul += rowcnt[row] perm = Permutation.to_standard(flatten(res)) if not perm_set.contains(perm): ok = False break if not ok: continue res = [[None] * colcnt[col] for col in range(w)] cumul = 1 for row in range(h - 1, -1, -1): for col in range(w): for idx, val in zip( sorted(colpart[col][row]), permute(sorted(rowpart[row][col]), arr[row][col])): res[col][idx] = cumul + val cumul += rowcnt[row] yield Permutation(flatten(res))
def incr(n): return SimpleGeneratingRule(Permutation([1, 2]), [X, P], description='increasing').to_static(n, empty)
def decr_nonempty(n): return SimpleGeneratingRule(Permutation([2, 1]), [X, P], description='decreasing nonempty').to_static( n, {1: [Permutation([1])]})
def decr(n): return SimpleGeneratingRule(Permutation([2, 1]), [X, P], description='decreasing').to_static(n, empty)
from permuta.misc import ordered_set_partitions, flatten from permstruct.permutation_sets import PermutationSet, StaticPermutationSet, PointPermutationSet, InputPermutationSet from permstruct import X, N, P, empty, generate_all_of_length from permuta import Permutation, Permutations from permstruct.permutation_sets import SimpleGeneratingRule, OverlayGeneratingRule from itertools import product from copy import deepcopy incr = SimpleGeneratingRule(Permutation([1, 2]), [X, P], description='increasing').to_static(8, empty) decr = SimpleGeneratingRule(Permutation([2, 1]), [X, P], description='decreasing').to_static(8, empty) def at_most_one_descent(p): found = False for i in range(1, len(p)): if p[i - 1] > p[i]: if found: return False found = True return True av123 = set([ tuple(p) for l in range(8) for p in Permutations(l) if p.avoids([1, 2, 3]) ]) # print(sorted(av123))
from permuta import Permutation from permstruct import * from permstruct.dag import * patts = [ Permutation([1,3,2]) ] # patts = [ Permutation([1,3,2]), Permutation([4,3,1,2]) ] # patts = [ Permutation([]), Permutation([]) ] # patts = [Permutation([1,4,3,2]), Permutation([4,2,3,1])] # patts = [Permutation([1,3,2,4])] # patts = [Permutation([1, 4, 2, 3]), Permutation([2, 1, 4, 3]), Permutation([2, 4, 3, 1]), Permutation([3, 1, 4, 2]), Permutation([3, 2, 1, 4]), Permutation([3, 2, 4, 1]), Permutation([3, 4, 1, 2]), Permutation([4, 1, 2, 3]), Permutation([4, 2, 1, 3]), Permutation([4, 2, 3, 1]), Permutation([4, 3, 2, 1])] # patts = [Permutation([3,2,1]), Permutation([2,1,4,3])] # patts = [ Permutation([1,2,3]) ] # patts = [ Permutation([1,3,2,4]) ] perm_bound = 7 settings = StructSettings( perm_bound=perm_bound, verify_bound=7, max_rule_size=(3,3), max_non_empty=3, verbosity=StructLogger.INFO) # settings.set_input(StructInput.from_avoidance(settings, patts)) settings.set_input(AvoiderInput(settings, patts)) # settings.set_dag(taylor_dag(settings, max_len_patt=3, remove=True, upper_bound=3)) # settings.set_dag(taylor_dag(settings, remove=False)) # el = taylor_dag(settings, remove=True, max_len_patt=2, upper_bound=1).elements # print(el) # print(len(el)) dag = taylor_dag(settings, remove=False, subpattern_type=SubPatternType.EVERY)
def generate_of_length(self, n, input): if n == 1: yield Permutation([1])
# if avoids_231_vinc(p) and p.avoids([1,2,3]): # cnt += 1 # # print(p) # print(l, cnt) # # import sys # sys.exit(0) avoiders_len_3 = [] for p in Permutations(3): avoiders_len_3.append((lambda perm: perm.avoids(p),StaticPermutationSet.from_predicate(lambda x: x.avoids(p), 6, description='Av(%s)' % str(p)))) # avoiders_len_3.append((lambda perm: len(perm) >= 3 and perm.avoids(p),StaticPermutationSet.from_predicate(lambda x: x.avoids(p), 6, description='Av(%s)' % str(p)))) incr = SimpleGeneratingRule(Permutation([1,2]), [X, P], description='increasing').to_static(8, empty) decr = SimpleGeneratingRule(Permutation([2,1]), [X, P], description='decreasing').to_static(8, empty) incr_nonempty = SimpleGeneratingRule(Permutation([1,2]), [X, P], description='increasing nonempty').to_static(8, {1:[Permutation([1])]}) decr_nonempty = SimpleGeneratingRule(Permutation([2,1]), [X, P], description='decreasing nonempty').to_static(8, {1:[Permutation([1])]}) max_len = 6 n_range = (2, 3) # number of rows (min, max) m_range = (2, 3) # numbor of columns (min, max) max_nonempty = 4 max_ec_cnt = 4 # permProp = lambda perm: perm.avoids([1,2]) permProp = lambda perm: perm.avoids([2,3,1]) # permProp = lambda perm: perm.avoids([1,4,2,3])
def taylor_dag(settings, max_len_patt=None, upper_bound=None, remove=False, remove_finite=True, subpattern_type=SubPatternType.EVERY): assert settings.sinput.avoidance is not None, "Tayloring is only supported for avoidance" patterns = settings.sinput.avoidance started = datetime.datetime.now() settings.logger.log('Tayloring DAG') elems = [] if len(patterns) > 0: if max_len_patt is None: max_len_patt = max(len(p) for p in patterns) n = max(len(p) for p in patterns) sub = [set([]) for _ in range(len(patterns))] for i, p in enumerate(patterns): last = set([p]) if len(p) <= max_len_patt: sub[i] |= last for l in range(len(p) - 1, 1, -1): nxt = set([]) for q in last: for j in range(len(q)): qp = Permutation([ x - 1 if x > q[j] else x for x in q[:j] + q[j + 1:] ]) nxt.add(qp) if l <= max_len_patt: sub[i] |= nxt last = nxt valid = set() for i, p in enumerate(patterns): if subpattern_type == SubPatternType.RECTANGULAR: for l in range(len(p)): for r in range(l, len(p)): here = sorted(p.perm[l:r + 1]) for x in range(len(here)): want = set() for y in range(x, len(here)): want.add(here[y]) cur = [] for j in range(l, r + 1): if p.perm[j] in want: cur.append(p.perm[j]) if len(cur) <= max_len_patt: valid.add(Permutation.to_standard(cur)) elif subpattern_type == SubPatternType.CONSECUTIVE: for l in range(len(p)): for r in range(l, len(p)): if r - l + 1 > max_len_patt: break here = p.perm[l:r + 1] if max(here) - min(here) + 1 == len(here): valid.add(Permutation.to_standard(here)) if subpattern_type != SubPatternType.EVERY: for i, p in enumerate(patterns): sub[i] &= valid def can_add(add, picked): for p in picked: if len(p) > len(add) and p.contains(add): return False if len(add) > len(p) and add.contains(p): return False return True def bt(at, picked, seen): if upper_bound is not None and len(picked) > upper_bound: pass elif picked == set(patterns): pass elif at == len(patterns): yield picked else: for s in subsets(list(sub[at] - picked - seen)): npicked = set(picked) ok = True for add in set(s): if not can_add(add, npicked): ok = False break npicked.add(add) if not ok: continue found = False for q in npicked: if patterns[at].contains(q): found = True break if not found: continue for res in bt(at + 1, npicked, seen | sub[at]): yield res for ps in bt(0, set(), set()): # if remove_av_incr_decr: # if any( p.is_increasing() for p in ps ) and any( p.is_decreasing() for p in ps ): # continue s = AvoiderPermutationSet(ps) s._assure_length(settings.perm_bound) here = set() finite = False for l in range(settings.perm_bound + 1): found = False for p in s.generate_of_length(l, {}): here.add(Permutation(list(p))) found = True if not found: finite = True if finite and remove_finite and settings.sinput.is_classical: break if finite and remove_finite and settings.sinput.is_classical: continue here = { Permutation(list(p)) for l in range(settings.perm_bound + 1) for p in s.generate_of_length(l, {}) } elems.append((s, here, None)) input = settings.sinput.get_permutation_set() elems.append((InputPermutationSet(settings), input, None)) elems.append((N, set([Permutation([])]), None)) elems.append((P, set([Permutation([1])]), None)) res = DAG() if remove: for ps, here, descr in elems: rem = set() rems = [] for qs, other, odescr in elems: if other and other < here: rems.append(qs) rem |= other if not here - rem: continue if rems: res.add_element( SubtractPermutationSet(ps, rems, alone_ok=type(ps) is not InputPermutationSet)) else: res.add_element(ps) else: for ps, here, descr in elems: res.add_element(ps) for ps, here, descr in elems: for qs, other, odescr in elems: if other and other < here: res.put_below(qs, ps) ended = datetime.datetime.now() settings.logger.log('Finished in %.3fs' % (ended - started).total_seconds()) return res
return not is_polynomial(C) def wrong_is_polynomial(C): overallinterset = set([]) for perm in C: overallinterset = overallinterset.union(wrong_types(perm)) if len(overallinterset) == 10: return True return False def wrong_is_non_polynomial(C): return not wrong_is_polynomial(C) while True: line = sys.stdin.readline() if not line: break line = line.strip() perms = [Permutation(list(map(int, p))) for p in line.split('_')] if is_non_polynomial(perms): print line # Use the stuff below to see what we first missed # winp = wrong_is_non_polynomial(perms) # inp = is_non_polynomial(perms) # if winp != inp: # print line
def rotate(perm): n = len(perm) return Permutation([ perm.index(n-i) + 1 for i in range(n)])
def contains(self, perm): if type(perm) is not Permutation: perm = Permutation(list(perm)) return perm in self.permutations[len(perm)]
def test_taylor(self): settings = StructSettings(perm_bound=7, max_rule_size=(3, 3), max_non_empty=3) patts = [Permutation([1, 2, 3]), Permutation([3, 2, 1])] settings.set_input(StructInput.from_avoidance(settings, patts)) res = taylor_dag(settings, remove=False) self.check([], res) patts = [Permutation([1, 2, 3]), Permutation([3, 2, 1])] settings.set_input(StructInput.from_avoidance(settings, patts)) res = taylor_dag(settings, remove=False, remove_finite=False) self.check([ [Permutation([1, 2]), Permutation([2, 1])], [Permutation([1, 2, 3]), Permutation([2, 1])], [Permutation([1, 2]), Permutation([3, 2, 1])], ], res) patts = [ Permutation([1, 2, 3]), Permutation([3, 2, 1]), ] settings.set_input(StructInput.from_avoidance(settings, patts)) res = taylor_dag(settings, upper_bound=1, remove=False, remove_finite=False) self.check([], res) patts = [ Permutation([1, 2, 3]), Permutation([3, 2, 1]), ] settings.set_input(StructInput.from_avoidance(settings, patts)) res = taylor_dag(settings, max_len_patt=2, remove=False, remove_finite=False) self.check([ [Permutation([1, 2]), Permutation([2, 1])], ], res)