Ejemplo n.º 1
0
def test_constraint_violation():
    are_constraints_violated = UniformCombinatoricSamplingStrategy._UniformCombinatoricSamplingStrategy__are_constraints_violated

    block = fully_cross_block([color, text, con_factor_within_trial],
                              [color, text],
                              [ExactlyKInARow(2, (color, red_color))])

    assert are_constraints_violated(
        block,
        {color: [red_color, red_color, blue_color, blue_color]}) == False
    assert are_constraints_violated(
        block, {color: [red_color, blue_color, red_color, blue_color]}) == True

    block = fully_cross_block([color, text, con_factor_within_trial],
                              [color, text],
                              [NoMoreThanKInARow(2, (color, red_color))])

    assert are_constraints_violated(
        block,
        {color: [red_color, blue_color, blue_color, blue_color]}) == False
    assert are_constraints_violated(
        block,
        {color: [red_color, red_color, blue_color, blue_color]}) == False
    assert are_constraints_violated(
        block, {color: [red_color, red_color, red_color, blue_color]}) == True
    assert are_constraints_violated(
        block, {color: [blue_color, red_color, red_color, red_color]}) == True
Ejemplo n.º 2
0
def test_consistency():
    # From standard example
    # [ LowLevelRequest("EQ", 1, [1, 2]), LowLevelRequest("EQ", 1, [3, 4]), ...]
    backend_request = BackendRequest(0)

    Consistency.apply(block, backend_request)
    assert backend_request.ll_requests == \
        list(map(lambda x: LowLevelRequest("EQ", 1, [x, x+1]), range(1, 24, 2)))

    # Different case
    backend_request = BackendRequest(0)
    f = Factor("a", ["b", "c", "d", "e"])
    f_block = fully_cross_block([f], [f], [])

    Consistency.apply(f_block, backend_request)
    assert backend_request.ll_requests == \
        list(map(lambda x: LowLevelRequest("EQ", 1, [x, x+1, x+2, x+3]), range(1, 16, 4)))

    # Varied level lengths
    backend_request = BackendRequest(0)
    f1 = Factor("a", ["b", "c", "d"])
    f2 = Factor("e", ["f"])
    f_block = fully_cross_block([f1, f2], [f1, f2], [])

    Consistency.apply(f_block, backend_request)
    assert backend_request.ll_requests == [
        LowLevelRequest("EQ", 1, [1, 2, 3]),
        LowLevelRequest("EQ", 1, [4]),
        LowLevelRequest("EQ", 1, [5, 6, 7]),
        LowLevelRequest("EQ", 1, [8]),
        LowLevelRequest("EQ", 1, [9, 10, 11]),
        LowLevelRequest("EQ", 1, [12])
    ]
Ejemplo n.º 3
0
def test_kinarow_with_bad_factor():
    bogus_factor = Factor("f", ["a", "b", "c"])
    with pytest.raises(ValueError):
        fully_cross_block(design, crossing, [
            ExactlyKInARow(
                2, (bogus_factor, get_level_from_name(bogus_factor, "a")))
        ])
Ejemplo n.º 4
0
def test_generate_encoding_diagram_with_window_with_stride():
    congruent_bookend = Factor("congruent bookend?", [
        DerivedLevel("yes", Window(lambda colors, texts: colors[0] == texts[0], [color, text], 1, 3)),
        DerivedLevel("no",  Window(lambda colors, texts: colors[0] != texts[0], [color, text], 1, 3))
    ])

    block = fully_cross_block([color, text, congruent_bookend], [color, text], [])

    assert __generate_encoding_diagram(block) == "\
------------------------------------------------------\n\
|   Trial |  color   |   text   | congruent bookend? |\n\
|       # | red blue | red blue |    yes       no    |\n\
------------------------------------------------------\n\
|       1 |  1   2   |  3   4   |    17        18    |\n\
|       2 |  5   6   |  7   8   |                    |\n\
|       3 |  9   10  | 11   12  |                    |\n\
|       4 | 13   14  | 15   16  |    19        20    |\n\
------------------------------------------------------\n"

    congruent_bookend = Factor("congruent bookend?", [
        DerivedLevel("yes", Window(lambda colors, texts: colors[0] == texts[0], [color, text], 2, 2)),
        DerivedLevel("no",  Window(lambda colors, texts: colors[0] != texts[0], [color, text], 2, 2))
    ])

    block = fully_cross_block([color, text, congruent_bookend], [color, text], [])

    assert __generate_encoding_diagram(block) == "\
def test_generate_derivations_should_raise_error_if_some_factor_matches_multiple_levels(
):
    local_con_factor = Factor("congruent?", [
        DerivedLevel("con", WithinTrial(op.eq, [color, text])),
        DerivedLevel("inc", WithinTrial(op.eq, [color, text]))
    ])

    with pytest.raises(ValueError):
        fully_cross_block([color, text, local_con_factor], [color, text], [])
