예제 #1
0
파일: sat.py 프로젝트: frenetic-lang/slices
def transfer(topo, p_out, p_in):
    """Build constraint for moving p_out to p_in across an edge."""
    options = []
    for s1, s2 in topo.edges():
        p1 = topo.node[s1]["ports"][s2]
        p2 = topo.node[s2]["ports"][s1]
        # Need both directions because topo.edges() only gives one direction for
        # undirected graphs.
        constraint1 = And(And(switch(p_out) == s1, port(p_out) == p1), And(switch(p_in) == s2, port(p_in) == p2))
        constraint2 = And(And(switch(p_out) == s2, port(p_out) == p2), And(switch(p_in) == s1, port(p_in) == p1))
        options.append(constraint1)
        options.append(constraint2)
    forward = nary_or(options)

    # We also need to ensure that the rest of the packet is the same.  Without
    # this, packet properties can change in flight.
    header_constraints = []
    for f in HEADERS:
        if f is not "switch" and f is not "port":
            header_constraints.append(HEADER_INDEX[f](p_out) == HEADER_INDEX[f](p_in))
    # header_constraints is never empty
    return And(forward, nary_and(header_constraints))
예제 #2
0
파일: sat.py 프로젝트: frenetic-lang/slices
def one_per_edge(topo, pol, field="vlan"):
    """Determine if pol only uses one value of field on each internal edge.
    
    We don't care about external edges because they never have the problem of
    preventing tiling of two-node connectivity since this slice never reads
    packets sent to them.
    """

    p, pp, q, qq = Consts("p pp q qq", Packet)
    r, rr, s, ss = Consts("r rr s ss", Packet)

    solv = Solver()
    solv.add(forwards(pol, p, pp))
    solv.add(transfer(topo, pp, r))
    solv.add(forwards(pol, r, rr))
    solv.add(forwards(pol, q, qq))
    solv.add(switch(pp) == switch(qq))
    solv.add(port(pp) == port(qq))
    solv.add(HEADER_INDEX[field](pp) != HEADER_INDEX[field](qq))
    if solv.check() == unsat:
        return None
    else:
        return solv.model(), (p, pp), HEADER_INDEX