def check_diagram(sparse_diagram, ext_possible_chords, ext_min, ext_max):

    # Skip diagrams with 1, 2 or 3 moves
    compressed_diag = get_compressed_diagram(sparse_diagram)
    if (contains_one_move(compressed_diag) or
        contains_two_move(compressed_diag) or
        contains_three_move(compressed_diag)):
        return (sparse_diagram, [], [])

    # Find the permitted single chord extensions
    invariant_chords = get_invariant_chords_for_diagram(
            sparse_diagram, ext_possible_chords, diagram_filter=diagram_filter,
            doScale=False)
    if len(invariant_chords) == 0:
        # Skip diagrams with no invariant chords
        return (sparse_diagram, invariant_chords, [])

    # Test planarability of sparse_diag plus combinations of min..max chords
    planarable_extension_sets = []
    for n_extensions in range(ext_min, ext_max+1):
        for extensions in combinations(invariant_chords, n_extensions):
            # Skip extension chord pair if they share any nodes
            uniq_nodes = {node for ext in extensions for node in ext}
            if len(uniq_nodes) != n_extensions * 2:
                continue
            diag = Diagram(sparse_diagram + list(extensions))
            if diag.is_planarable():
                planarable_extension_sets.append((timestamp(), extensions))

    return (sparse_diagram, invariant_chords, planarable_extension_sets)
def diagram_filter(orig_sparse_diag, extension_chord, extended_sparse_diag):
    diag = Diagram(extended_sparse_diag)
    diag.compress()
    if (contains_one_move(diag) or
        contains_three_move(diag)):
        return False # Skip this diagram
    return True # Use this diagram
def check_123_planarable(diagram):

    # Skip diagrams with 1, 2 or 3 moves
    if (contains_one_move(diagram) or
        contains_two_move(diagram) or
        contains_three_move(diagram)):
        return (diagram, False)

    # Test planarability of sparse_diag
    diag = Diagram(diagram)
    rv = diag.is_planarable()

    return (diagram, rv)
Esempio n. 4
0
def diagram_filter(diagram):
    '''
    Filter function that gets passed into gen_possible_diagrams to filter
      at generation time.
    The filter applies two basic tests:
    1. Skip diagrams containing 2 or 3 moves
    2. Skip if other-ends of chords with adjacent nodes are 1 or 2 nodes apart
       This test is known as the parallel with defect 3 test.

    Closure arguments:
        filter_two_moves: Filter out two moves when True
        filter_three_moves: Filter out three moves when True
    Arguments:
        diagram: Diagram to check.  Assumption: diagram is compressed, i.e.
                 all 1..2*n_chords nodes are part of a chord.
    Returns:
        True (keep diagram) if the diagram meets the requirements
        False (discard diagram) if the diagram fails either test
    Raises:
        None
    '''

    # Allow access to globals set in main.  Necessary with multiprocessing.Pool
    global filter_two_moves
    global filter_three_moves
    global max_parallel_defect

    # Remove diagram nodes with no chord
    compressed_diag = get_compressed_diagram(diagram)

    # Filter out 2 and 3 moves.  One moves are pre-filtered in chord list
    if (filter_two_moves and contains_two_move(compressed_diag)
            or filter_three_moves and contains_three_move(compressed_diag)):
        return False  # Skip diagram

    # Filter out parallel chords with defect
    chords_by_node = {node: chord for chord in diagram for node in chord}
    n_nodes = len(chords_by_node)
    for node1 in range(1, n_nodes + 1):
        node2 = node1 % n_nodes + 1  # Adjacent chord
        chord1 = chords_by_node[node1]
        chord2 = chords_by_node[node2]
        if chord_length(
            (get_other_node(chord1, node1), get_other_node(chord2, node2)),
                n_nodes) < max_parallel_defect:
            return False  # Skip diagram
    return True  # Keep diagram
Esempio n. 5
0
def diagram_filter(diagram):
    # Skip diagrams with 2 or 3 moves
    # or if other ends of chords with adjacent nodes are too close

    # Filter out 2 and 3 moves.  One moves are pre-filtered in chord list
    if (contains_two_move(diagram) or
        contains_three_move(diagram)):
        return False # Skip diagram

    # Filter out parallel chords with defect
    defect_length = 3
    chords_by_node = { node:chord for chord in diagram for node in chord}
    n_nodes = len(chords_by_node)
    for node1 in range(1, n_nodes+1):
        node2 = node1 % n_nodes + 1 # Adjacent chord
        chord1 = chords_by_node[node1]
        chord2 = chords_by_node[node2]
        if chord_length((get_other_node(chord1, node1),
                         get_other_node(chord2, node2)), n_nodes) < defect_length:
            return False # Skip diagram
    return True # Keep diagram
Esempio n. 6
0
def main(argv):
    "Process command line arguments and kick things off"
    progname = argv[0].split('/')[-1]
    print_all = False # Print detail on each move type

    # Parse command line options
    try:
        (opts, args) = getopt.getopt(argv[1:], "ha")
    except getopt.GetoptError as err:
        print >>sys.stderr, str(err)
        usage(progname)
    for opt, _ in opts:
        if opt == '-a':
            print_all = True
        if opt == '-h':
            usage(progname)

    diag_files = args
    if len(diag_files) == 0:
        diag_files.append(None) # Read from stdin

    # Do the work
    count = 0
    for diag_file in diag_files:
        diag_gen = load_diagrams_from_file(diag_file)
        for diagram in diag_gen:
            count += 1
            diag_compressed = get_compressed_diagram(diagram)
            one = contains_one_move(diag_compressed)
            two = contains_two_move(diag_compressed)
            three = contains_three_move(diag_compressed)

            if print_all:
                print "{}{}{}: {}".format(
                    '1' if one else '-',
                    '2' if two else '-',
                    '3' if three else '-', diagram)
            elif not (one or two or three):
                print diagram