def test_generate_derivations_should_produce_warning_if_some_level_is_unreachable(capsys):
    local_con_factor = Factor("congruent?", [
        DerivedLevel("con", WithinTrial(op.eq, [color, text])),
        DerivedLevel("inc", WithinTrial(op.ne, [color, text])),
        DerivedLevel("dum", WithinTrial(lambda c, t: c=='green', [color, text]))
    ])
    fully_cross_block([color, text, local_con_factor],
                      [color, text],
                      [])
    assert capsys.readouterr().out == "WARNING: There is no assignment that matches factor congruent? with level dum.\n"
Ejemplo n.º 7
0
def test_validate_accepts_derived_factors_with_simple_windows():
    block = fully_cross_block([color, text, con_factor_within_trial],
                              [color, text], [])
    UniformCombinatoricSamplingStrategy._UniformCombinatoricSamplingStrategy__validate(
        block)

    block = fully_cross_block([color, text, con_factor_window], [color, text],
                              [])
    UniformCombinatoricSamplingStrategy._UniformCombinatoricSamplingStrategy__validate(
        block)
def test_generate_derivations_should_raise_error_if_fn_doesnt_return_a_boolean():
    def local_eq(color, text):
            color == text # Notice the missing return stmt

    local_con_factor = Factor("congruent?", [
        DerivedLevel("con", WithinTrial(local_eq, [color, text])),
        DerivedLevel("inc", WithinTrial(lambda c, t: not local_eq(c, t), [color, text]))
    ])

    with pytest.raises(ValueError):
        fully_cross_block([color, text, local_con_factor],
                          [color, text],
                          [])
def test_generate_derivations_with_window():
    block = fully_cross_block([color, text, congruent_bookend], [color, text], [])

    assert DerivationProcessor.generate_derivations(block) == [
        Derivation(16, [[0, 2], [1, 3]], congruent_bookend),
        Derivation(17, [[0, 3], [1, 2]], congruent_bookend)
    ]
def test_generate_derivations_transition(design):
    block = fully_cross_block(design, [color, text], [])

    assert DerivationProcessor.generate_derivations(block) == [
        Derivation(16, [[0, 4], [1, 5]], color_repeats_factor),
        Derivation(17, [[0, 5], [1, 4]], color_repeats_factor)
    ]
Ejemplo n.º 11
0
def test_exclude_with_three_derived_levels():
    color_list = ["red", "green", "blue"]
    color = Factor("color", color_list)
    text = Factor("text", color_list)

    def count_diff(colors, texts):
        changes = 0
        if (colors[0] != colors[1]): changes += 1
        if (texts[0] != texts[1]): changes += 1
        return changes

    def make_k_diff_level(k):
        def k_diff(colors, texts):
            return count_diff(colors, texts) == k

        return DerivedLevel(str(k), Transition(k_diff, [color, text]))

    changed = Factor(
        "changed",
        [make_k_diff_level(0),
         make_k_diff_level(1),
         make_k_diff_level(2)])

    exclude_constraint = Exclude(changed, get_level_from_name(changed, "2"))

    design = [color, text, changed]
    crossing = [color, text]
    block = fully_cross_block(design, crossing, [exclude_constraint])

    backend_request = BackendRequest(0)
    exclude_constraint.apply(block, backend_request)
    assert backend_request.cnfs == [
        And([-57, -60, -63, -66, -69, -72, -75, -78])
    ]
Ejemplo n.º 12
0
def test_build_variable_list_for_simple_factors():
    block = fully_cross_block([color, text, con_factor], [color, text], [])

    assert block.build_variable_list((color, red_color)) == [1, 7, 13, 19]
    assert block.build_variable_list(
        (con_factor, get_level_from_name(con_factor,
                                         "con"))) == [5, 11, 17, 23]
