def can_orient(G,edge):
    """Test whether edge should be oriented under PC algorithm rules for non-collider edges.
    
    :param G: partially oriented graph
    :param edge: edge of G under test
    :returns: True if edge should be oriented, False otherwise
    """

    if not G.is_undir_edge(edge): # test that edge is not already oriented
        return False
    # tests from [2]
    x,y = edge
    testR1 = [z for z in G if G.is_dir_edge((z,x)) and G.is_non_adj((z, y))]
    testR2 = [z for z in G if G.is_dir_edge((x,z)) and G.is_dir_edge((z,y))]
    non_adj_list = [(z1,z2) for z1 in G for z2 in G if G.is_non_adj((z1, z2))]
    testR3 = [(z1,z2) for (z1,z2) in non_adj_list
              if G.is_undir_edge((x, z1)) and G.is_dir_edge((z1, y))
              and G.is_undir_edge((x, z2)) and G.is_dir_edge((z2, y))]
    testR4 = [(z1,z2) for (z1,z2) in non_adj_list
              if G.is_undir_edge((x, z1)) and G.is_dir_edge((z1, z2)) and G.is_dir_edge((z2, y))]
    if testR1 or testR2 or testR3 or testR4:
        return True
    else:
        return False