Ejemplo n.º 13
0
def test_fully_cross_block_decode_variable_with_transition_first():
    block = fully_cross_block(
        [text_repeats_factor, text, color, color_repeats_factor],
        [color, text], [])

    assert block.decode_variable(1) == (text, red_text)
    assert block.decode_variable(2) == (text, blue_text)
    assert block.decode_variable(5) == (text, red_text)
    assert block.decode_variable(14) == (text, blue_text)

    assert block.decode_variable(3) == (color, red_color)
    assert block.decode_variable(4) == (color, blue_color)
    assert block.decode_variable(15) == (color, red_color)
    assert block.decode_variable(12) == (color, blue_color)

    assert block.decode_variable(17) == (text_repeats_factor, yes_text_repeats)
    assert block.decode_variable(18) == (text_repeats_factor, no_text_repeats)
    assert block.decode_variable(19) == (text_repeats_factor, yes_text_repeats)
    assert block.decode_variable(22) == (text_repeats_factor, no_text_repeats)

    assert block.decode_variable(23) == (color_repeats_factor,
                                         yes_color_repeats)
    assert block.decode_variable(24) == (color_repeats_factor,
                                         no_color_repeats)
    assert block.decode_variable(27) == (color_repeats_factor,
                                         yes_color_repeats)
    assert block.decode_variable(28) == (color_repeats_factor,
                                         no_color_repeats)
def test_generate_derivations_within_trial():
    assert DerivationProcessor.generate_derivations(blk) == [
        Derivation(4, [[0, 2], [1, 3]], con_factor),
        Derivation(5, [[0, 3], [1, 2]], con_factor)
    ]

    integer = Factor("integer", ["1", "2"])
    numeral = Factor("numeral", ["I", "II"])
    text = Factor("text", ["one", "two"])

    twoConLevel = DerivedLevel("twoCon",
                               WithinTrial(two_con, [integer, numeral, text]))
    twoNotConLevel = DerivedLevel(
        "twoNotCon", WithinTrial(two_not_con, [integer, numeral, text]))
    two_con_factor = Factor("twoCon?", [twoConLevel, twoNotConLevel])

    one_two_design = [integer, numeral, text, two_con_factor]
    one_two_crossing = [integer, numeral, text]

    assert DerivationProcessor.generate_derivations(
        fully_cross_block(one_two_design, one_two_crossing, [])) == [
            Derivation(6,
                       [[0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5],
                        [1, 3, 4]], two_con_factor),
            Derivation(7, [[0, 2, 4], [1, 3, 5]], two_con_factor)
        ]
Ejemplo n.º 15
0
def test_build_variable_list_for_three_derived_levels():
    def count_diff(colors, texts):
        changes = 0
        if (colors[0] != colors[1]): changes += 1
        if (texts[0] != texts[1]): changes += 1
        return changes

    def make_k_diff_level(k):
        def k_diff(colors, texts):
            return count_diff(colors, texts) == k

        return DerivedLevel(str(k), Transition(k_diff, [color, text]))

    changed = Factor(
        "changed",
        [make_k_diff_level(0),
         make_k_diff_level(1),
         make_k_diff_level(2)])

    block = fully_cross_block([color, text, changed], [color, text], [])

    assert block.build_variable_list(
        (changed, get_level_from_name(changed, "0"))) == [17, 20, 23]
    assert block.build_variable_list(
        (changed, get_level_from_name(changed, "1"))) == [18, 21, 24]
    assert block.build_variable_list(
        (changed, get_level_from_name(changed, "2"))) == [19, 22, 25]
def test_generate_sample_basic_stroop_variation(sequence_number, expected_solution):
    block = fully_cross_block([color, text, congruency],
                              [color, congruency],
                              [])
    enumerator = UCSolutionEnumerator(block)
    print (enumerator.generate_sample(sequence_number))
    assert enumerator.generate_sample(sequence_number) == expected_solution
Ejemplo n.º 17
0
def test_generate_encoding_diagram_with_constraint_and_multiple_transitions_in_different_order(
):
    block = fully_cross_block(
        [text_repeats_factor, color, color_repeats_factor, text, con_factor],
        [color, text], [])

    assert __generate_encoding_diagram(block) == "\
Ejemplo n.º 18
0
def test_fully_cross_with_transition_in_design(design):
    block = fully_cross_block(design, [color, text], [])

    backend_request = BackendRequest(23)
    FullyCross.apply(block, backend_request)

    (expected_cnf, _) = to_cnf_tseitin(
        And([
            Iff(23, And([1, 3])),
            Iff(24, And([1, 4])),
            Iff(25, And([2, 3])),
            Iff(26, And([2, 4])),
            Iff(27, And([5, 7])),
            Iff(28, And([5, 8])),
            Iff(29, And([6, 7])),
            Iff(30, And([6, 8])),
            Iff(31, And([9, 11])),
            Iff(32, And([9, 12])),
            Iff(33, And([10, 11])),
            Iff(34, And([10, 12])),
            Iff(35, And([13, 15])),
            Iff(36, And([13, 16])),
            Iff(37, And([14, 15])),
            Iff(38, And([14, 16]))
        ]), 39)

    assert backend_request.fresh == 72
    assert backend_request.cnfs == [expected_cnf]
    assert backend_request.ll_requests == [
        LowLevelRequest("GT", 0, [23, 27, 31, 35]),
        LowLevelRequest("GT", 0, [24, 28, 32, 36]),
        LowLevelRequest("GT", 0, [25, 29, 33, 37]),
        LowLevelRequest("GT", 0, [26, 30, 34, 38])
    ]
Ejemplo n.º 19
0
def test_fully_cross_simple():
    block = fully_cross_block([color, text], [color, text], [])

    (expected_cnf, _) = to_cnf_tseitin(
        And([
            Iff(17, And([1, 3])),
            Iff(18, And([1, 4])),
            Iff(19, And([2, 3])),
            Iff(20, And([2, 4])),
            Iff(21, And([5, 7])),
            Iff(22, And([5, 8])),
            Iff(23, And([6, 7])),
            Iff(24, And([6, 8])),
            Iff(25, And([9, 11])),
            Iff(26, And([9, 12])),
            Iff(27, And([10, 11])),
            Iff(28, And([10, 12])),
            Iff(29, And([13, 15])),
            Iff(30, And([13, 16])),
            Iff(31, And([14, 15])),
            Iff(32, And([14, 16]))
        ]), 33)

    backend_request = BackendRequest(17)
    FullyCross.apply(block, backend_request)

    assert backend_request.fresh == 66
    assert backend_request.cnfs == [expected_cnf]
    assert backend_request.ll_requests == [
        LowLevelRequest("GT", 0, [17, 21, 25, 29]),
        LowLevelRequest("GT", 0, [18, 22, 26, 30]),
        LowLevelRequest("GT", 0, [19, 23, 27, 31]),
        LowLevelRequest("GT", 0, [20, 24, 28, 32])
    ]
Ejemplo n.º 20
0
def test_consistency_with_transition_first_and_uneven_level_lengths():
    color3 = Factor("color3", ["red", "blue", "green"])

    yes_fn = lambda colors: colors[0] == colors[1] == colors[2]
    no_fn = lambda colors: not yes_fn(colors)
    color3_repeats_factor = Factor("color3 repeats?", [
        DerivedLevel("yes", Window(yes_fn, [color3], 3, 1)),
        DerivedLevel("no", Window(no_fn, [color3], 3, 1))
    ])

    block = fully_cross_block([color3_repeats_factor, color3, text],
                              [color3, text], [])

    backend_request = BackendRequest(0)
    Consistency.apply(block, backend_request)

    assert backend_request.ll_requests == [
        LowLevelRequest("EQ", 1, [1, 2, 3]),
        LowLevelRequest("EQ", 1, [4, 5]),
        LowLevelRequest("EQ", 1, [6, 7, 8]),
        LowLevelRequest("EQ", 1, [9, 10]),
        LowLevelRequest("EQ", 1, [11, 12, 13]),
        LowLevelRequest("EQ", 1, [14, 15]),
        LowLevelRequest("EQ", 1, [16, 17, 18]),
        LowLevelRequest("EQ", 1, [19, 20]),
        LowLevelRequest("EQ", 1, [21, 22, 23]),
        LowLevelRequest("EQ", 1, [24, 25]),
        LowLevelRequest("EQ", 1, [26, 27, 28]),
        LowLevelRequest("EQ", 1, [29, 30]),
        LowLevelRequest("EQ", 1, [31, 32]),
        LowLevelRequest("EQ", 1, [33, 34]),
        LowLevelRequest("EQ", 1, [35, 36]),
        LowLevelRequest("EQ", 1, [37, 38])
    ]
Ejemplo n.º 21
0
def test_derivation_with_multiple_transitions():
    block = fully_cross_block(
        [color, text, color_repeats_factor, text_repeats_factor],
        [color, text], [])

    # Text repeats derivation
    d = Derivation(22, [[2, 6], [3, 7]], text_repeats_factor)
    backend_request = BackendRequest(29)
    d.apply(block, backend_request)

    (expected_cnf, expected_fresh) = to_cnf_tseitin(
        And([
            Iff(23, Or([And([3, 7]), And([4, 8])])),
            Iff(25, Or([And([7, 11]), And([8, 12])])),
            Iff(27, Or([And([11, 15]), And([12, 16])]))
        ]), 29)

    assert backend_request.fresh == expected_fresh
    assert backend_request.cnfs == [expected_cnf]

    # Text does not repeat derivation
    d = Derivation(23, [[2, 7], [3, 6]], text_repeats_factor)
    backend_request = BackendRequest(29)
    d.apply(block, backend_request)

    (expected_cnf, expected_fresh) = to_cnf_tseitin(
        And([
            Iff(24, Or([And([3, 8]), And([4, 7])])),
            Iff(26, Or([And([7, 12]), And([8, 11])])),
            Iff(28, Or([And([11, 16]), And([12, 15])]))
        ]), 29)

    assert backend_request.fresh == expected_fresh
    assert backend_request.cnfs == [expected_cnf]
Ejemplo n.º 22
0
def test_fully_cross_with_uncrossed_simple_factors():
    other = Factor('other', ['l1', 'l2'])
    block = fully_cross_block([color, text, other], [color, text], [])

    backend_request = BackendRequest(25)
    FullyCross.apply(block, backend_request)

    (expected_cnf, _) = to_cnf_tseitin(
        And([
            Iff(25, And([1, 3])),
            Iff(26, And([1, 4])),
            Iff(27, And([2, 3])),
            Iff(28, And([2, 4])),
            Iff(29, And([7, 9])),
            Iff(30, And([7, 10])),
            Iff(31, And([8, 9])),
            Iff(32, And([8, 10])),
            Iff(33, And([13, 15])),
            Iff(34, And([13, 16])),
            Iff(35, And([14, 15])),
            Iff(36, And([14, 16])),
            Iff(37, And([19, 21])),
            Iff(38, And([19, 22])),
            Iff(39, And([20, 21])),
            Iff(40, And([20, 22]))
        ]), 41)

    assert backend_request.fresh == 74
    assert backend_request.cnfs == [expected_cnf]
    assert backend_request.ll_requests == [
        LowLevelRequest("GT", 0, [25, 29, 33, 37]),
        LowLevelRequest("GT", 0, [26, 30, 34, 38]),
        LowLevelRequest("GT", 0, [27, 31, 35, 39]),
        LowLevelRequest("GT", 0, [28, 32, 36, 40])
    ]
Ejemplo n.º 23
0
def test_no_solutions_without_override_flag():
    block = fully_cross_block(design, crossing, constraints)
    experiments = synthesize_trials_non_uniform(block, 500)

    assert block.crossing_size() == 6
    assert len(experiments) == 0
    assert_no_repetition(experiments)
Ejemplo n.º 24
0
def test_decode_with_transition():
    block = fully_cross_block([color, text, color_repeats_factor],
                              [color, text],
                              [])

    solution = [ 1,  -2,  3,  -4,
                 5,  -6, -7,   8,   #  17, -18
                -9,  10,  11, -12,  # -19,  20
                -13, 14, -15,  16,  #  21, -22
                17, -18, -19, 20, 21, -22] # color_repeats_factor
    decoded = __decode(block, solution)
    assert decoded['color'] ==          ['red', 'red',  'blue', 'blue']
    assert decoded['text']  ==          ['red', 'blue', 'red',  'blue']
    assert decoded['color repeats?'] == ['',    'yes',  'no',   'yes' ]


    solution = [ 1,  -2,  -3,   4,
                -5,   6,   7,  -8,
                -9,   10, -11,  12,
                 13, -14,  15, -16,
                -17,  18,  19, -20, -21, 22]
    decoded = __decode(block, solution)
    assert decoded['color'] ==          ['red',  'blue', 'blue', 'red']
    assert decoded['text']  ==          ['blue', 'red',  'blue', 'red']
    assert decoded['color repeats?'] == ['',     'no',   'yes',  'no' ]
Ejemplo n.º 25
0
def test_derivation_with_transition():
    block = fully_cross_block([color, text, color_repeats_factor],
                              [color, text], [])

    # Color repeats derivation
    d = Derivation(16, [[0, 4], [1, 5]], color_repeats_factor)
    backend_request = BackendRequest(23)
    d.apply(block, backend_request)

    (expected_cnf, expected_fresh) = to_cnf_tseitin(
        And([
            Iff(17, Or([And([1, 5]), And([2, 6])])),
            Iff(19, Or([And([5, 9]), And([6, 10])])),
            Iff(21, Or([And([9, 13]), And([10, 14])]))
        ]), 23)

    assert backend_request.fresh == expected_fresh
    assert backend_request.cnfs == [expected_cnf]

    # Color does not repeat derivation
    d = Derivation(17, [[0, 5], [1, 4]], color_repeats_factor)
    backend_request = BackendRequest(23)
    d.apply(block, backend_request)

    (expected_cnf, expected_fresh) = to_cnf_tseitin(
        And([
            Iff(18, Or([And([1, 6]), And([2, 5])])),
            Iff(20, Or([And([5, 10]), And([6, 9])])),
            Iff(22, Or([And([9, 14]), And([10, 13])]))
        ]), 23)

    assert backend_request.fresh == expected_fresh
    assert backend_request.cnfs == [expected_cnf]
Ejemplo n.º 26
0
def test_generate_derivations_when_derived_factor_precedes_dependencies():
    block = fully_cross_block([congruency, motion, color, task],
                              [color, motion, task], [])
    derivations = DerivationProcessor.generate_derivations(block)

    assert Derivation(0, [[4, 2], [5, 3]], congruency) in derivations
    assert Derivation(1, [[4, 3], [5, 2]], congruency) in derivations
Ejemplo n.º 27
0
def test_derivation_with_general_window():
    block = fully_cross_block([color, text, congruent_bookend], [color, text],
                              [])
    # congruent bookend - yes
    d = Derivation(16, [[0, 2], [1, 3]], congruent_bookend)
    backend_request = BackendRequest(19)
    d.apply(block, backend_request)

    (expected_cnf, expected_fresh) = to_cnf_tseitin(
        And([
            Iff(17, Or([And([1, 3]), And([2, 4])])),
            Iff(19, Or([And([13, 15]), And([14, 16])]))
        ]), 19)

    assert backend_request.fresh == expected_fresh
    assert backend_request.cnfs == [expected_cnf]

    # congruent bookend - no
    d = Derivation(17, [[0, 3], [1, 2]], congruent_bookend)
    backend_request = BackendRequest(19)
    d.apply(block, backend_request)

    (expected_cnf, expected_fresh) = to_cnf_tseitin(
        And([
            Iff(18, Or([And([1, 4]), And([2, 3])])),
            Iff(20, Or([And([13, 16]), And([14, 15])]))
        ]), 19)

    assert backend_request.fresh == expected_fresh
    assert backend_request.cnfs == [expected_cnf]
Ejemplo n.º 28
0
def test_validate_rejects_exclude_constraints():
    block = fully_cross_block([color, text, con_factor_within_trial],
                              [color, text], [Exclude(color, red_color)])

    with pytest.raises(ValueError):
        UniformCombinatoricSamplingStrategy._UniformCombinatoricSamplingStrategy__validate(
            block)
Ejemplo n.º 29
0
def test_correct_solution_count_when_unconstrained(design):
    crossing = [color, text]
    constraints = []

    block = fully_cross_block(design, crossing, constraints)
    experiments = synthesize_trials_non_uniform(block, 100)

    assert len(experiments) == 24
Ejemplo n.º 30
0
def test_consistency_with_multiple_transitions(design):
    block = fully_cross_block(design, [color, text], [])

    backend_request = BackendRequest(0)
    Consistency.apply(block, backend_request)

    assert backend_request.ll_requests == \
        list(map(lambda x: LowLevelRequest("EQ", 1, [x, x+1]), range(1, 28, 2)))