
procedure check_separator(G, S)

    H := G;
    
    vs := [ Integers() | Index(x) : x in S ];

    if Type(H) eq GrphDir then

	if not IsEmpty(S) then
	    assert IsStronglyConnected(H);
	    
	    RemoveVertices(~H, vs);
	    assert (Order(H) eq 1) or not IsStronglyConnected(H);
	else
	    assert (Order(H) eq 1) or not IsStronglyConnected(H);
	end if;
    else
	if not IsEmpty(S) then
	    assert IsConnected(H);
	    
	    RemoveVertices(~H, vs);
	    assert (Order(H) eq 1) or (not IsConnected(H));
	else
	    assert (Order(H) eq 1) or (not IsConnected(H));
	end if;
    end if;

    for v in S do
	H := G; 
	s := S;
	Exclude(~s, v);
	vs := [ Integers() | Index(x) : x in s ];
	
	if Type(G) eq GrphDir then

	    RemoveVertices(~H, vs); 
	    assert IsStronglyConnected(H);
	else

	    RemoveVertices(~H, vs); 
	    assert IsConnected(H);
	end if;
    end for;
    
end procedure;

procedure check_e_separator(G, S)

    H := G;
    if Type(H) eq GrphDir then

	if not IsEmpty(S) then
	    assert IsStronglyConnected(H);
	    
	    M := [ [  Index(e[1]), Index(e[2]) ]
	    where e := EndVertices(e) : e in S ];
	    RemoveEdges(~H, M);
	    assert not IsStronglyConnected(H);
	else
	    assert not IsStronglyConnected(H);
	end if;
    else
	if not IsEmpty(S) then
	    assert IsConnected(H);
	    
	    M := [ { Index(e[1]), Index(e[2]) }
	    where e := SetToSequence(EndVertices(e)) : e in S ];
	    RemoveEdges(~H, M);
	    assert not IsConnected(H);
	else
	    assert not IsConnected(H);
	end if;
    end if;

    for e in S do
	H := G; 
	s := S;
	Exclude(~s, e);
	
	if Type(G) eq GrphDir then

	    M := [ [  Index(e[1]), Index(e[2]) ]
	    where e := EndVertices(e) : e in s ];
	    RemoveEdges(~H, M);

	    assert IsStronglyConnected(H);
	else

	    M := [ { Index(e[1]), Index(e[2]) }
	    where e := SetToSequence(EndVertices(e)) : e in s ];
	    RemoveEdges(~H, M);
	    assert IsConnected(H);
	end if;
    end for;
    
end procedure;


procedure check_v_conn(G, c)

    for k in [0..c] do
	assert IsKVertexConnected(G, k);
    end for;
    for k in [c+1..Order(G)-1] do
	assert not IsKVertexConnected(G, k);
    end for;
    
end procedure;


procedure check_v_conn_dinic(G, c)

    for k in [0..c] do
	assert IsKVertexConnected(G, k : Al := "Dinic");
    end for;
    for k in [c+1..Order(G)-1] do
	assert not IsKVertexConnected(G, k : Al := "Dinic");
    end for;
    
end procedure;



procedure check_e_conn(G, c)

    for k in [0..c] do
	assert IsKEdgeConnected(G, k);
    end for;
    for k in [c+1..Order(G)-1] do
	assert not IsKEdgeConnected(G, k);
    end for;
    
end procedure;




procedure check_e_conn_dinic(G, c)

    for k in [0..c] do
	assert IsKEdgeConnected(G, k : Al := "Dinic");
    end for;
    for k in [c+1..Order(G)-1] do
	assert not IsKEdgeConnected(G, k : Al := "Dinic");
    end for;
    
end procedure;


procedure check_matching(G, M)

    H := G;
    N := EmptyGraph(Order(G));

    MM := [ { Index(e[1]), Index(e[2]) }
    where e := SetToSequence(EndVertices(e)) : e in M ];

    while not IsEmpty(MM) do

	RemoveEdges(~H, MM);
	AddEdges(~N, MM);
	
	M := MaximumMatching(H);
	MM := [ { Index(e[1]), Index(e[2]) }
	where e := SetToSequence(EndVertices(e)) : e in M ];
	
    end while;

    assert N eq G;
    
end procedure;

procedure check_matching_dinic(G, M)

    H := G;
    N := EmptyGraph(Order(G));

    MM := [ { Index(e[1]), Index(e[2]) }
    where e := SetToSequence(EndVertices(e)) : e in M ];

    while not IsEmpty(MM) do

	RemoveEdges(~H, MM);
	AddEdges(~N, MM);
	
	M := MaximumMatching(H : Al := "Dinic");
	MM := [ { Index(e[1]), Index(e[2]) }
	where e := SetToSequence(EndVertices(e)) : e in M ];
	
    end while;

    assert N eq G;
    
end procedure;


function stack_graph(G, m)
    /*
    stack m G graphs one above the other
    */

    if m le 1 then
	return G;
    end if;

    n := Order(G);
    K := G;
    for i in [1..m-1] do
	K := Union(K, G);
	for v in [1..n] do
	    AddEdge(~K, (i-1)*n + v, i*n + v);
	end for;
	assert Order(K) eq (i+1)*n;
	assert Size(K) eq (i+1)*Size(G)+ i*n;
    end for;
    
    return K;
    
end function;


function union_graph(G, m)
    /*
    union of m G graphs
    */

    if m le 1 then
	return G;
    end if;

    n := Order(G);
    K := G;
    for i in [1..m-1] do
	K := CompleteUnion(K, G);
	assert Order(K) eq (i+1)*n;
    end for;
    
    return K;
    
end function;

function rand_bip(n, m, d)
    /*
    a random bipartite graph
    */

    G := EmptyGraph(n);
    H := EmptyGraph(m);
    G := G join H;

    if d gt m then
	d := m;
    end if;

    for u in [1..n] do
	t := Random(0, d);
	for tt in [1..t] do
	    v := Random(n+1, n+m); 
	    AddEdge(~G, VertexSet(G)!u, VertexSet(G)!v);
	end for;
    end for;
    
    G := Graph< Order(G) | G : SparseRep := true >;
    return G;
    
end function;


function rand_net(n, d, c, j)
    /*
    a random network
    */

    S := [];

    for i in [1..j] do 

        s := 0;
        while s eq 0 do
            G := RandomDigraph(n, d : SparseRep := true);
            s := Size(G);
        end while;
	E := [ [ Index(EndVertices(e)[1]),
	Index(EndVertices(e)[2]) ] : e in Edges(G) ];
	Ec := [ < [e[1], e[2]], cap > where cap := Random(0, c) :
	e in E | not e[1] eq e[2] ];
	Ec := Ec cat [ < [e[1], e[2]], 0 >  : e in E | e[1] eq e[2] ];
	
	for j in [1..#Ec] do
	    Append(~S, Ec[j]);
	end for;

    end for;

    G := Network< n | S >;
    
    return G;
    
end function;

function rand_unit_net(n, d, j)
    /*
    a random unit network
    */

    S := [];

    for i in [1..j] do 

        s := 0;
        while s eq 0 do
            G := RandomDigraph(n, d : SparseRep := true);
            s := Size(G);
        end while;
        E := [ [ Index(EndVertices(e)[1]),
        Index(EndVertices(e)[2]) ] : e in Edges(G) ];
        Ec := [ < [e[1], e[2]], 1 > : e in E | not e[1] eq e[2] ];
	Ec := Ec cat [ < [e[1], e[2]], 0 >  : e in E | e[1] eq e[2] ];

        for j in [1..#Ec] do
            Append(~S, Ec[j]);
        end for;

    end for;

    G := Network< n | S >;
    
    return G;
    
end function;

function rand_multi_graph(n, d)
    /*
    a random multigraph
    */

    G1 := RandomGraph(n, d : SparseRep := true);
    G2 := RandomGraph(n, d : SparseRep := true);
    G3 := RandomGraph(n, d : SparseRep := true);

    return MultiGraph< n | G1, G2, G3 >;
    
end function;

function rand_multi_digraph(n, d)
    /*
    a random multigraph
    */

    G1 := RandomDigraph(n, d : SparseRep := true);
    G2 := RandomDigraph(n, d : SparseRep := true);
    G3 := RandomDigraph(n, d : SparseRep := true);

    return MultiDigraph< n | G1, G2, G3 >;
    
end function;

function prepend_vertices(G, n)
    /*
    return the graph of size Order(G) + n with all edges
    relabelled
    */

    T := Type(G);
    if T eq GrphUnd then
	H := EmptyGraph(Order(G) + n);
    elif T eq GrphDir then
	H := EmptyDigraph(Order(G) + n);
    elif T eq GrphNet then
	H := EmptyNetwork(Order(G) + n);
    elif T eq GrphMultUnd then
	H := EmptyMultiGraph(Order(G) + n);
    else 
	H := EmptyMultiDigraph(Order(G) + n);
    end if;

    V := VertexSet(H);
    E := Edges(G);
    for e in E do
	ea := e; ca := -1;
	if T eq GrphUnd then
	    ea := SetToSequence(EndVertices(e));
	elif T eq GrphDir then
	    ea := EndVertices(e);
	elif T eq GrphNet then
	    ea := EndVertices(e);
	    ca := Capacity(e);
	elif T eq GrphMultUnd then
	    ea := SetToSequence(EndVertices(e));
	else 
	    ea := EndVertices(e);
	end if;

	u := Index(ea[1]) + n;
	v := Index(ea[2]) + n;

	if not T eq GrphNet then
	    AddEdge(~H, VertexSet(H)!u, VertexSet(H)!v);
	else
	    assert ca ge 0;
	    AddEdge(~H, VertexSet(H)!u, VertexSet(H)!v, ca);
	end if;
    end for;

    return H;
    
end function;
    
    
procedure check_cut(N, s, t, F, C)

    cap := 0;
    EdgeCut := {};
    for edge in Edges(N) do
	u := EndVertices(edge)[1];
	v := EndVertices(edge)[2];
	if u in C and (not v in C) then
	    Include(~EdgeCut, edge);
	    assert Capacity(edge) eq Flow(edge);
	    cap +:= Capacity(edge);
	    assert Capacity(u, v) eq Flow(u, v);
	end if;
    end for;
    
    assert cap eq F;

    H := N;
    RemoveEdges(~H, EdgeCut);
    V := VertexSet(H);

    FF, CC := MaximumFlow(V!s, V!t);
    FFF, CCC := MaximumFlow(V!s, V!t : Al := "Dinic");
    assert FFF eq FF;
    assert FF eq 0;
    // assert #CC eq Order(H) - 1 or #CC eq 1;
    CC := [ Index(c) : c in CC ];
    assert not t in CC;
    assert #CCC eq 1;
    assert Index(CCC[1]) eq s;

end procedure;

procedure check_multi_cut(N, S, T, F, C)

    cap := 0;
    EdgeCut := {};
    for edge in Edges(N) do
	u := EndVertices(edge)[1];
	v := EndVertices(edge)[2];
	if u in C and (not v in C) then
	    Include(~EdgeCut, edge);
	    assert Capacity(edge) eq Flow(edge);
	    cap +:= Capacity(edge);
	    assert Capacity(u, v) eq Flow(u, v);
	end if;
    end for;
    
    assert cap eq F;

    H := N;
    RemoveEdges(~H, EdgeCut);
    V := VertexSet(H);
    SS := [ V!i : i in S ];
    TT := [ V!i : i in T ];

    
    FF, CC := MaximumFlow(SS, TT);
    assert FF eq 0;

end procedure;

function get_2_rand_int(n)

    a := Random(1, n);
    b := a;
    while b eq a do
	b := Random(1, n);
    end while;

    return a, b;
    
end function;

function get_3_rand(S)

    a := Random(S);
    b := a;
    while b eq a do
	b := Random(S);
    end while;
    c := a;
    while c eq a or c eq b do
	c := Random(S);
    end while;

    return a, b, c;
    
end function;

procedure check_sub(N)

    SE := {};
    for edge in Edges(N) do
	u := EndVertices(edge)[1];
	v := EndVertices(edge)[2]; 
	c := Capacity(edge);
	Include(~SE, <[u, v], c>);
    end for;

    H := sub< N | SE >;
    assert IsSubgraph(N, H);

    a, b, c := get_3_rand(SE);
    H := sub< N | a, b, c >;
    assert IsSubgraph(N, H);

    SE := {};
    for edge in Edges(N) do
	u := EndVertices(edge)[1];
	v := EndVertices(edge)[2]; 
	Include(~SE, [u, v]);
    end for;

    H := sub< N | SE >;
    assert IsSubgraph(N, H);

    a, b, c := get_3_rand(SE);
    H := sub< N | a, b, c >;
    assert IsSubgraph(N, H);

    SE := { e : e in Edges(N) };
    H := sub< N | SE >;
    assert IsSubgraph(N, H);
    assert H eq N;

    a, b, c := get_3_rand(SE);
    H := sub< N | a, b, c >;
    assert IsSubgraph(N, H);

    SV := { v : v in Vertices(N) };
    H := sub< N | SV >;
    assert IsSubgraph(N, H);
    assert H eq N;

    a, b, c := get_3_rand(SE);
    H := sub< N | a, b, c >;
    assert IsSubgraph(N, H);
    
end procedure;

procedure check_join(H, G1, G2)

    assert Order(H) eq Order(G1) + Order(G2);
    assert Size(H) eq Size(G1) + Size(G2);
    assert IsSubgraph(H, G1);
    
    NG1 := G1 + Order(G2);
    NG2 := prepend_vertices(G2, Order(G1));
    NH := EdgeUnion(NG1, NG2);

    assert NH eq H;

    S := { G1, G2, NH, H };
    s := [];
    for g in S do
	Append(~s, g);
    end for;
    assert &join S eq &join s;

end procedure;


function rand_graph(n, d, c)
    
    i := Random(1, 7);

    //print "i", i;

    case i:

        when 1:
	//print "und simple and dense";
	return RandomGraph(n, d);
	
	when 2:
	//print "und simple and sparse";
	return RandomGraph(n, d : SparseRep := true);
	
	when 3:
	//print "dir simple and dense";
	return RandomDigraph(n, d);
	
	when 4:
	//print "dir simple and sparse";
	return RandomDigraph(n, d : SparseRep := true);
	
	when 5:
	//print "multi graph";
	return rand_multi_graph(n, d);
	
	when 6:
	//print "multi digraph";
	return rand_multi_digraph(n, d);
	
	when 7:
	//print "network";
	return rand_net(n, d, c, 3);
	
    end case;
    
end function;

function copy_net(N)

    n := Order(N);
    D := MultiDigraph< n | >;
    for e in EdgeSet(N) do
	D, edge := AddEdge(D,
	VertexSet(D)!InitialVertex(e),
	VertexSet(D)!TerminalVertex(e));
	AssignCapacity(~D, edge, Capacity(e));
    end for;

    return D;
end function;


function underlying(G)
    case Type(G):

        when GrphUnd:
	return UnderlyingGraph(G);
        
        when GrphDir:
	return UnderlyingDigraph(G);
        
        when GrphMultUnd:
        return UnderlyingMultiGraph(G);
        
        when GrphMultDir:
	return UnderlyingMultiDigraph(G);
        
        when GrphNet:
	return UnderlyingNetwork(G);
        
    end case;
end function;

function get_graph(S, G)
    case Type(G):

        when GrphUnd:
	return Graph< S | G >;
        
        when GrphDir:
	return Digraph< S | G >;
        
        when GrphMultUnd:
        return MultiGraph< S | G >;
        
        when GrphMultDir:
	return MultiDigraph< S | G >;
        
        when GrphNet:
	return Network< S | G >;
        
    end case;
end function;

procedure test_sup_labels(G)

    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];

    n := Order(G);

    // support
    S := {@ @};
    while #S lt n do
        Include(~S, &cat [ Random(A) : i in [1..3] ]);
    end while;
    assert #S eq n;
    
    GG := get_graph(S, G);
    //Support(GG);
    assert not GG eq G;
    assert underlying(GG) eq G;
    
    assert not IsSubgraph(G, GG);
    assert IsSubgraph(G, underlying(GG));
    
    VS := { Random(VertexSet(GG)) : i in [1..n div 2] };
    H := sub< GG | VS >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);
    assert not IsSubgraph(GG, underlying(H));
    
    ES := { Random(EdgeSet(GG)) : i in [1..n div 2] };
    H := sub< GG | ES >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);
    assert not IsSubgraph(GG, underlying(HH));
    
    // vertex labels
    V := VertexSet(GG);
    for u in [1..Order(GG)] do
	p := Random(1, 2);
	if p eq 1 then
	    AssignLabel(~GG, V!u, Random(1, Order(GG)));
	end if;
    end for;
    //VertexLabels(GG);
    ChangeUniverse(~VS, VertexSet(GG));
    H := sub< GG | VS >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);
    assert not IsSubgraph(GG, underlying(HH));
    
    ChangeUniverse(~ES, EdgeSet(GG));
    H := sub< GG | ES >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);
    assert not IsSubgraph(GG, underlying(HH));
    
    // edge labels
    E := EdgeSet(GG);
    size := Size(GG);
    if not IsSimple(GG) and not IsDirected(GG) then
	size := 2 * Size(GG);
    end if;
    for e in [1..size] do 
	p := Random(1, 2);
	if p eq 1 then
	    AssignLabel(~GG, E.e, Random(A));
	end if;
    end for;
    //EdgeLabels(GG);
    ChangeUniverse(~VS, VertexSet(GG));
    H := sub< GG | VS >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);
    assert not IsSubgraph(GG, underlying(HH));
    
    ChangeUniverse(~ES, EdgeSet(GG));
    H := sub< GG | ES >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);
    assert not IsSubgraph(GG, underlying(HH));

end procedure;


procedure test_sup_labels_add_remove(G)
    
    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];

    n := Order(G);

    // support
    S := {@ @};
    while #S lt n do
        Include(~S, &cat [ Random(A) : i in [1..3] ]);
    end while;
    assert #S eq n;

    GG := get_graph(S, G);

    ////////////// Support(GG);
    H := GG;
    for i in [1..n div 2] do
	H -:= Random(VertexSet(H));
	assert IsSubgraph(GG, H);
	assert IsSubgraph(underlying(GG), underlying(H));
	assert IsSubgraph(StandardGraph(GG),
	StandardGraph(H));
	assert IsSubgraph(UnlabelledGraph(GG),
	UnlabelledGraph(H));
    end for;

    HH := H;
    for i in [1..n div 2] do
	HH +:= 1;
	assert not IsSubgraph(HH, H);
	assert IsSubgraph(underlying(HH), underlying(H));
	assert IsSubgraph(StandardGraph(HH),
	StandardGraph(H));
	assert not IsSubgraph(UnlabelledGraph(HH),
	UnlabelledGraph(H));
    end for;

    H := GG;
    for i in [1..n div 2] do
	H -:= { Random(EdgeSet(H)) };
	assert IsSubgraph(GG, H);
	assert IsSubgraph(underlying(GG), underlying(H));
	assert IsSubgraph(StandardGraph(GG),
	StandardGraph(H));
	assert IsSubgraph(UnlabelledGraph(GG),
	UnlabelledGraph(H));
    end for;

    H := GG;
    for i in [1..n div 2] do
	a, b := get_2_rand_int(n);
	c := Random(1, n);
	if not Type(GG) eq GrphNet then
	    AddEdge(~H, VertexSet(H)!a, VertexSet(H)!b);
	else
	    AddEdge(~H, VertexSet(H)!a, VertexSet(H)!b, c);
	end if;
	assert IsSubgraph(H, GG);
	assert IsSubgraph(underlying(H), underlying(GG));
	assert IsSubgraph(StandardGraph(H),
	StandardGraph(GG));
	assert IsSubgraph(UnlabelledGraph(H),
	UnlabelledGraph(GG));
    end for;
    
    ///////////////// vertex labels
    V := VertexSet(GG);
    for u in [1..Order(GG)] do
        p := Random(1, 2);
        if p eq 1 then
            AssignLabel(~GG, V!u, Random(1, Order(GG)));
        end if;
    end for;

    H := GG;
    for i in [1..n div 2] do
	H -:= Random(VertexSet(H));
	assert IsSubgraph(GG, H);
	assert IsSubgraph(underlying(GG), underlying(H));
	assert IsSubgraph(StandardGraph(GG),
	StandardGraph(H));
	assert IsSubgraph(UnlabelledGraph(GG),
	UnlabelledGraph(H));
    end for;

    HH := H;
    for i in [1..n div 2] do
	HH +:= 1;
	assert not IsSubgraph(HH, H);
	assert IsSubgraph(underlying(HH), underlying(H));
	assert IsSubgraph(StandardGraph(HH),
	StandardGraph(H));
	assert not IsSubgraph(UnlabelledGraph(HH),
	UnlabelledGraph(H));
    end for;

    HH := H;
    for i in [1..n div 2] do
	AddVertex(~HH, Random(1, Order(GG)));
	assert not IsSubgraph(HH, H);
	assert IsSubgraph(underlying(HH), underlying(H));
	assert IsSubgraph(StandardGraph(HH),
	StandardGraph(H));
	assert not IsSubgraph(UnlabelledGraph(HH),
	UnlabelledGraph(H));
    end for;

    H := GG;
    for i in [1..n div 2] do
	H -:= { Random(EdgeSet(H)) };
	assert IsSubgraph(GG, H);
	assert IsSubgraph(underlying(GG), underlying(H));
	assert IsSubgraph(StandardGraph(GG),
	StandardGraph(H));
	assert IsSubgraph(UnlabelledGraph(GG),
	UnlabelledGraph(H));
    end for;

    H := GG;
    for i in [1..n div 2] do
	a, b := get_2_rand_int(n);
	c := Random(1, n);
	if not VertexSet(H)!a adj VertexSet(H)!b then
	    if not Type(GG) eq GrphNet then
		AddEdge(~H,
		VertexSet(H)!a, VertexSet(H)!b);
	    else
		AddEdge(~H,
		VertexSet(H)!a, VertexSet(H)!b, c);
	    end if;
	end if;
	assert IsSubgraph(H, GG);
	assert IsSubgraph(underlying(H), underlying(GG));
	assert IsSubgraph(StandardGraph(H),
	StandardGraph(GG));
	assert IsSubgraph(UnlabelledGraph(H),
	UnlabelledGraph(GG));
    end for;

    /////////////// edge labels
    E := EdgeSet(GG);
    size := Size(GG);
    if not IsSimple(GG) and not IsDirected(GG) then
        size := 2 * Size(GG);
    end if;
    for e in [1..size] do 
        p := Random(1, 2);
        if p eq 1 then
            AssignLabel(~GG, E.e, Random(A));
        end if;
    end for;

    H := GG;
    for i in [1..n div 2] do
	////GetSeed();
	H -:= Random(VertexSet(H));
	assert IsSubgraph(GG, H);
	assert IsSubgraph(underlying(GG), underlying(H));
	assert IsSubgraph(StandardGraph(GG),
	StandardGraph(H));
	assert IsSubgraph(UnlabelledGraph(GG),
	UnlabelledGraph(H));
    end for;

    HH := H;
    for i in [1..n div 2] do
	HH +:= 1;
	assert not IsSubgraph(HH, H);
	assert IsSubgraph(underlying(HH), underlying(H));
	assert IsSubgraph(StandardGraph(HH),
	StandardGraph(H));
	assert not IsSubgraph(UnlabelledGraph(HH),
	UnlabelledGraph(H));
    end for;

    HH := H;
    for i in [1..n div 2] do
	AddVertex(~HH, Random(1, Order(GG)));
	assert not IsSubgraph(HH, H);
	assert IsSubgraph(underlying(HH), underlying(H));
	assert IsSubgraph(StandardGraph(HH),
	StandardGraph(H));
	assert not IsSubgraph(UnlabelledGraph(HH),
	UnlabelledGraph(H));
    end for;

    H := GG;
    for i in [1..n div 2] do
	H -:= { Random(EdgeSet(H)) };
	assert IsSubgraph(GG, H);
	assert IsSubgraph(underlying(GG), underlying(H));
	assert IsSubgraph(StandardGraph(GG),
	StandardGraph(H));
	assert IsSubgraph(UnlabelledGraph(GG),
	UnlabelledGraph(H));
    end for;

    H := GG;
    for i in [1..n div 2] do
	a, b := get_2_rand_int(n);
	c := Random(1, n);
	if not VertexSet(H)!a adj VertexSet(H)!b then
	    if not Type(GG) eq GrphNet then
		AddEdge(~H,
		VertexSet(H)!a, VertexSet(H)!b);
	    else
		AddEdge(~H,
		VertexSet(H)!a, VertexSet(H)!b, c);
	    end if;
	end if;
	assert IsSubgraph(H, GG);
	assert IsSubgraph(underlying(H), underlying(GG));
	assert IsSubgraph(StandardGraph(H),
	StandardGraph(GG));
	assert IsSubgraph(UnlabelledGraph(H),
	UnlabelledGraph(GG));
    end for;

    H := GG;
    for i in [1..n div 2] do
	a, b := get_2_rand_int(n);
	c := Random(1, n);
	if not VertexSet(H)!a adj VertexSet(H)!b then
	    if not Type(GG) eq GrphNet then
		AddEdge(~H,
		VertexSet(H)!a, VertexSet(H)!b,
		Random(A));
	    else
		AddEdge(~H,
		VertexSet(H)!a, VertexSet(H)!b, c,
		Random(A));
	    end if;
	end if;
	assert IsSubgraph(H, GG);
	assert IsSubgraph(underlying(H), underlying(GG));
	assert IsSubgraph(StandardGraph(H),
	StandardGraph(GG));
	assert IsSubgraph(UnlabelledGraph(H),
	UnlabelledGraph(GG));
    end for;

end procedure;


procedure test_sup_labels_eq(G)
    
    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];
    
    n := Order(G);

    // support
    S := {@ @};
    while #S lt n do
        Include(~S, &cat [ Random(A) : i in [1..3] ]);
    end while;
    assert #S eq n;

    GG := get_graph(S, G);

    /////// vertices & labels
    m := n div 5;

    H1 := GG;
    H2 := GG;
    AddVertices(~H1, m);
    H2 := H2 + m;
    assert H1 eq H2;
    g := underlying(GG);
    assert IsSubgraph(H1, underlying(GG));
    assert IsSubgraph(H2, underlying(GG));
    /*
    for i in [1..Order(GG)] do
	assert VertexSet(underlying(GG))!i
	eq VertexSet(H1)!i;
	assert VertexSet(underlying(GG))!i
	eq VertexSet(H2)!i;
    end for;
    */
    for v in [1..m] do
	RemoveVertex(~H1, VertexSet(H1)!(n+1));
	H2 := H2 - VertexSet(H2)!(n+1);
    end for;
    assert H1 eq underlying(GG);
    assert H2 eq underlying(GG);
    assert IsSubgraph(H1, underlying(GG));
    assert IsSubgraph(H2, underlying(GG));

    AddVertices(~H1, m);
    H2 := H2 + m;
    assert H1 eq H2;
    S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
    S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
    RemoveVertices(~H1, S1);
    H2 := H2 - S2;
    assert H1 eq underlying(GG);
    assert H2 eq underlying(GG);
    assert IsSubgraph(H1, underlying(GG));
    assert IsSubgraph(H2, underlying(GG));

    L := [];
    for i in [1..m] do
	Append(~L, IntegerToString(i));
    end for;
    for i in [1..m] do
	AddVertex(~H1, L[i]);
    end for;
    for i in [1..m] do
	assert IsLabelled(VertexSet(H1)!(n+i));
    end for;
    for i in [1..m] do
	RemoveVertex(~H1, VertexSet(H1)!(n+1));
    end for;
    assert not IsVertexLabelled(H1);
    assert H1 eq underlying(GG);
    AddVertices(~H1, m, L);
    for i in [1..m] do
	assert IsLabelled(VertexSet(H1)!(n+i));
    end for;
    S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
    RemoveVertices(~H1, S1);
    assert not IsVertexLabelled(H1);
    assert H1 eq underlying(GG);


    //edges & labels
    EP := {};
    for u in VertexSet(GG) do
	for v in VertexSet(GG) do
	    if not u eq v and not u adj v then
		if Type(GG) eq GrphUnd 
		    or Type(GG) eq GrphMultUnd then
		    if not {v,u} in EP then
			Include(~EP, {u,v});
		    end if;
		elif Type(GG) eq GrphDir
		    or Type(GG) eq GrphMultDir then
		    if not [u, v] in EP then
			Include(~EP, [u,v]);
		    end if;
		else
		    Include(~EP, <[u,v], Random(1, m)>);
		end if;
	    end if;
	end for;
    end for;
    H1 := GG;
    
    L := [];
    for i in [1..#EP] do
	Append(~L, IntegerToString(i));
    end for;
    EPL := SetToSequence(EP);

    EPA := {};
    for i in [1..#EP] do
	e := EPL[i];
	if Type(H1) eq GrphUnd then
	    H1, edge := AddEdge(H1,
	    SetToSequence(e)[1], SetToSequence(e)[2],
	    L[i]);
	    ChangeUniverse(~EPA, EdgeSet(H1));
	    Include(~EPA, edge);
	    assert IsLabelled(EdgeSet(H1)!e);
	elif Type(H1) eq GrphMultUnd then
	    H1, edge := AddEdge(H1,
	    SetToSequence(e)[1], SetToSequence(e)[2],
	    L[i]);
	    ChangeUniverse(~EPA, EdgeSet(H1));
	    Include(~EPA, edge);
	    assert IsLabelled(edge);
	elif Type(H1) eq GrphDir then
	    AddEdge(~H1, e[1], e[2], L[i]);
	    assert IsLabelled(EdgeSet(H1)!e);
	elif Type(H1) eq GrphMultDir then
	    H1, edge := AddEdge(H1, e[1], e[2], L[i]);
	    ChangeUniverse(~EPA, EdgeSet(H1));
	    Include(~EPA, edge);
	    assert IsLabelled(edge);
	else
	    H1, edge := AddEdge(H1,
	    e[1][1], e[1][2], e[2], L[i]);
	    ChangeUniverse(~EPA, EdgeSet(H1));
	    Include(~EPA, edge);
	    assert IsLabelled(edge);
	end if;
    end for;
    assert IsSubgraph(H1, GG);
    EPAC := EPA;
    for i in [1..#EP] do
	e := EPL[i];
	if Type(H1) eq GrphUnd then
	    RemoveEdge(~H1,
	    SetToSequence(e)[1], SetToSequence(e)[2]);
	elif Type(H1) eq GrphDir then
	    RemoveEdge(~H1, e[1], e[2]);
	else
	    edge := Random(EPAC);
	    Exclude(~EPAC, edge);
	    RemoveEdge(~H1, edge);
	end if;
    end for;
    assert H1 eq GG;
    AddEdges(~H1, EPL, L);
    assert IsSubgraph(H1, GG);
    for e in EdgeSet(H1) do
	if IsLabelled(e) then
	    RemoveEdge(~H1, e);
	end if;
    end for;
    assert H1 eq GG;

    /// edge labels -- more random (!) for multigraphs specifically
    if Type(GG) eq GrphMultUnd or Type(GG) eq GrphMultDir
	or Type(GG) eq GrphNet then
	EP := [];
	for i in [1..20] do
	    u, v := get_2_rand_int(Order(GG));
	    u := VertexSet(H1)!u;
	    v := VertexSet(H1)!v;
	    if Type(GG) eq GrphMultUnd then
		Append(~EP, {u,v});
	    elif Type(GG) eq GrphMultDir then
		Append(~EP, [u,v]);
	    else
		Append(~EP, <[u,v], Random(1, m)>);
	    end if;
	end for;
	L := [];
	for i in [1..#EP] do
	    Append(~L, IntegerToString(i));
	end for;
	AddEdges(~H1, EP, L);
	assert IsSubgraph(H1, GG);
	for e in EdgeSet(H1) do
	    if IsLabelled(e) then
		RemoveEdge(~H1, e);
	    end if;
	end for;
	assert H1 eq GG;

        if Type(GG) eq GrphMultUnd or Type(GG) eq GrphMultDir
            or Type(GG) eq GrphNet then
            for i in [1..20] do
                u := Random(1, Order(GG));
                v := Random(1, Order(GG));
                u := VertexSet(H1)!u; 
                v := VertexSet(H1)!v; 
                if Type(GG) eq GrphMultUnd or Type(GG) eq GrphMultDir
                    then
                    AddEdge(~H1, u, v, IntegerToString(i));
                elif u eq v then
                    AddEdge(~H1, u, v, 0, IntegerToString(i));
                else
                    AddEdge(~H1, u, v, Random(1, m), IntegerToString(i));
                end if;
            end for;
            assert IsSubgraph(H1, GG);
            for e in EdgeSet(H1) do
                if IsLabelled(e) then
                    RemoveEdge(~H1, e);
                end if;
            end for;
            
            assert H1 eq GG;
        end if;
    end if;
    
end procedure;



procedure test_sup_caps(G)

    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];

    n := Order(G);

    // support
    S := {@ @};
    while #S lt n do
        Include(~S, &cat [ Random(A) : i in [1..3] ]);
    end while;
    assert #S eq n;
    
    GG := get_graph(S, G);
    VS := { Random(VertexSet(GG)) : i in [1..n div 2] };
    ES := { Random(EdgeSet(GG)) : i in [1..n div 2] };

    // edge caps
    E := EdgeSet(GG);
    size := Size(GG);
    if not IsSimple(GG) and not IsDirected(GG) then
        size := 2 * Size(GG);
    end if;
    for e in [1..size] do 
        p := Random(1, 2);
	if p eq 1 then
	    if InitialVertex(E.e) eq TerminalVertex(E.e)
		then AssignCapacity(~GG, E.e, 0);
	    else
		c := Random(1, n);
		AssignCapacity(~GG, E.e, c);
	    end if;
        end if;
    end for;
    //EdgeCaps(GG);
    ChangeUniverse(~VS, VertexSet(GG));
    H := sub< GG | VS >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);
    assert not IsSubgraph(GG, underlying(HH));
    
    ChangeUniverse(~ES, EdgeSet(GG));
    H := sub< GG | ES >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);
    assert not IsSubgraph(GG, underlying(HH));

end procedure;

procedure test_sup_caps_add_remove(G)
    
    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];

    n := Order(G);

    // support
    S := {@ @};
    while #S lt n do
        Include(~S, &cat [ Random(A) : i in [1..3] ]);
    end while;
    assert #S eq n;

    GG := get_graph(S, G);

    /////////////// edge caps
    E := EdgeSet(GG);
    size := Size(GG);
    if not IsSimple(GG) and not IsDirected(GG) then
        size := 2 * Size(GG);
    end if;
    for e in [1..size] do 
        p := Random(1, 2);
	if p eq 1 then
	    if InitialVertex(E.e) eq TerminalVertex(E.e)
		then
		AssignCapacity(~GG, E.e, 0);
	    else
		c := Random(1, n);
		AssignCapacity(~GG, E.e, c);
	    end if;
        end if;
    end for;

    H := GG;
    for i in [1..n div 2] do
        ////GetSeed();
        H -:= Random(VertexSet(H));
        assert IsSubgraph(GG, H);
        assert IsSubgraph(underlying(GG), underlying(H));
        assert IsSubgraph(StandardGraph(GG),
        StandardGraph(H));
    end for;

    HH := H;
    for i in [1..n div 2] do
        HH +:= 1;
        assert not IsSubgraph(HH, H);
        assert IsSubgraph(underlying(HH), underlying(H));
        assert IsSubgraph(StandardGraph(HH),
        StandardGraph(H));
        assert not IsSubgraph(HH, H);
    end for;

    HH := H;
    for i in [1..n div 2] do
        AddVertex(~HH, Random(1, Order(GG)));
        assert not IsSubgraph(HH, H);
        assert IsSubgraph(underlying(HH), underlying(H));
        assert IsSubgraph(StandardGraph(HH),
        StandardGraph(H));
        assert not IsSubgraph(HH, H);
    end for;

    H := GG;
    for i in [1..n div 2] do
        H -:= { Random(EdgeSet(H)) };
        assert IsSubgraph(GG, H);
        assert IsSubgraph(underlying(GG), underlying(H));
        assert IsSubgraph(StandardGraph(GG),
        StandardGraph(H));
        assert IsSubgraph(UnlabelledGraph(GG),
        UnlabelledGraph(H));
    end for;

    H := GG;
    for i in [1..n div 2] do
        a, b := get_2_rand_int(n);
        c := Random(1, n);
        if not VertexSet(H)!a adj VertexSet(H)!b then
	    if not Type(GG) eq GrphNet then
		AddEdge(~H,
		VertexSet(H)!a, VertexSet(H)!b);
            else
                AddEdge(~H,
                VertexSet(H)!a, VertexSet(H)!b, c);
            end if;
        end if;
        assert IsSubgraph(H, GG);
        assert IsSubgraph(underlying(H), underlying(GG));
        assert IsSubgraph(StandardGraph(H),
        StandardGraph(GG));
        assert IsSubgraph(UnlabelledGraph(H),
        UnlabelledGraph(GG));
    end for;

    H := GG;
    for i in [1..n div 2] do
        a, b := get_2_rand_int(n);
        c := Random(1, n);
        if not VertexSet(H)!a adj VertexSet(H)!b then
	    if not Type(GG) eq GrphNet then
		H, edge := AddEdge(H,
		VertexSet(H)!a, VertexSet(H)!b);
		AssignCapacity(~H, edge, c);
	    else
		H, edge := AddEdge(H,
		VertexSet(H)!a, VertexSet(H)!b, c);
		AssignCapacity(~H, edge, Random(1, n));
            end if;
        end if;
        assert IsSubgraph(H, GG);
        assert IsSubgraph(underlying(H), underlying(GG));
        assert IsSubgraph(StandardGraph(H),
        StandardGraph(GG));
        assert IsSubgraph(UnlabelledGraph(H),
        UnlabelledGraph(GG));
    end for;

end procedure;


procedure test_sup_caps_eq(G)
    
    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];
    
    n := Order(G);
    m := n div 5;
    
    // support
    S := {@ @};
    while #S lt n do
        Include(~S, &cat [ Random(A) : i in [1..3] ]);
    end while;
    assert #S eq n;

    GG := get_graph(S, G);

    //edges & caps
    EP := {};
    for u in VertexSet(GG) do
        for v in VertexSet(GG) do
            if not u eq v and not u adj v then
                if Type(GG) eq GrphUnd 
                    or Type(GG) eq GrphMultUnd then
                    if not {v,u} in EP then
                        Include(~EP, {u,v});
                    end if;
                elif Type(GG) eq GrphDir
                    or Type(GG) eq GrphMultDir then
                    if not [u, v] in EP then
                        Include(~EP, [u,v]);
                    end if;
                else
                    Include(~EP, <[u,v], Random(1, m)>);
                end if;
            end if;
        end for;
    end for;
    H1 := GG;
    
    C := [];
    for i in [1..#EP] do
	c := Random(1, n);
        Append(~C, c);
    end for;
    EPL := SetToSequence(EP);

    EPA := {};
    for i in [1..#EP] do
        e := EPL[i];
        if Type(H1) eq GrphUnd then
            H1, edge := AddEdge(H1,
	    SetToSequence(e)[1], SetToSequence(e)[2]);
	    AssignCapacity(~H1, edge, C[i]);
            ChangeUniverse(~EPA, EdgeSet(H1));
            Include(~EPA, edge);
            assert IsCapacitated(EdgeSet(H1));
        elif Type(H1) eq GrphMultUnd then
            H1, edge := AddEdge(H1,
	    SetToSequence(e)[1], SetToSequence(e)[2]);
	    AssignCapacity(~H1, edge, C[i]);
            ChangeUniverse(~EPA, EdgeSet(H1));
            Include(~EPA, edge);
            assert IsCapacitated(EdgeSet(H1));
        elif Type(H1) eq GrphDir then
	    AddEdge(~H1, e[1], e[2]);
	    AssignCapacity(~H1, EdgeSet(H1)!e, C[i]);
            assert IsCapacitated(EdgeSet(H1));
        elif Type(H1) eq GrphMultDir then
	    H1, edge := AddEdge(H1, e[1], e[2]);
	    AssignCapacity(~H1, edge, C[i]);
            ChangeUniverse(~EPA, EdgeSet(H1));
            Include(~EPA, edge);
            assert IsCapacitated(EdgeSet(H1));
        else
            H1, edge := AddEdge(H1,
	    e[1][1], e[1][2], e[2]);
	    AssignCapacity(~H1, edge, C[i]);
            ChangeUniverse(~EPA, EdgeSet(H1));
            Include(~EPA, edge);
            assert IsCapacitated(EdgeSet(H1));
        end if;
    end for;
    assert IsSubgraph(H1, GG);
    EPAC := EPA;
    for i in [1..#EP] do
        e := EPL[i];
        if Type(H1) eq GrphUnd then
            RemoveEdge(~H1,
            SetToSequence(e)[1], SetToSequence(e)[2]);
        elif Type(H1) eq GrphDir then
            RemoveEdge(~H1, e[1], e[2]);
        else
            edge := Random(EPAC);
            Exclude(~EPAC, edge);
            RemoveEdge(~H1, edge);
        end if;
    end for;
    assert H1 eq GG;
    AddEdges(~H1, SequenceToSet(EPL));
    assert IsSubgraph(H1, GG);

    /// edge caps -- more random (!) for multigraphs specifically
    if Type(GG) eq GrphMultUnd or Type(GG) eq GrphMultDir
	then
        EP := [];
        for i in [1..20] do
            u, v := get_2_rand_int(Order(GG));
            u := VertexSet(H1)!u;
            v := VertexSet(H1)!v;
            if Type(GG) eq GrphMultUnd then
                Append(~EP, {u,v});
            elif Type(GG) eq GrphMultDir then
                Append(~EP, [u,v]);
            end if;
        end for;
        C := [];
	for i in [1..#EP] do
	    c := Random(1, n);
            Append(~C, c);
	end for;
        AddEdges(~H1, SequenceToSet(EP));
        assert IsSubgraph(H1, GG);

	if Type(GG) eq GrphMultUnd
	    or Type(GG) eq GrphMultDir then
            for i in [1..20] do
                u := Random(1, Order(GG));
                v := Random(1, Order(GG));
                u := VertexSet(H1)!u; 
		v := VertexSet(H1)!v;
		c := Random(1, n);
		H1, edge := AddEdge(H1, u, v);
		if u eq v then
		    AssignCapacity(~H1, edge, 0);
		else
		    AssignCapacity(~H1, edge, c);
                end if;
            end for;
            assert IsSubgraph(H1, GG);
	    for e in EdgeSet(H1) do
		c := Capacity(e);
		if c gt 0 then
                    RemoveEdge(~H1, e);
                end if;
            end for;
            
            assert IsSubgraph(H1, GG);
        end if;
    end if;
    
end procedure;



procedure test_sup_weights(G)

    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];

    n := Order(G);

    // support
    S := {@ @};
    while #S lt n do
        Include(~S, &cat [ Random(A) : i in [1..3] ]);
    end while;
    assert #S eq n;
    
    GG := get_graph(S, G);
    VS := { Random(VertexSet(GG)) : i in [1..n div 2] };
    ES := { Random(EdgeSet(GG)) : i in [1..n div 2] };

    // edge weights
    E := EdgeSet(GG);
    size := Size(GG);
    if not IsSimple(GG) and not IsDirected(GG) then
        size := 2 * Size(GG);
    end if;
    for e in [1..size] do 
        p := Random(1, 2);
	if p eq 1 then
	    a := Random(1, n);
	    b := Random(1, n);
            AssignWeight(~GG, E.e, a/b);
        end if;
    end for;
    //EdgeWeights(GG);
    ChangeUniverse(~VS, VertexSet(GG));
    H := sub< GG | VS >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);
    assert not IsSubgraph(GG, underlying(HH));
    
    ChangeUniverse(~ES, EdgeSet(GG));
    H := sub< GG | ES >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);
    assert not IsSubgraph(GG, underlying(HH));

end procedure;

procedure test_sup_weights_add_remove(G)
    
    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];

    n := Order(G);

    // support
    S := {@ @};
    while #S lt n do
        Include(~S, &cat [ Random(A) : i in [1..3] ]);
    end while;
    assert #S eq n;

    GG := get_graph(S, G);

    /////////////// edge weights
    E := EdgeSet(GG);
    size := Size(GG);
    if not IsSimple(GG) and not IsDirected(GG) then
        size := 2 * Size(GG);
    end if;
    for e in [1..size] do 
        p := Random(1, 2);
	if p eq 1 then
	    a := Random(1, n);
	    b := Random(1, n);
            AssignWeight(~GG, E.e, a/b);
        end if;
    end for;

    H := GG;
    for i in [1..n div 2] do
        ////GetSeed();
        H -:= Random(VertexSet(H));
        assert IsSubgraph(GG, H);
        assert IsSubgraph(underlying(GG), underlying(H));
        assert IsSubgraph(StandardGraph(GG),
        StandardGraph(H));
    end for;

    HH := H;
    for i in [1..n div 2] do
        HH +:= 1;
        assert not IsSubgraph(HH, H);
        assert IsSubgraph(underlying(HH), underlying(H));
        assert IsSubgraph(StandardGraph(HH),
        StandardGraph(H));
        assert not IsSubgraph(HH, H);
    end for;

    HH := H;
    for i in [1..n div 2] do
        AddVertex(~HH, Random(1, Order(GG)));
        assert not IsSubgraph(HH, H);
        assert IsSubgraph(underlying(HH), underlying(H));
        assert IsSubgraph(StandardGraph(HH),
        StandardGraph(H));
        assert not IsSubgraph(HH, H);
    end for;

    H := GG;
    for i in [1..n div 2] do
        H -:= { Random(EdgeSet(H)) };
        assert IsSubgraph(GG, H);
        assert IsSubgraph(underlying(GG), underlying(H));
        assert IsSubgraph(StandardGraph(GG),
        StandardGraph(H));
        assert IsSubgraph(UnlabelledGraph(GG),
        UnlabelledGraph(H));
    end for;

    H := GG;
    for i in [1..n div 2] do
        a, b := get_2_rand_int(n);
        c := Random(1, n);
        if not VertexSet(H)!a adj VertexSet(H)!b then
	    if not Type(GG) eq GrphNet then
		AddEdge(~H,
		VertexSet(H)!a, VertexSet(H)!b);
            else
                AddEdge(~H,
                VertexSet(H)!a, VertexSet(H)!b, c);
            end if;
        end if;
        assert IsSubgraph(H, GG);
        assert IsSubgraph(underlying(H), underlying(GG));
        assert IsSubgraph(StandardGraph(H),
        StandardGraph(GG));
        assert IsSubgraph(UnlabelledGraph(H),
        UnlabelledGraph(GG));
    end for;

    H := GG;
    for i in [1..n div 2] do
        a, b := get_2_rand_int(n);
        c := Random(1, n);
        if not VertexSet(H)!a adj VertexSet(H)!b then
	    if not Type(GG) eq GrphNet then
		H, edge := AddEdge(H,
		VertexSet(H)!a, VertexSet(H)!b);
		AssignWeight(~H, edge, a/b);
	    else
		H, edge := AddEdge(H,
		VertexSet(H)!a, VertexSet(H)!b, c);
		AssignWeight(~H, edge, a/b);
            end if;
        end if;
        assert IsSubgraph(H, GG);
        assert IsSubgraph(underlying(H), underlying(GG));
        assert IsSubgraph(StandardGraph(H),
        StandardGraph(GG));
        assert IsSubgraph(UnlabelledGraph(H),
        UnlabelledGraph(GG));
    end for;

end procedure;


procedure test_sup_weights_eq(G)
    
    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];
    
    n := Order(G);
    m := n div 5;
    
    // support
    S := {@ @};
    while #S lt n do
        Include(~S, &cat [ Random(A) : i in [1..3] ]);
    end while;
    assert #S eq n;

    GG := get_graph(S, G);

    //edges & weights
    EP := {};
    for u in VertexSet(GG) do
        for v in VertexSet(GG) do
            if not u eq v and not u adj v then
                if Type(GG) eq GrphUnd 
                    or Type(GG) eq GrphMultUnd then
                    if not {v,u} in EP then
                        Include(~EP, {u,v});
                    end if;
                elif Type(GG) eq GrphDir
                    or Type(GG) eq GrphMultDir then
                    if not [u, v] in EP then
                        Include(~EP, [u,v]);
                    end if;
                else
                    Include(~EP, <[u,v], Random(1, m)>);
                end if;
            end if;
        end for;
    end for;
    H1 := GG;
    
    W := [];
    for i in [1..#EP] do
	a := Random(1, n);
	b := Random(1, n);
        Append(~W, a/b);
    end for;
    EPL := SetToSequence(EP);

    EPA := {};
    for i in [1..#EP] do
        e := EPL[i];
        if Type(H1) eq GrphUnd then
            H1, edge := AddEdge(H1,
	    SetToSequence(e)[1], SetToSequence(e)[2]);
	    AssignWeight(~H1, edge, W[i]);
            ChangeUniverse(~EPA, EdgeSet(H1));
            Include(~EPA, edge);
            assert IsWeighted(EdgeSet(H1));
        elif Type(H1) eq GrphMultUnd then
            H1, edge := AddEdge(H1,
	    SetToSequence(e)[1], SetToSequence(e)[2]);
	    AssignWeight(~H1, edge, W[i]);
            ChangeUniverse(~EPA, EdgeSet(H1));
            Include(~EPA, edge);
            assert IsWeighted(EdgeSet(H1));
        elif Type(H1) eq GrphDir then
	    AddEdge(~H1, e[1], e[2]);
	    AssignWeight(~H1, EdgeSet(H1)!e, W[i]);
            assert IsWeighted(EdgeSet(H1));
        elif Type(H1) eq GrphMultDir then
	    H1, edge := AddEdge(H1, e[1], e[2]);
	    AssignWeight(~H1, edge, W[i]);
            ChangeUniverse(~EPA, EdgeSet(H1));
            Include(~EPA, edge);
            assert IsWeighted(EdgeSet(H1));
        else
            H1, edge := AddEdge(H1,
	    e[1][1], e[1][2], e[2]);
	    AssignWeight(~H1, edge, W[i]);
            ChangeUniverse(~EPA, EdgeSet(H1));
            Include(~EPA, edge);
            assert IsWeighted(EdgeSet(H1));
        end if;
    end for;
    assert IsSubgraph(H1, GG);
    EPAC := EPA;
    for i in [1..#EP] do
        e := EPL[i];
        if Type(H1) eq GrphUnd then
            RemoveEdge(~H1,
            SetToSequence(e)[1], SetToSequence(e)[2]);
        elif Type(H1) eq GrphDir then
            RemoveEdge(~H1, e[1], e[2]);
        else
            edge := Random(EPAC);
            Exclude(~EPAC, edge);
            RemoveEdge(~H1, edge);
        end if;
    end for;
    assert H1 eq GG;
    AddEdges(~H1, SequenceToSet(EPL));
    assert IsSubgraph(H1, GG);

    /// edge weights -- more random (!) for multigraphs specifically
    if Type(GG) eq GrphMultUnd or Type(GG) eq GrphMultDir
        or Type(GG) eq GrphNet then
        EP := [];
        for i in [1..20] do
            u, v := get_2_rand_int(Order(GG));
            u := VertexSet(H1)!u;
            v := VertexSet(H1)!v;
            if Type(GG) eq GrphMultUnd then
                Append(~EP, {u,v});
            elif Type(GG) eq GrphMultDir then
                Append(~EP, [u,v]);
            else
                Append(~EP, <[u,v], Random(1, m)>);
            end if;
        end for;
        W := [];
	for i in [1..#EP] do
	    a := Random(1, n);
	    b := Random(1, n);
            Append(~W, a/b);
	end for;
        AddEdges(~H1, SequenceToSet(EP));
        assert IsSubgraph(H1, GG);

	if Type(GG) eq GrphMultUnd
	    or Type(GG) eq GrphMultDir
            or Type(GG) eq GrphNet then
            for i in [1..20] do
                u := Random(1, Order(GG));
                v := Random(1, Order(GG));
                u := VertexSet(H1)!u; 
		v := VertexSet(H1)!v;
		a := Random(1, n);
		b := Random(1, n);
		if Type(GG) eq GrphMultUnd
		    or Type(GG) eq GrphMultDir
		    then
		    H1, edge := AddEdge(H1, u, v);
		    AssignWeight(~H1, edge, a/b);
		elif u eq v then
		    H1, edge := AddEdge(H1, u, v, 0);
		    AssignWeight(~H1, edge, a/b);
		else
		    H1, edge := AddEdge(H1, u, v,
		    Random(1, m));
		    AssignWeight(~H1, edge, a/b);
                end if;
            end for;
            assert IsSubgraph(H1, GG);
	    for e in EdgeSet(H1) do
		w := Weight(e);
		if not w eq 0 then
                    RemoveEdge(~H1, e);
                end if;
            end for;
            
            assert IsSubgraph(H1, GG);
        end if;
    end if;
    
end procedure;






function get_support(n)

    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];

    S := {@ @};
    while #S lt n do
        Include(~S, &cat [ Random(A) : i in [1..3] ]);
    end while;
    assert #S eq n;

    return S;
end function;

function put_support(G)

    S := get_support(Order(G));
    return get_graph(S, G);
    
end function;

function put_labels(G)

    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];
    
    E := EdgeSet(G);
    size := Size(G);
    if not IsSimple(G) and not IsDirected(G) then
        size := 2 * Size(G);
    end if;
    for e in [1..size] do 
        p := Random(1, 2);
        if p eq 1 then
            AssignLabel(~G, E.e, Random(A));
        end if;
    end for;

    return G;
end function;

function put_all_labels(G)

    A := [ "a", "b", "c", "d", "e", "f", "g", "h", "i",
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
    "u", "v", "w", "x", "y", "z" ];
    
    E := EdgeSet(G);
    size := Size(G);
    if not IsSimple(G) and not IsDirected(G) then
        size := 2 * Size(G);
    end if;
    for e in [1..size] do 
        AssignLabel(~G, E.e, Random(A));
    end for;

    return G;
end function;


function put_weights(G)

    n := Order(G);
    
    E := EdgeSet(G);
    size := Size(G);
    if not IsSimple(G) and not IsDirected(G) then
        size := 2 * Size(G);
    end if;
    for e in [1..size] do 
        p := Random(1, 2);
        if p eq 1 then
            a := Random(1, n);
            b := Random(1, n);
            AssignWeight(~G, E.e, a/b);
        end if;
    end for;

    return G;
end function;

function put_all_weights(G)

    n := Order(G);
    
    E := EdgeSet(G);
    size := Size(G);
    if not IsSimple(G) and not IsDirected(G) then
        size := 2 * Size(G);
    end if;
    for e in [1..size] do 
        a := Random(1, n);
        b := Random(1, n);
        AssignWeight(~G, E.e, a/b);
    end for;

    return G;
end function;


function put_caps(G)

    n := Order(G);
    
    E := EdgeSet(G);
    size := Size(G);
    if not IsSimple(G) and not IsDirected(G) then
        size := 2 * Size(G);
    end if;
    for e in [1..size] do 
        p := Random(1, 2);
        if p eq 1 then
            if not InitialVertex(E.e)
                eq TerminalVertex(E.e) then
                c := Random(1, n);
                AssignCapacity(~G, E.e, c);
            end if;
        end if;
    end for;

    return G;
end function;

function put_all_caps(G)

    n := Order(G);
    
    E := EdgeSet(G);
    size := Size(G);
    if not IsSimple(G) and not IsDirected(G) then
        size := 2 * Size(G);
    end if;
    for e in [1..size] do 
        if not InitialVertex(E.e)
            eq TerminalVertex(E.e) then
            c := Random(1, n);
            AssignCapacity(~G, E.e, c);
        end if;
    end for;

    return G;
end function;


procedure check_un_decs(G)

    GG := put_support(G);
    GG := put_all_labels(GG);  //EdgeLabels(GG);
    GG := put_all_weights(GG); //EdgeWeights(GG);
    GG := put_all_caps(GG);    //EdgeCapacities(GG);

    assert not IsEdgeLabelled(UnlabelledGraph(GG))
    and IsEdgeCapacitated(UnlabelledGraph(GG))
    and IsEdgeWeighted(UnlabelledGraph(GG))
    and not StandardGraph(UnlabelledGraph(GG))
    eq UnlabelledGraph(GG);

    if not Type(G) eq GrphNet then
        assert IsEdgeLabelled(UncapacitatedGraph(GG))
        and not IsEdgeCapacitated(UncapacitatedGraph(GG))
        and IsEdgeWeighted(UncapacitatedGraph(GG))
        and not StandardGraph(UncapacitatedGraph(GG))
        eq UncapacitatedGraph(GG);
    else
        assert IsEdgeLabelled(UncapacitatedGraph(GG))
        and IsEdgeCapacitated(UncapacitatedGraph(GG))
        and IsEdgeWeighted(UncapacitatedGraph(GG))
        and not StandardGraph(UncapacitatedGraph(GG))
        eq UncapacitatedGraph(GG);
    end if;
    
    assert IsEdgeLabelled(UnweightedGraph(GG))
    and IsEdgeCapacitated(UnweightedGraph(GG))
    and not IsEdgeWeighted(UnweightedGraph(GG))
    and not StandardGraph(UnweightedGraph(GG))
    eq UnweightedGraph(GG);

    H := GG;
    DeleteEdgeLabels(~H);
    assert not IsEdgeLabelled(H)
    and IsEdgeCapacitated(H)
    and IsEdgeWeighted(H)
    and not StandardGraph(H) eq H;

    H := GG;
    DeleteCapacities(~H);
    if not Type(G) eq GrphNet then
        assert IsEdgeLabelled(H)
        and not IsEdgeCapacitated(H)
        and IsEdgeWeighted(H)
        and not StandardGraph(H) eq H;
    else
        assert IsEdgeLabelled(H)
        and IsEdgeCapacitated(H)
        and IsEdgeWeighted(H)
        and not StandardGraph(H) eq H;
    end if;
    
    assert IsEdgeLabelled(GG)
    and IsEdgeCapacitated(GG)
    and IsEdgeWeighted(GG)
    and not StandardGraph(GG) eq GG;
    
    H := GG;
    DeleteWeights(~H);
    assert IsEdgeLabelled(H)
    and IsEdgeCapacitated(H)
    and not IsEdgeWeighted(H)
    and not StandardGraph(H) eq H;

    assert IsEdgeLabelled(GG)
    and IsEdgeCapacitated(GG)
    and IsEdgeWeighted(GG)
    and not StandardGraph(GG) eq GG;
    
end procedure;

procedure check_decs(G)

    GG := put_support(G);
    GG := put_labels(GG);  //EdgeLabels(GG);
    GG := put_weights(GG); //EdgeWeights(GG);
    GG := put_caps(GG);    //EdgeCapacities(GG);

    n := Order(G);
    VS := { Random(VertexSet(GG)) : i in [1..n div 2] };
    ES := { Random(EdgeSet(GG)) : i in [1..n div 2] };

    H := sub< GG | VS >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);
    H := sub< GG | ES >;
    assert IsSubgraph(GG, H);
    HH := H;
    assert IsSubgraph(GG, HH);

    m := n div 5;

    H1 := GG;
    H1 := H1 + m;
    assert IsSubgraph(H1, StandardGraph(GG));

    for v in [1..m] do
        H1 := H1 - VertexSet(H1)!(n+1);
    end for;
    assert H1 eq StandardGraph(GG);
    assert IsSubgraph(H1, StandardGraph(GG));

    EP := {};
    for u in VertexSet(GG) do
        for v in VertexSet(GG) do
            if not u eq v and not u adj v then
                if Type(GG) eq GrphUnd 
                    or Type(GG) eq GrphMultUnd then
                    if not {v,u} in EP then
                        Include(~EP, {u,v});
                    end if;
                elif Type(GG) eq GrphDir
                    or Type(GG) eq GrphMultDir then
                    if not [u, v] in EP then
                        Include(~EP, [u,v]);
                    end if;
		end if;
            end if;
        end for;
    end for;
    H1 := GG;

    EPA := {};
    for e in EP do
	if Type(H1) eq GrphUnd or Type(H1) eq GrphMultUnd
	    then
	    H1, edge := AddEdge(H1,
	    SetToSequence(e)[1], SetToSequence(e)[2]);
	else
	    H1, edge := AddEdge(H1, e[1], e[2]);
	end if;
	ChangeUniverse(~EPA, EdgeSet(H1));
	Include(~EPA, edge);
    end for;
    assert IsSubgraph(H1, GG);

    for e in EPA do
	RemoveEdge(~H1, e);
    end for;
    assert H1 eq GG;
    
end procedure;

procedure check_edges(GG, H)

    if Type(GG) eq GrphUnd
	or Type(GG) eq GrphDir then
	for e in EdgeSet(H) do
	    if IsLabelled(e) then
		assert Label(e) eq Label(EdgeSet(GG)!e);
	    else
		assert not IsLabelled(EdgeSet(GG)!e);
	    end if;
	    if IsWeighted(EdgeSet(H)) then
		assert Weight(e) eq Weight(EdgeSet(GG)!e);
	    else
		assert not IsWeighted(EdgeSet(GG));
	    end if;
	    if IsCapacitated(EdgeSet(H)) then
		assert Capacity(e)
		eq Capacity(EdgeSet(GG)!e);
	    else
		assert not IsCapacitated(EdgeSet(GG));
	    end if;
	end for;
    else
	for u in VertexSet(H) do
	    for v in VertexSet(H) do
		EH := Edges(u, v); 
		EGG := Edges(VertexSet(GG)!u,
		VertexSet(GG)!v);
		assert #EH eq #EGG;
		LH := {}; LGG := {};
		WH := 0; WGG := 0;
		CH := 0; CGG := 0;
		for e in EH do
		    if IsLabelled(e) then
			Include(~LH, Label(e));
		    end if;
		    if IsWeighted(EdgeSet(H)) then
			WH +:= Weight(e);
		    end if;
		    if IsCapacitated(EdgeSet(H)) then
			CH +:= Capacity(e);
		    end if;
		end for;
		for e in EGG do
		    if IsLabelled(e) then
			Include(~LGG, Label(e));
		    end if;
		    if IsWeighted(EdgeSet(GG)) then
			WGG +:= Weight(e);
		    end if;
		    if IsCapacitated(EdgeSet(GG)) then
			CGG +:= Capacity(e);
		    end if;
		end for;
		assert LH eq LGG and WH eq WGG
		and CH eq CGG;
	    end for;
	end for;
    end if;

end procedure;

procedure check_decs_eq(G)

    GG := put_support(G);
    GG := put_labels(GG);  //EdgeLabels(GG);
    GG := put_weights(GG); //EdgeWeights(GG);
    GG := put_caps(GG);    //EdgeCapacities(GG);

    VS := { v : v in VertexSet(GG) };
    ES := { e : e in EdgeSet(GG) };

    H := sub< GG | VS >;
    assert IsSubgraph(GG, H);
    assert H eq GG;
    HH := H;
    assert IsSubgraph(GG, HH);
    assert HH eq GG;
    check_edges(H, GG);
    
    H := sub< GG | ES >;
    assert IsSubgraph(GG, H);
    assert H eq GG;
    HH := H;
    assert IsSubgraph(GG, HH);
    assert HH eq GG;
    check_edges(H, GG);
    
end procedure;


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
// /home/paule/graph/test/hb_graph_testfile

////SetHistorySize(0);
////SetPreviousSize(0);
////SetDelCheck(true);
////SetTrace(62252,true);
////SetMark(true);


/// do
/// export MAGMA_NAUTY=/home/paule/graph/bdm_pgr/nauty
/// before starting this session

//////////////////   Graph.text

//print "Example: H1E1";

P := Graph< 10 | { 1, 2 }, { 1, 5 }, { 1, 6 }, { 2, 3 }, { 2, 7 },
           { 3, 4 }, { 3, 8 }, { 4, 5 }, { 4, 9 }, { 5, 10 },
           { 6, 8 }, { 6, 9 }, { 7, 9 }, { 7, 10 }, { 8, 10 } >;
P := Graph< 10 | [ { 2, 5, 6 }, { 1, 3, 7 }, { 2, 4, 8 }, { 3, 5, 9 },
              { 1, 4, 10 }, { 1, 8, 9 }, { 2, 9, 10 }, { 3, 6, 10 },
              { 4, 6, 7 }, { 5, 7, 8 } ] >;
M := MatrixRing( Integers(), 10 );
P := Graph< 10 | M![ 0,1,0,0,1,1,0,0,0,0,
                  1,0,1,0,0,0,1,0,0,0,
                  0,1,0,1,0,0,0,1,0,0,
                  0,0,1,0,1,0,0,0,1,0,
                  1,0,0,1,0,0,0,0,0,1,
                  1,0,0,0,0,0,0,1,1,0,
                  0,1,0,0,0,0,0,0,1,1,
                  0,0,1,0,0,1,0,0,0,1,
                  0,0,0,1,0,1,1,0,0,0,
                  0,0,0,0,1,0,1,1,0,0] >;
P;


////clear;
////ShowActive();
////ShowActive();
 
//print "Example: H1E2";

G := PermutationGroup< 30 |
    (1, 2)(3, 4)(5, 7)(6, 8)(9, 13)(10, 12)(11, 15)(14, 19) (16, 23)
        (17, 22)(18, 21)(20, 27)(24, 29)(25, 28)(26, 30),
    (1, 24, 28, 8)(2, 9, 17, 22)(3, 29, 19, 15)(4, 5, 21, 25)
        (6, 18, 7, 16)(10, 13, 30, 11)(12, 14)(20, 23)(26, 27) >;
N1 := rep{ o : o in Orbits(Stabilizer(G, 1)) | #o eq 3 };
tutte := Graph< 30 | <1, N1>^G >;

////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E3";

D1 := Digraph< 5 | [1, 2], [1, 3], [1, 4],
                  [3, 2], [4, 3] >;
D1;
M := MatrixRing(Integers(), 5);
D2 := Digraph< 5 | 
          M![ 0,1,1,1,0, 
              0,0,0,0,0, 
              0,1,0,0,0, 
              0,0,1,0,0,
              0,0,0,0,0 ] >; 
IsIsomorphic(D1, D2);


////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E4";

V := Subsets({1..5}, 2);                                   
O3 := Graph< V | { {u,v} : u,v in V | IsDisjoint(u, v) } >;
O3;
Support(O3);
SO3 := StandardGraph(O3);                                  
SO3;
Support(SO3);            

////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E5";

kd5 := CompleteDigraph(5);
kd5;
rd5 := RandomDigraph( 5, 0.75);
rd5;


////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E6";

S := Subsets({1..5}, 2);                                   
O3, V, E := Graph< S | { {u,v} : u,v in S | IsDisjoint(u, v) } >;
VertexSet(O3);
Vertices(O3); 
EdgeSet(O3);
Edges(O3);  
u := V!{1, 2};
u, Type(u);
Index(u);
x := E!{ {1,2}, {3,4}};
x, Type(x);



////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E7";

K34, V, E := BipartiteGraph(3, 4);
L := [ IsEven(Distance(V!1, v)) select "red" else "blue" : 
                                       v in Vertices(K34) ];
AssignLabels(~K34, Vertices(K34), L);
VertexLabels(K34);                                          


////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E8";

G<a,b> := FPGroup(Sym(4));
I,m := Transversal(G, sub<G | 1>);
S := Setseq(Generators(G));
N := [{m(a*b) : b in S} : a in I];      
graph := StandardGraph(Digraph<I | N>);
AssignLabels(VertexSet(graph), IndexedSetToSequence(I));
V := VertexSet(graph);
E := EdgeSet(graph);
for i in [1..#I] do
    AssignLabels([E![V | i, Index(I, m(I[i]*s))] : s in S],
    S);
end for;
&*EdgeLabels(graph, [[1,2],[2,5],[5,4],[4,1]]);
G;

////clear;
////ShowActive();
////ShowActive();


//print "Example: H1E9";

K6, V, E := CompleteGraph(6);
K6;
F1 := { E | {1,2}, {3, 4}, {5, 6} };
G1, V1, E1 := K6 - F1;
G1;



////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E10";

K9, V, E := CompleteGraph(9);
P := { { V | 1, 2, 3}, { V | 4, 5, 6}, { V | 7, 8, 9} };
Q := quo< K9 | P >;
Q;



////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E11";

G := CompleteGraph(5);
E := EdgeSet(G);
H := InsertVertex({ E | { 1, 3 }, { 1, 4 }, { 2, 4 }, { 2, 5 }, { 3, 5 } } );
L := Union(H, CompleteGraph(1));
V := VertexSet(L);
L := L + {  { V.11, V.6 }, { V.11, V.7 }, { V.11, V.8 }, { V.11, V.9 },
           { V.11, V.10 } };
L;

////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E12";

G:=Graph< 5 | [{2,5}, {1,3,5}, {2,4,5}, {3,5}, {1,2,3,4} ]>;
ChromaticNumber(G);
OptimalVertexColouring(G);
ChromaticIndex(G);
OptimalEdgeColouring(G);
ChromaticPolynomial(G);



////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E13";

G := Graph< 9 | [ {4,5,6,7,8,9}, {4,5,6,7,8,9}, {4,5,6,7,8,9},
                  {1,2,3,7,8,9}, {1,2,3,7,8,9}, {1,2,3,7,8,9},
                  {1,2,3,4,5,6}, {1,2,3,4,5,6}, {1,2,3,4,5,6} ]>;
HasClique(G, 2);
HasClique(G, 2, true);
HasClique(G, 2, false);
HasClique(G, 2, true: Al := "Dynamic");
HasClique(G, 2, false: Al := "Dynamic");
HasClique(G, 2, true, 1);
MaximumClique(G);
AC := AllCliques(G);
#AC;
AC3 := AllCliques(G,3);
#AC3;
AC eq AC3;    
AllCliques(G, 2, true);
AllCliques(G, 2, false);


////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E14";

G := Graph<5 | { {1,2}, {2,3}, {3,4}, {4,5}, {5,1} }>;
 
AssignVertexLabels(~G, ["a", "b", "a", "b", "b"]);
A, _, _, _, _, C1 := AutomorphismGroup(G);
A;
C1;
B, _, _, _, _, C2 := AutomorphismGroup(G : IgnoreLabels := true);
B;
C2;
C, _, _, _, _, C3 := AutomorphismGroup(G : Stabilizer :=
[ { VertexSet(G) | 1, 2 } ]);
C;
#C;
C3;


////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E15";

G1 := CompleteGraph(5);
AssignVertexLabels(~G1, ["a", "a", "b", "b", "b"]);
G2 := CompleteGraph(5);
IsIsomorphic(G1, G2);
 
V1 := Vertices(G1);
V2 := Vertices(G2);
S1 := { V1 | 1, 2, 3};
S2 := { V2 | 3, 4, 5};
IsIsomorphic(G1, G2);

SS1 := [ { V1 | 1}, {V1 | 2, 3} ];
SS2 := [ { V2 | 3, 4}, { V2 | 1} ];
IsIsomorphic(G1, G2);
 
SS1 := [ {V1 | 2, 3}, { V1 | 1} ];
IsIsomorphic(G1, G2);

G1 := CompleteGraph(5);
AssignVertexLabels(~G1, ["a", "a", "b", "b", "b"]);
G2 := CompleteGraph(5);
IsIsomorphic(G1, G2);
IsIsomorphic(G1, G2);
G1 := CompleteGraph(5);
G2 := CompleteGraph(5);
AssignVertexLabels(~G1, ["a", "a", "b", "b", "b"]);
AssignVertexLabels(~G2, ["a", "b", "a", "b", "a"]);
IsIsomorphic(G1, G2);
AssignVertexLabels(~G2, ["b", "a", "b", "a", "b"]);
IsIsomorphic(G1, G2);
 
AssignVertexLabels(~G2, ["b", "c", "b", "c", "c"]);
IsIsomorphic(G1, G2);
 
IsIsomorphic(G1, G2);

////clear;
////ShowActive();
////ShowActive();
 
//print "Example: H1E16";

S := { 1 .. 5 };
V := &join[ Subsets({1..5}, 2*k) : k in [0..#S div 2]];
E := { {u,v} : u,v in V | #(u sdiff v) eq 4 };
G, V, E := StandardGraph( Graph< V | E >);
G;                                                                   
A, AV, AE := AutomorphismGroup(G);
A;
CompositionFactors(A);
IsPrimitive(A);                                                    
F := FittingSubgroup(A);
F;
EARNS(A) eq F;
S1 := Stabilizer(A, AV, V!1);
#S1;
IsTransitive(S1);
O := Orbits(S1);
O;
IsSymmetric(ActionImage(S1, O[3]));

////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E17";

g := KCubeGraph(8);
IsVertexTransitive(g);
IsEdgeTransitive(g);
IsSymmetric(g);
IsDistanceTransitive(g);
IntersectionArray(g);


////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E18";


D :=  StronglyRegularGraphsDatabase();
Cs := Classes(D);
Cs;
assert NumberOfClasses(D) eq #Cs;
NumberOfGraphs(D);
for i in [1..#Cs] do
    NumberOfGraphs(D, Cs[i]);
end for;
gs := Graphs(D, Cs[2]);
g :=  Graph(D, Cs[2], Random(1, NumberOfGraphs(D, Cs[2])));


////clear;
////ShowActive();
////ShowActive();



//print "Example: H1E19";

F := GenerateGraphs (12:
    FirstGraph:= 10,
    Connected:= true,
    Biconnected:= true,
    TriangleFree:= true,
    FourCycleFree:= true,
    Bipartite:= true,
    MinDeg:= 1,
    MaxDeg:= 9
);
count := 0;
while true do
    more := NextGraph(F);
    if more then
      count +:= 1;
    else
      break;
    end if;
end while;
count;


////clear;
////ShowActive();
////ShowActive();


///////////  IncidenceGeometry.text

//print "Example: H1E1";

gr := Graph<10|
  {1,2},{1,5},{1,6},{2,7},{2,3},{3,8},{3,4},{4,9},{4,5},{5,10},
  {6,8},{8,10},{10,7},{7,9},{9,6}>;
ig := IncidenceGeometry(gr);
ig;
 

////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E2";

g := Graph<26|
   {1,9},{1,12},{1,13},{1,21},{1,22},{1,25},
   {2,9},{2,10},{2,14},{2,21},{2,22},{2,23},
   {3,10},{3,11},{3,15},{3,21},{3,23},{3,24},
   {4,11},{4,12},{4,16},{4,21},{4,24},{4,25},
   {5,13},{5,18},{5,17},{5,22},{5,25},{5,26},
   {6,14},{6,19},{6,18},{6,23},{6,22},{6,26},
   {7,15},{7,19},{7,20},{7,24},{7,26},{7,23},
   {8,17},{8,20},{8,16},{8,26},{8,24},{8,25},
   {9,21},{9,22},{10,21},{10,23},{11,21},{11,24},
   {12,21},{12,25},{13,22},{13,25},{14,22},{14,23},
   {15,23},{15,24},{16,24},{16,25},{17,25},{17,26},
   {18,22},{18,26},{19,23},{19,26},{20,24},{20,26}>;
v := VertexSet(g);
AssignVertexLabels(~g, [1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3]);
cube := IncidenceGeometry(g);
cube;

////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E3";

HoffmanSingletonGraph := function()
  pentagram := Graph< 5 | { {1,3}, {3,5}, {5,2}, {2,4}, {4,1} } >;
  pentagon := PolygonGraph(5);
  PP := pentagram join pentagon;
  HS := &join [ PP : i in [1..5] ];
  return HS + { { Vertices(HS) | i + j*10, k*10 + 6 + (i+j*k) mod 5 } : 
                                 i in [1..5], j in [0..4], k in [0..4] };
end function;
ig := IncidenceGeometry(HoffmanSingletonGraph());


////clear;
////ShowActive();
////ShowActive();

//print "Example: H1E4";

gr := HoffmanSingletonGraph();
ig := IncidenceGeometry(gr);
aut := AutomorphismGroup(ig);
n := NormalSubgroups(aut);
X1 := VertexSet(gr);
g := CompleteGraph(50);
e := EdgeSet(gr);
ebis := [];
for x in EdgeSet(gr) do
    for i := 1 to 50 do
        for j := i+1 to 50 do
            if VertexSet(gr)!i in x then
                if VertexSet(gr)!j in x then
                    Append(~ebis,[i,j]);
                end if;
            end if;
        end for;
    end for;
end for;
for i := 1 to #ebis do
    RemoveEdge(~g,ebis[i][1],ebis[i][2]);
end for;
c := MaximumClique(g);
cbis := [];
for i := 1 to 50 do
    if (VertexSet(gr)!i in c) then Append(~cbis,i); end if;
end for;
c := Set(cbis);
X2 := Orbit(n[2]`subgroup,c);
X2 := SetToSequence(X2);
e := [];
for i := 1 to 50 do
    for j := 1 to 50 do
        if X1!i in Neighbours(X1!j) then Append(~e,{i,j+50}); end if;
    end for;
end for;
for i :=1 to 50 do
    for j := 1 to 50 do
        if not(i in X2[j]) then Append(~e,{i,j+100});end if;
    end for;
end for;
for i :=1 to 50 do
    for j := 1 to 50 do
        if i in  X2[j] then Append(~e,{i,j+150});end if;
    end for;
end for;
for i :=1 to 50 do
    for j := 1 to 50 do
        if i in  X2[j] then Append(~e,{i+50,j+100});end if;
    end for;
end for;
for i :=1 to 50 do
    for j := 1 to 50 do
        if not(i in  X2[j]) then Append(~e,{i+50,j+150});end if;
    end for;
end for;
for i :=1 to 50 do
    for j := 1 to 50 do
        if X2[i] meet X2[j] eq {} then Append(~e,{i+100,j+150});end if;
    end for;
end for;
gr2 := Graph<200|Set(e)>;
v := VertexSet(gr2);
labs := [i: j in {1..50}, i in {1..4}];
AssignVertexLabels(~gr2,labs);
neumaier := IncidenceGeometry(gr2);


//print "Example: H1E5";

g := Sym(5);
g0 := Stabilizer(g,{1,2});
g01 := Stabilizer(g,[{1,2},{3,4}]);
g1 := sub<g|g01,(1,3)(2,4)>;
cg := CosetGeometry(g,{g0,g1});
cg;


//print "Example: H1E6";

g := sub<Sym(8)|
    (1,2,3,4)(5,6,7,8), (1,5)(2,6)(3,7)(4,8), (2,4,5)(3,8,6)>;
g0 := Stabilizer(g,1);
g1 := Stabilizer(g,{1,2});
g2 := Stabilizer(g,{1,2,3,4});
cg := CosetGeometry(g,{g0,g1,g2});
cg;


//print "Example: H1E7";

g := Sym(6);
s := [Stabilizer(g,{1..j}) : j in {1..5}];
cg := CosetGeometry(g,Set(s));
cg;


//print "Example: H1E9";

g := Graph<10|
{1,2},{1,5},{1,6},{2,7},{2,3},{3,8},{3,4},{4,9},{4,5},{5,10},
{6,8},{8,10},{10,7},{7,9},{9,6}>;
ig := IncidenceGeometry(g);
IsFirm(ig);
IsRC(ig);
IsFTGeometry(ig);
g := Graph<10|
{1,2},{1,5},{1,6},{2,7},{2,3},{3,8},{3,4},{4,9},{4,5},{5,10},
{6,8},{8,10},{10,7},{7,9},{9,6}>;
ig := IncidenceGeometry(g);
d, v, e := Diagram(ig); 
d;
for x in v do print x, Label(x);
end for;
for x in e do print x, Label(x);
end for;

//print "Example: H1E10";

g := Graph<26|
   {1,9},{1,12},{1,13},{1,21},{1,22},{1,25},
   {2,9},{2,10},{2,14},{2,21},{2,22},{2,23},
   {3,10},{3,11},{3,15},{3,21},{3,23},{3,24},
   {4,11},{4,12},{4,16},{4,21},{4,24},{4,25},
   {5,13},{5,18},{5,17},{5,22},{5,25},{5,26},
   {6,14},{6,19},{6,18},{6,23},{6,22},{6,26},
   {7,15},{7,19},{7,20},{7,24},{7,26},{7,23},
   {8,17},{8,20},{8,16},{8,26},{8,24},{8,25},
   {9,21},{9,22},{10,21},{10,23},{11,21},{11,24},
   {12,21},{12,25},{13,22},{13,25},{14,22},{14,23},
   {15,23},{15,24},{16,24},{16,25},{17,25},{17,26},
   {18,22},{18,26},{19,23},{19,26},{20,24},{20,26}>;
v := VertexSet(g);
AssignVertexLabels(~g, [1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3]);
cube := IncidenceGeometry(g);
d, v, e := Diagram(cube);
d;
for x in v do x, Label(x); end for;
for x in e do x, Label(x); end for;

//print "Example: H1E11";

HoffmanSingletonGraph := function()
  pentagram := Graph< 5 | { {1,3}, {3,5}, {5,2}, {2,4}, {4,1} } >;
  pentagon := PolygonGraph(5);
  PP := pentagram join pentagon;
  HS := &join [ PP : i in [1..5] ];
  return HS + { { Vertices(HS) | i + j*10, k*10 + 6 + (i+j*k) mod 5 } : 
                                i in [1..5], j in [0..4], k in [0..4] };
end function;
ig := IncidenceGeometry(HoffmanSingletonGraph());
d, v, e := Diagram(ig);
d;
for x in v do print x, Label(x); end for;
for x in e do print x, Label(x); end for;


////print "Example: H1E12";
// this crashes

//d, v, e := Diagram(neumaier); 
//d;                                       
//for x in v do print x, Label(x); end for;
//for x in e do print x, Label(x); end for;


////clear;
////ShowActive();
////ShowActive();


///////////////   Plane.text


//print "Example: H1E18";


P, V, L := FiniteAffinePlane(3);
#V, #L;
IncidenceGraph(P);
LinearCode(P, Field(P));


////clear;
////ShowActive();
////ShowActive();

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

////load "/home/paule/planes/HB/design/all.m";
////load "/home/paule/planes/HB/plane/all.m";




////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////// /home/paule/graph/test/oldtestfile.m



//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);

G := Graph< 10 |
{ 1, 2 }, { 1, 5 }, { 1, 6 }, { 2, 3 }, { 2, 7 },
{ 3, 4 }, { 3, 8 }, { 4, 5 }, { 4, 9 }, { 5, 10 },
{ 6, 8 }, { 6, 9 }, { 7, 9 }, { 7, 10 }, { 8, 10 } >;


GS := Graph< 10 |
{ 1, 2 }, { 1, 5 }, { 1, 6 }, { 2, 3 }, { 2, 7 },
{ 3, 4 }, { 3, 8 }, { 4, 5 }, { 4, 9 }, { 5, 10 },
{ 6, 8 }, { 6, 9 }, { 7, 9 }, { 7, 10 }, { 8, 10 }
: SparseRep := true >;

assert G eq GS;


G1 := Graph< 10 |
[ { 2, 5, 6 }, { 1, 3, 7 }, { 2, 4, 8 }, { 3, 5, 9 },
{ 1, 4, 10 }, { 1, 8, 9 }, { 2, 9, 10 }, { 3, 6, 10 },
{ 4, 6, 7 }, { 5, 7, 8 } ] >;


GS1 := Graph< 10 |
[ { 2, 5, 6 }, { 1, 3, 7 }, { 2, 4, 8 }, { 3, 5, 9 },
{ 1, 4, 10 }, { 1, 8, 9 }, { 2, 9, 10 }, { 3, 6, 10 },
{ 4, 6, 7 }, { 5, 7, 8 } ]
: SparseRep := true >;

assert G eq G1;
assert G1 eq GS1;


M := MatrixRing( Integers(), 10 );
G2 := Graph< 10 | M![ 0,1,0,0,1,1,0,0,0,0,
                  1,0,1,0,0,0,1,0,0,0,
                  0,1,0,1,0,0,0,1,0,0,
                  0,0,1,0,1,0,0,0,1,0,
                  1,0,0,1,0,0,0,0,0,1,
                  1,0,0,0,0,0,0,1,1,0,
                  0,1,0,0,0,0,0,0,1,1,
                  0,0,1,0,0,1,0,0,0,1,
                  0,0,0,1,0,1,1,0,0,0,
                  0,0,0,0,1,0,1,1,0,0] >;

assert G2 eq G;





//clear;
//ShowActive();
//ShowActive();
 
////////////////////////////////////////////////////////



G := PermutationGroup< 30 |
(1, 2)(3, 4)(5, 7)(6, 8)(9, 13)(10, 12)(11, 15)
(14, 19) (16, 23)
(17, 22)(18, 21)(20, 27)(24, 29)(25, 28)(26, 30),
(1, 24, 28, 8)(2, 9, 17, 22)(3, 29, 19, 15)(4, 5, 21, 25)
(6, 18, 7, 16)(10, 13, 30, 11)(12, 14)(20, 23)(26, 27) >;
N1 := rep{ o : o in Orbits(Stabilizer(G, 1)) | #o eq 3 };

tutte := Graph< 30 | <1, N1>^G >;
tutteS := Graph< 30 | <1, N1>^G : SparseRep := true >;
 
assert tutte eq tutteS;




//clear;
//ShowActive();
//ShowActive();


G := Graph< 10 |
{ 1, 2 }, { 1, 5 }, { 1, 6 }, { 2, 3 }, { 2, 7 },
{ 3, 4 }, { 3, 8 }, { 4, 5 }, { 4, 9 }, { 5, 10 },
{ 6, 8 }, { 6, 9 }, { 7, 9 }, { 7, 10 }, { 8, 10 } >;


GS := Graph< 10 |
{ 1, 2 }, { 1, 5 }, { 1, 6 }, { 2, 3 }, { 2, 7 },
{ 3, 4 }, { 3, 8 }, { 4, 5 }, { 4, 9 }, { 5, 10 },
{ 6, 8 }, { 6, 9 }, { 7, 9 }, { 7, 10 }, { 8, 10 }
: SparseRep := true >;

assert G eq GS;


G1 := Graph< 10 |
[ { 2, 5, 6 }, { 1, 3, 7 }, { 2, 4, 8 }, { 3, 5, 9 },
{ 1, 4, 10 }, { 1, 8, 9 }, { 2, 9, 10 }, { 3, 6, 10 },
{ 4, 6, 7 }, { 5, 7, 8 } ] >;


GS1 := Graph< 10 |
[ { 2, 5, 6 }, { 1, 3, 7 }, { 2, 4, 8 }, { 3, 5, 9 },
{ 1, 4, 10 }, { 1, 8, 9 }, { 2, 9, 10 }, { 3, 6, 10 },
{ 4, 6, 7 }, { 5, 7, 8 } ]
: SparseRep := true >;

assert G eq G1;
assert G1 eq GS1;


M := MatrixRing( Integers(), 10 );
G2 := Graph< 10 | M![ 0,1,0,0,1,1,0,0,0,0,
                  1,0,1,0,0,0,1,0,0,0,
                  0,1,0,1,0,0,0,1,0,0,
                  0,0,1,0,1,0,0,0,1,0,
                  1,0,0,1,0,0,0,0,0,1,
                  1,0,0,0,0,0,0,1,1,0,
                  0,1,0,0,0,0,0,0,1,1,
                  0,0,1,0,0,1,0,0,0,1,
                  0,0,0,1,0,1,1,0,0,0,
                  0,0,0,0,1,0,1,1,0,0] >;

assert G2 eq G;





//clear;
//ShowActive();
//ShowActive();
 
////////////////////////////////////////////////////////



G := PermutationGroup< 30 |
(1, 2)(3, 4)(5, 7)(6, 8)(9, 13)(10, 12)(11, 15)
(14, 19) (16, 23)
(17, 22)(18, 21)(20, 27)(24, 29)(25, 28)(26, 30),
(1, 24, 28, 8)(2, 9, 17, 22)(3, 29, 19, 15)(4, 5, 21, 25)
(6, 18, 7, 16)(10, 13, 30, 11)(12, 14)(20, 23)(26, 27) >;
N1 := rep{ o : o in Orbits(Stabilizer(G, 1)) | #o eq 3 };

tutte := Graph< 30 | <1, N1>^G >;
tutteS := Graph< 30 | <1, N1>^G : SparseRep := true >;
 
assert tutte eq tutteS;




//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);

D1 := Digraph< 5 | [1, 2], [1, 3], [1, 4],
                  [3, 2], [4, 3] >;

D1S := Digraph< 5 | [1, 2], [1, 3], [1, 4],
[3, 2], [4, 3]
: SparseRep := true >;

assert D1 eq D1S;

		  
M := MatrixRing(Integers(), 5);
D2 := Digraph< 5 | 
          M![ 0,1,1,1,0, 
              0,0,0,0,0, 
              0,1,0,0,0, 
              0,0,1,0,0,
              0,0,0,0,0 ] >; 
assert IsIsomorphic(D1, D2);
assert IsIsomorphic(D1S, D2);
 
//clear;
//ShowActive();
//ShowActive();



////////////////////////////////////////////////////////


	      
V := Subsets({1..5}, 2);                                   
G := Graph< V | { {u,v} : u,v in V | IsDisjoint(u, v) } >;
GS := Graph< V | { {u,v} : u,v in V | IsDisjoint(u, v) } :
SparseRep := true >;


assert Support(G) eq Support(GS);
assert StandardGraph(G) eq StandardGraph(GS);


////////////////////////////////////////////////////////



kd5 := CompleteDigraph(5);

GS := Digraph< 5 | kd5 : SparseRep := true >;
assert HasSparseRep(GS);
assert GS eq kd5;


G := Digraph< 5 | GS >;
assert HasDenseRep(G);
assert G eq GS;
assert G eq kd5;


G := Digraph< 5 | GS : SparseRep := true >;
assert HasSparseRep(G);
assert G eq kd5;

G := Digraph< 5 | kd5 >;
assert HasDenseRep(G);
assert G eq kd5;







rd5 := RandomDigraph(5, 0.75);

GS := Digraph< 5 | rd5 : SparseRep := true >;
assert HasSparseRep(GS);
assert GS eq rd5;



G := Digraph< 5 | GS >;
assert HasDenseRep(G);
assert G eq GS;
assert G eq rd5;


G := Digraph< 5 | GS : SparseRep := true >;
assert HasSparseRep(G);
assert G eq rd5;

G := Digraph< 5 | rd5 >;
assert HasDenseRep(G);
assert G eq rd5;




 
//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////



K34, V, E := BipartiteGraph(3, 4);
L := [ IsEven(Distance(V!1, v)) select "red" else "blue" : 
    v in Vertices(K34) ];
AssignLabels(Vertices(K34), L);


KS34 := Graph< 7 | K34 : SparseRep := true >;
assert  HasSparseRep(KS34);
AssignLabels(Vertices(KS34), L);

//K34:Magma;
//KS34:Magma;
//K34:Maximal;
//KS34:Maximal;

assert VertexLabels(K34) eq VertexLabels(KS34);


//////////////////////////////////////////////////////////


G<a,b> := FPGroup(Sym(4));
I,m := Transversal(G, sub<G | 1>);
S := Setseq(Generators(G));
N := [{m(a*b) : b in S} : a in I];

graph := StandardGraph(Digraph<I | N>);
assert HasDenseRep(graph);
AssignLabels(VertexSet(graph), IndexedSetToSequence(I));
for i in [1..#I] do
    AddEdges(~graph,
    [[i, Index(I, m(I[i]*s))] : s in S], S);
end for;


graphS := StandardGraph(Digraph<I | N
: SparseRep := true>);
assert HasSparseRep(graphS);

assert graphS eq UnlabelledGraph(graph);

//Edges(graph);
//Edges(graphS);
//for e in [1..#Edges(graph)] do
//    edge := Edges(graph)[e];
//    edgeS := Edges(graphS)[e];
//    assert EndVertices(edge)[1] eq EndVertices(edgeS)[1];
//end for;
// Could not find an overgraph for vertices or edges


AssignLabels(VertexSet(graphS), IndexedSetToSequence(I));
for i in [1..#I] do
    AddEdges(~graphS,
    [[i, Index(I, m(I[i]*s))] : s in S], S);
end for;

assert EdgeLabels(graph) eq EdgeLabels(graphS);
assert &*EdgeLabels(graph, [[1,2],[2,5],[5,4],[4,1]])
eq &*EdgeLabels(graphS, [[1,2],[2,5],[5,4],[4,1]]);

//graph;
//graphS;
//graph:Magma;
//graphS:Magma;
//graph:Maximal;
//graphS:Maximal;



//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);

K6 := CompleteGraph(6);
K6S := Graph< 6 | K6 : SparseRep := true >;

assert HasDenseRep(K6);
assert HasSparseRep(K6S);
assert K6 eq K6S;

EL := [ IntegerToString(i) cat IntegerToString(j) :
j in [i+1..6], i in [1..6]  ];

for i in [1..6] do
    for j in [i+1..6] do
	AssignLabel(K6, i, j,
	IntegerToString(i) cat IntegerToString(j));
    end for;
end for;


for i in [1..6] do
    for j in [i+1..6] do
	AssignLabel(K6S, i, j,
	IntegerToString(i) cat IntegerToString(j));
    end for;
end for;

assert EdgeLabels(K6) eq EdgeLabels(K6S);
assert EdgeLabels(K6) eq EL;

//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);

 
K6, V, E := CompleteGraph(6);
F1 := { E | {1,2}, {3, 4}, {5, 6} };
G1, V1, E1 := K6 - F1;
assert IsSubgraph(K6, G1);


K6S := Graph< 6 | K6 : SparseRep := true>;
assert HasSparseRep(K6S);
G1S := K6S - F1;



assert G1S eq G1;
assert HasSparseRep(G1S);
assert HasDenseRep(G1);
assert IsSubgraph(K6S, G1S);


G2 := sub< K6 | { VertexSet(K6)!1, VertexSet(K6)!2 ,
VertexSet(K6)!3, VertexSet(K6)!4 } >;
assert HasDenseRep(G2);
assert IsSubgraph(K6, G2);



G2S := sub< K6S | { VertexSet(K6S)!1, VertexSet(K6S)!2 ,
VertexSet(K6S)!3, VertexSet(K6S)!4 } >;
assert HasSparseRep(G2S);
assert IsSubgraph(K6S, G2S);
assert G2 eq G2S;



 
K9, V, E := CompleteGraph(9);
P := { { V | 1, 2, 3}, { V | 4, 5, 6}, { V | 7, 8, 9} };
Q := quo< K9 | P >;
assert HasDenseRep(Q);

K9S, VS, ES := Graph< 9 | K9 : SparseRep := true >;
assert HasSparseRep(K9S);

PS := { { VS | 1, 2, 3}, { VS | 4, 5, 6},
{ VS | 7, 8, 9} };
QS := quo< K9S | PS >;
assert HasSparseRep(QS);
assert Q eq QS;


 

//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////



G := CompleteGraph(5);
GS := Graph<5 | G : SparseRep := true >;
assert HasDenseRep(G);
assert HasSparseRep(GS);
assert G eq GS;


E := EdgeSet(G);
H := InsertVertex({ E |
{ 1, 3 }, { 1, 4 }, { 2, 4 }, { 2, 5 }, { 3, 5 } } );


L := Union(H, CompleteGraph(1));
V := VertexSet(L);
L := L + {  { V.11, V.6 }, { V.11, V.7 },
{ V.11, V.8 }, { V.11, V.9 }, { V.11, V.10 } };



ES := EdgeSet(GS);
HS := InsertVertex({ ES |
{ 1, 3 }, { 1, 4 }, { 2, 4 }, { 2, 5 }, { 3, 5 } } );

assert HasDenseRep(H);
assert HasSparseRep(HS) and not HasDenseRep(HS);
assert H eq HS;


LS := Union(HS, CompleteGraph(1));
VS := VertexSet(LS);
LS := LS + {  { VS.11, VS.6 }, { VS.11, VS.7 },
{ VS.11, VS.8 }, { VS.11, VS.9 }, { VS.11, VS.10 } };
assert HasSparseRepOnly(HS);
assert HasDenseRep(LS);
assert LS  eq L;


H1 := Contract({ VertexSet(H) | 1, 6, 7 });
H1 := Contract({ VertexSet(H1) | 2, 6, 7 });
H1 := Contract({ VertexSet(H1) | 3, 6 });
assert H1 eq G;
assert HasDenseRep(H1) and not HasSparseRep(H1);


HS := InsertVertex({ ES |
{ 1, 3 }, { 1, 4 }, { 2, 4 }, { 2, 5 }, { 3, 5 } } );
H1S := Contract({ VertexSet(HS) | 1, 6, 7 });
H1S := Contract({ VertexSet(H1S) | 2, 6, 7 });
H1S := Contract({ VertexSet(H1S) | 3, 6 });
assert H1S eq GS;
assert HasSparseRep(H1S) and not HasDenseRep(H1S);



H := Switch({ VertexSet(G) | 1, 5});
assert HasDenseRep(H) and not HasSparseRep(H);
HS := Switch({ VertexSet(GS) | 1, 5});
assert HasSparseRep(HS) and not HasDenseRep(HS);
assert HS eq H;

//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////


 
 
 
G := Graph< 5 | {1, 2}, {1, 3}, {1, 4}, {1, 5} >;
H := Graph< 5 | {2, 1}, {2, 3}, {2, 4}, {2, 5} >;
 
U := EdgeUnion(G, H);
assert HasDenseRep(G) and HasDenseRep(H)
and HasDenseRep(U);

 
 
 
G := Graph< 5 | {1, 2}, {1, 3}, {1, 4}, {1, 5} :
SparseRep := true >;
H := Graph< 5 | {2, 1}, {2, 3}, {2, 4}, {2, 5} :
SparseRep := true >;
 
U1 := EdgeUnion(G, H);
assert HasSparseRepOnly(G) and HasSparseRepOnly(H)
and HasSparseRepOnly(U1);

 
 
 
G := Graph< 5 | {1, 2}, {1, 3}, {1, 4}, {1, 5} >;
H := Graph< 5 | {2, 1}, {2, 3}, {2, 4}, {2, 5} :
SparseRep := true >;
 
U2 := EdgeUnion(G, H);
assert HasDenseRepOnly(G) and HasSparseRepOnly(H)
and HasDenseRepOnly(U2);

 
 
 
G := Graph< 5 | {1, 2}, {1, 3}, {1, 4}, {1, 5} :
SparseRep := true >;
H := Graph< 5 | {2, 1}, {2, 3}, {2, 4}, {2, 5} >;
 
U3 := EdgeUnion(G, H);
assert HasSparseRepOnly(G) and HasDenseRepOnly(H)
and HasSparseRepOnly(U3);

assert U eq U1 and U1 eq U2 and U2 eq U3;

 
 
//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

 

G := Graph< 6 | [{ 6, 5, 4, 3 },  { 6, 5, 4, 3 },
{ 6, 5, 2, 1 }, { 6, 5, 2, 1 }, { 4, 3, 2, 1},
{4, 3, 2, 1} ] >;

assert HasDenseRep(G);
assert IsPlanar(G);
assert HasDenseAndSparseRep(G);


GS := Graph< 6 | [{ 6, 5, 4, 3 },  { 6, 5, 4, 3 },
{ 6, 5, 2, 1 }, { 6, 5, 2, 1 }, { 4, 3, 2, 1},
{ 4, 3, 2, 1} ] : SparseRep := true >;

assert HasSparseRep(GS);
assert IsPlanar(GS);
assert not HasDenseAndSparseRep(GS);


//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////


G := CompleteGraph(5);
GS := Graph< 5 | G : SparseRep := true >;
assert GS eq G;

UG := OrientatedGraph(G);
assert HasDenseRep(UG) and not HasSparseRep(UG);

UGS := OrientatedGraph(GS);
assert HasSparseRep(UGS) and not HasDenseRep(UGS);
assert UGS eq UG;


O := UnderlyingGraph(UG);
assert HasDenseRep(O) and not HasSparseRep(O);
assert O eq G;


OS := UnderlyingGraph(UGS);
assert HasSparseRep(OS) and not HasDenseRep(OS);
assert OS eq GS;

D := UnderlyingDigraph(G);
assert HasDenseRep(D) and not HasSparseRep(D);


DS := UnderlyingDigraph(GS);
assert HasSparseRep(DS) and not HasDenseRep(DS);
assert D eq DS;



//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetMark(true);

for n in [10..15] do

    d := 0.1;
    while d le 0.9 do
        
	//print "new graph", n, RealField(4)!d;
	//GetSeed();
	G := RandomDigraph(n, d : SparseRep := true);

	H := Converse(G);
	assert HasSparseRepOnly(H);
	for i in [1..n] do
	    for j in [1..n] do
		if VertexSet(G)!i adj VertexSet(G)!j then
		    assert VertexSet(H)!j adj
		    VertexSet(H)!i;
		else
		    assert not VertexSet(H)!j adj
		    VertexSet(H)!i;
		end if;
	    end for;
	end for;
	
	//print "new graph", n, RealField(4)!d;
	//GetSeed();
	G := RandomDigraph(n, d);

	H := Converse(G);
	assert HasDenseRepOnly(H);
	for i in [1..n] do
	    for j in [1..n] do
		if VertexSet(G)!i adj VertexSet(G)!j then
		    assert VertexSet(H)!j adj
		    VertexSet(H)!i;
		else
		    assert not VertexSet(H)!j adj
		    VertexSet(H)!i;
		end if;
	    end for;
	end for;
	
        d +:= 0.1;

    end while;

end for;

//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);
 
n := 200;
G := CompleteGraph(n);
assert HasDenseRep(G) and not HasSparseRep(G);
GS := Graph< n | G : SparseRep := true >;
assert HasSparseRep(GS) and not HasDenseRep(GS);
assert G eq GS;

assert DegreeSequence(G) eq DegreeSequence(GS);

assert IsRegular(G);
assert HasDenseRep(G) and not HasSparseRep(G);
assert IsRegular(GS);
assert Valence(G) eq Valence(GS);

assert HasSparseRep(GS) and not HasDenseRep(GS);


UG := UnderlyingDigraph(G);
assert HasDenseRep(UG) and not HasSparseRep(UG);
UGS := UnderlyingDigraph(GS);
assert HasSparseRep(UGS) and not HasDenseRep(UGS);

assert DegreeSequence(UG) eq DegreeSequence(UGS);

assert IsRegular(UG);
assert HasDenseRep(G) and not HasSparseRep(G);
assert IsRegular(UGS);
assert HasSparseRep(GS) and not HasDenseRep(UGS);
assert Valence(UG) eq Valence(UGS);


UG := OrientatedGraph(G);
assert HasDenseRep(UG) and not HasSparseRep(UG);
UGS := OrientatedGraph(GS);
assert HasSparseRep(UGS) and not HasDenseRep(UGS);

assert DegreeSequence(UG) eq DegreeSequence(UGS);



//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);
 
n := 100;
G := RandomGraph(n, 0.5);
assert HasDenseRep(G) and not HasSparseRep(G);
GS := Graph< n | G : SparseRep := true >;
assert HasSparseRep(GS) and not HasDenseRep(GS);
assert G eq GS;


for i in [1..n] do
    assert Degree(VertexSet(G)!i)
    eq Degree(VertexSet(GS)!i);
end for;
assert HasDenseRep(G) and not HasSparseRep(G);
assert HasSparseRep(GS) and not HasDenseRep(GS);

maxdG, vG  := MaximumDegree(G);
maxdGS, vGS := MaximumDegree(GS);
assert maxdG eq maxdGS;
assert Index(vG) eq Index(vGS);

mindG, vG  := MinimumDegree(G);
mindGS, vGS := MinimumDegree(GS);
assert mindG eq mindGS;
assert Index(vG) eq Index(vGS);

assert HasDenseRep(G) and not HasSparseRep(G);
assert HasSparseRep(GS) and not HasDenseRep(GS);


for d in [1..n] do
    S := Alldeg(G, d);
    SS := Alldeg(GS, d);
    assert #S eq #SS;
    for l in [1..#S] do
	assert Index(SetToSequence(S)[l])
	eq Index(SetToSequence(SS)[l]);
    end for;
end for;
assert HasDenseRep(G) and not HasSparseRep(G);
assert HasSparseRep(GS) and not HasDenseRep(GS);





D := OrientatedGraph(G);
DS := OrientatedGraph(GS);
assert HasDenseRep(D) and not HasSparseRep(D);
assert HasSparseRep(DS) and not HasDenseRep(DS);
assert D eq DS;




for i in [1..n] do
    assert Degree(VertexSet(D)!i)
    eq Degree(VertexSet(DS)!i);
    assert InDegree(VertexSet(D)!i)
    eq InDegree(VertexSet(DS)!i);
    assert OutDegree(VertexSet(D)!i)
    eq OutDegree(VertexSet(DS)!i);
end for;
assert HasDenseRep(D) and not HasSparseRep(D);
assert HasSparseRep(DS) and not HasDenseRep(DS);

maxdD, vD  := MaximumDegree(D);
maxdDS, vDS := MaximumDegree(DS);
assert maxdG eq maxdDS;
assert Index(vD) eq Index(vDS);

mindD, vD  := MinimumDegree(D);
mindDS, vDS := MinimumDegree(DS);
assert mindD eq mindDS;
assert Index(vD) eq Index(vDS);

maxdD, vD  := MaximumInDegree(D);
maxdDS, vDS := MaximumInDegree(DS);
assert maxdD eq maxdDS;
assert Index(vD) eq Index(vDS);

maxdD, vD  := MaximumOutDegree(D);
maxdDS, vDS := MaximumOutDegree(DS);
assert maxdD eq maxdDS;
assert Index(vD) eq Index(vDS);

mindG, vD  := MinimumInDegree(D);
mindDS, vDS := MinimumInDegree(DS);
assert mindG eq mindDS;
assert Index(vD) eq Index(vDS);

mindD, vD  := MinimumOutDegree(D);
mindDS, vDS := MinimumOutDegree(DS);
assert mindD eq mindDS;
assert Index(vD) eq Index(vDS);

assert HasDenseRep(D) and not HasSparseRep(D);
assert HasSparseRep(DS) and not HasDenseRep(DS);


for d in [1..2 * n] do
    S := Alldeg(D, d);
    SS := Alldeg(DS, d);
    assert #S eq #SS;
    for l in [1..#S] do
	assert Index(SetToSequence(S)[l])
	eq Index(SetToSequence(SS)[l]);
    end for;
end for;
assert HasDenseRep(D) and not HasSparseRep(D);
assert HasSparseRep(DS) and not HasDenseRep(DS);





//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);

n := 100;
G := RandomGraph(n, 0.5);
assert HasDenseRep(G) and not HasSparseRep(G);
GS := Graph< n | G : SparseRep := true >;
assert HasSparseRep(GS) and not HasDenseRep(GS);
assert G eq GS;


for v in [1..n] do
    
    N := Neighbours(VertexSet(G)!v);
    NS := Neighbours(VertexSet(GS)!v);
    assert #N eq #NS;

    for l in [1..#N] do
	assert Index(SetToSequence(N)[l])
	eq Index(SetToSequence(NS)[l]);
    end for;
    
end for;
assert HasDenseRep(G) and not HasSparseRep(G);
assert HasSparseRep(GS) and not HasDenseRep(GS);


for v in [1..n] do
    E := IncidentEdges(VertexSet(G)!v);
    ES := IncidentEdges(VertexSet(GS)!v);
    assert #E eq #ES;

    assert #E eq Degree(VertexSet(G)!v);
    assert #ES eq Degree(VertexSet(GS)!v);
    E := SetToSequence(E);
    ES := SetToSequence(ES);

    for l in [1..#E] do

	e := E[l];
	e1 := SetToSequence(EndVertices(e))[1];
	e2 := SetToSequence(EndVertices(e))[2];

	es := ES[l];
	es1 := SetToSequence(EndVertices(es))[1];
	es2 := SetToSequence(EndVertices(es))[2];

	assert Index(e1) eq Index(es1);
	assert Index(e2) eq Index(es2);
	
    end for;
end for;
assert HasDenseRep(G) and not HasSparseRep(G);
assert HasSparseRep(GS) and not HasDenseRep(GS);


D := OrientatedGraph(G);
DS := OrientatedGraph(GS);
assert HasDenseRep(D) and not HasSparseRep(D);
assert HasSparseRep(DS) and not HasDenseRep(DS);
assert D eq DS;


for v in [1..n] do
    
    N := InNeighbours(VertexSet(D)!v);
    NS := InNeighbours(VertexSet(DS)!v);
    assert #N eq #NS;
    for l in [1..#N] do
	assert Index(SetToSequence(N)[l])
	eq Index(SetToSequence(NS)[l]);
    end for;

    N := OutNeighbours(VertexSet(D)!v);
    NS := OutNeighbours(VertexSet(DS)!v);
    assert #N eq #NS;
    for l in [1..#N] do
	assert Index(SetToSequence(N)[l])
	eq Index(SetToSequence(NS)[l]);
    end for;
end for;
assert HasDenseRep(D) and not HasSparseRep(D);
assert HasSparseRep(DS) and not HasDenseRep(DS);


for v in [1..n] do
    E := IncidentEdges(VertexSet(D)!v);
    ES := IncidentEdges(VertexSet(DS)!v);
    assert #E eq #ES;

    assert #E eq OutDegree(VertexSet(D)!v) +
	InDegree(VertexSet(D)!v);
    assert #ES eq OutDegree(VertexSet(DS)!v) +
	InDegree(VertexSet(DS)!v);
    
    E := SetToSequence(E);
    ES := SetToSequence(ES);
    for l in [1..#E] do

	e := E[l];
	e1 := EndVertices(e)[1];
	e2 := EndVertices(e)[2];

	es := ES[l];
	es1 := EndVertices(es)[1];
	es2 := EndVertices(es)[2];

	assert Index(e1) eq Index(es1);
	assert Index(e2) eq Index(es2);
	
    end for;
end for;
assert HasDenseRep(D) and not HasSparseRep(D);
assert HasSparseRep(DS) and not HasDenseRep(DS);


//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);


procedure is_ok(G, GS)

    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);

    if IsConnected(G) then
	C := { Index(v) : v in CutVertices(G) };
	CS := { Index(v) : v in CutVertices(GS) };
	assert C eq CS;
	//print "cut vertices ", #C;
    end if;
    //print "#edges ", Size(G);
    
     B := Bicomponents(G);
     BS := Bicomponents(GS);
    assert #B eq #BS;
    //print "bicomponents ", #B;
    total_size := 0;
    for b in B do
	bb := { Index(v) : v in b };
	bbs := { VertexSet(GS) | v : v in bb };
	assert bbs in BS;

	H := sub< G | b >;
	assert IsBiconnected(H);
	HS := sub< GS | bbs >;
	assert IsBiconnected(HS);
	assert H eq HS;
	assert HasDenseRepOnly(H);
	assert HasSparseRepOnly(HS);

	total_size +:= Size(HS);
    end for;
    assert SequenceToSet(B) eq SequenceToSet(BS);

    assert total_size eq Size(GS);
    
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);
   
end procedure;


G := Graph< 6 | [ {2, 3}, {1, 3, 4}, {1, 2},
{2, 5, 6}, {4, 6}, {4, 5} ] >;
GS := Graph< 6 | G : SparseRep := true >;
is_ok(G, GS);

G := EmptyGraph(5);
GS := Graph< 5 | G : SparseRep := true >;
is_ok(G, GS);

G := Graph< 5 | [ {5}, {5}, {5}, {5}, {1,2,3,4} ] >;
GS := Graph< 5 | G : SparseRep := true >;
is_ok(G, GS);

G := Graph< 5 | [ {2,3,4,5}, {1}, {1}, {1}, {1} ] >;
GS := Graph< 5 | G : SparseRep := true >;
is_ok(G, GS);

n := 20;
while n lt 300 do
    //print "n                ", n;
    d := 0.01;
    //while d lt 0.6 do 
	for i in [1..1] do

	    //GetSeed();

	    G := RandomGraph(n, d); //IsConnected(G);
	    GS := Graph< n | G : SparseRep := true >;
	    is_ok(G, GS);

	end for;
	// d +:= 0.05;
    // end while;
    n +:= 20;
end while;

//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);


n := 20;
while n lt 200 do
    //print "n                ", n;
    d := 0.01;
    //while d lt 0.6 do 
	for i in [1..2] do

	    //GetSeed();

	    G := RandomGraph(n, d); 
	    GS := Graph< n | G : SparseRep := true >;
	    assert IsConnected(G) eq IsConnected(GS);
	     b := IsConnected(G);
	     b := IsConnected(GS);
	    
	    assert HasDenseRepOnly(G);
	    assert HasSparseRepOnly(GS);
   
	end for;
	// d +:= 0.05;
    // end while;
    n +:= 20;
end while;


n := 20;
//SetSeed(1, 347659);
while n lt 200 do
    //print "n                ", n;
    d := 0.05;
    //while d lt 0.6 do 
	for i in [1..2] do

	    //GetSeed();

	    G := RandomGraph(n, d); 
	    GS := Graph< n | G : SparseRep := true >;

	    if IsConnected(G) then
		assert IsSeparable(G) eq IsSeparable(GS);
		b := IsSeparable(G);
		b := IsSeparable(GS);
	    end if;
	    
	    assert HasDenseRepOnly(G);
	    assert HasSparseRepOnly(GS);
   
	end for;
	// d +:= 0.05;
    // end while;
    n +:= 20;
end while;

n := 10;
for i in [1..10] do
    G := PathGraph(n);
    GS := Graph< n | G : SparseRep := true >;

    assert IsPath(G) eq IsPath(GS);
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);
end for;

n := 10;
d := 0.5;
for i in [1..10] do
    G := RandomGraph(n, d);
    GS := Graph< n | G : SparseRep := true >;

    assert IsPath(G) eq IsPath(GS);
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);
end for;


//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);




n := 20;
while n lt 200 do
    //print "n                ", n;
    d := 0.02;
    //while d lt 0.6 do 
	for i in [1..2] do

	    //GetSeed();

	    G := RandomGraph(n, d); 
	    GS := Graph< n | G : SparseRep := true >;

	     C := Components(G);
	     CS := Components(GS);
	    assert #C eq #CS;

	    NC := {};
	    NCS := {};
	    for s in C do
		S := { Index(v) : v in s };
		Include(~NC, S);
	    end for;
	    for s in CS do
		S := { Index(v) : v in s };
		Include(~NCS, S);
	    end for;
	    assert NC eq NCS;
	    
	    assert HasDenseRepOnly(G);
	    assert HasSparseRepOnly(GS);
   
	end for;
	// d +:= 0.05;
    // end while;
    n +:= 20;
end while;



n := 20;
while n lt 200 do
    //print "n                ", n;
    d := 0.02;
    //while d lt 0.6 do 
	for i in [1..1] do

	    //GetSeed();

	    G := RandomGraph(n, d); 
	    GS := Graph< n | G : SparseRep := true >;

	    for v in [1..n] do
		//print " ";
		C := Component(VertexSet(G)!v);
		CS := Component(VertexSet(GS)!v);
		assert C eq CS;
	    end for;
	    
	    assert HasDenseRepOnly(G);
	    assert HasSparseRepOnly(GS);
   
	end for;
	// d +:= 0.05;
    // end while;
    n +:= 20;
end while;



//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);



/////////////////////////////////////


n := 20;
while n lt 100 do
    //print "n                ", n;
    d := 0.5;
    //while d lt 0.6 do 
	for i in [1..1] do

	    //GetSeed();

	    G := RandomGraph(n, d); 
	    GS := Graph< n | G : SparseRep := true >;

	    for v in [1..n] do
		    
		//print " ";
		C := DFSTree(VertexSet(G)!v);
		assert IsTree(C);
		CS := DFSTree(VertexSet(GS)!v);
		assert IsTree(CS);
		assert Size(C) eq Size(CS);
		
	    end for;
	    
	    assert HasDenseRepOnly(G);
	    assert HasSparseRepOnly(GS);
   
	end for;
	// d +:= 0.05;
    // end while;
    n +:= 50;
end while;



n := 20;
while n lt 200 do
    //print "n                ", n;
    d := 0.5;
    //while d lt 0.6 do 
	for i in [1..10] do

	    //GetSeed();

	    G := RandomGraph(n, d); 
	    GS := Graph< n | G : SparseRep := true >;

	    if IsConnected(G) then 
		    //print " ";

		     C := SpanningTree(G);
		    assert IsTree(C);
		     CS := SpanningTree(GS);
		    assert IsTree(CS);
		    assert Size(C) eq Size(CS);

		    assert IsConnected(SpanningForest(G));
		    assert IsConnected(SpanningForest(GS));
	    else
		C := SpanningForest(G);
		assert IsForest(C);
		CS := SpanningForest(GS);
		assert IsForest(CS);
		assert Size(C) eq Size(CS);
		assert #Components(C) eq #Components(CS);
	    end if;
		
	    
	    assert HasDenseRepOnly(G);
	    assert HasSparseRepOnly(GS);
   
	end for;
	// d +:= 0.05;
    // end while;
    n +:= 50;
end while;


//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);

procedure digraph_is_ok(G, GS)

    assert G eq GS;
    assert IsWeaklyConnected(G) eq
    IsWeaklyConnected(GS);
    assert IsStronglyConnected(G) eq
    IsStronglyConnected(GS);

    C := StronglyConnectedComponents(G);
    CS := StronglyConnectedComponents(GS);
    assert #C eq #CS;

    NC := {};
    NCS := {};
    for s in C do
	S := { Index(v) : v in s };
	Include(~NC, S);
    end for;
    for s in CS do
	S := { Index(v) : v in s };
	Include(~NCS, S);
    end for;
    assert NC eq NCS;
    
    s := 0;
    for c in C do
	H := sub< G | c >;
	assert IsStronglyConnected(H);
	assert HasDenseRepOnly(H);
	s +:= Order(H);
    end for;
    assert s eq Order(G);
	    
    s := 0;
    for c in CS do
	H := sub< GS | c >;
	assert IsStronglyConnected(H);
	assert HasSparseRepOnly(H);
	s +:= Order(H);
    end for;
    assert s eq Order(G);
	    
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);
    

    for v in [1..Order(G)] do

	T := DFSTree(VertexSet(G)!v);
	TS := DFSTree(VertexSet(GS)!v);
	assert IsTree(T) eq IsTree(TS);
	assert Order(T) eq Order(TS);
	assert HasDenseRepOnly(T);
	assert HasSparseRepOnly(TS);

	C := Component(VertexSet(G)!v);
	CS := Component(VertexSet(GS)!v);
	assert Order(C) eq Order(CS);
	assert Size(C) eq Size(CS);
	assert HasDenseRepOnly(C);
	assert HasSparseRepOnly(CS);
	
    end for;

end procedure;


G := Digraph< 5 | [1, 2], [2, 3], [3, 4], [1, 5] >;
GS := Digraph< 5 | G : SparseRep := true >;
digraph_is_ok(G, GS);


G := Digraph< 5 | [1, 2], [2, 3], [3, 4], [4, 5], [5, 1] >;
GS := Digraph< 5 | G : SparseRep := true >;
digraph_is_ok(G, GS);


G := CompleteDigraph(5);
GS := Digraph< 5 | G : SparseRep := true >;
digraph_is_ok(G, GS);


n := 20;
while n le 100 do
    //print "n                ", n;
    d := 0.05;
    //while d lt 0.6 do 
	for i in [1..1] do

	    //GetSeed();
	    G := RandomDigraph(n, d); 
	    GS := Digraph< n | G : SparseRep := true >;
	    digraph_is_ok(G, GS);
    	    
	end for;
	// d +:= 0.05;
    // end while;
    n +:= 20;
end while;


//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);

procedure bfs_is_ok(G, GS)

    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);

    for v in [1..Order(G)] do
    //for v in [1..1] do
    
	//print " ";
	T := BFSTree(VertexSet(G)!v);
	TS := BFSTree(VertexSet(GS)!v);
	assert IsTree(T) eq IsTree(TS);
	assert Order(T) eq Order(TS);
	assert HasDenseRepOnly(T);
	assert HasSparseRepOnly(TS);
	
    end for;
    
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);
   
end procedure;


G := Graph< 6 | [ {2, 3}, {1, 3, 4}, {1, 2},
{2, 5, 6}, {4, 6}, {4, 5} ] >;
GS := Graph< 6 | G : SparseRep := true >;
bfs_is_ok(G, GS);

G := EmptyGraph(5);
GS := Graph< 5 | G : SparseRep := true >;
bfs_is_ok(G, GS);

G := Graph< 5 | [ {5}, {5}, {5}, {5}, {1,2,3,4} ] >;
GS := Graph< 5 | G : SparseRep := true >;
bfs_is_ok(G, GS);

G := Graph< 5 | [ {2,3,4,5}, {1}, {1}, {1}, {1} ] >;
GS := Graph< 5 | G : SparseRep := true >;
bfs_is_ok(G, GS);



G := Digraph< 5 | [1, 2], [2, 3], [3, 4], [1, 5] >;
GS := Digraph< 5 | G : SparseRep := true >;
bfs_is_ok(G, GS);


G := Digraph< 5 | [1, 2], [2, 3], [3, 4], [4, 5], [5, 1] >;
GS := Digraph< 5 | G : SparseRep := true >;
bfs_is_ok(G, GS);


G := CompleteDigraph(5);
GS := Digraph< 5 | G : SparseRep := true >;
bfs_is_ok(G, GS);

n := 20;
while n lt 200 do
    //print "n                ", n;
    d := 0.01;
    //while d lt 0.6 do 
	for i in [1..1] do

	    //GetSeed();

	    G := RandomGraph(n, d);
	    GS := Graph< n | G : SparseRep := true >;
	    bfs_is_ok(G, GS);

	end for;
	// d +:= 0.05;
    // end while;
    n +:= 20;
end while;

n := 20;
while n lt 200 do
    //print "n                ", n;
    d := 0.01;
    //while d lt 0.6 do 
	for i in [1..1] do

	    //GetSeed();

	    G := RandomDigraph(n, d);
	    GS := Digraph< n | G : SparseRep := true >;
	    bfs_is_ok(G, GS);

	end for;
	// d +:= 0.05;
    // end while;
    n +:= 20;
end while;

//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);


G := Graph< 6 | [ {2, 3}, {1, 3, 4}, {1, 2},
{2, 5, 6}, {4, 6}, {4, 5} ] >;
GS := Graph< 6 | G : SparseRep := true >;

assert IsConnected(G);
assert IsConnected(GS);

G1 := G;
GS1 := GS;
RemoveVertex(~G1, 2);
RemoveVertex(~GS1, 2);
assert not IsConnected(G1);
assert not IsConnected(GS1);
assert HasDenseRepOnly(G1);
assert HasSparseRepOnly(GS1);

G1 := G;
GS1 := GS;
AddVertex(~G1);
AddVertex(~GS1);
assert not IsConnected(G1);
assert not IsConnected(GS1);
assert HasDenseRepOnly(G1);
assert HasSparseRepOnly(GS1);

G1 := G;
GS1 := GS;
AddEdge(~G1, 1, 3);
AddEdge(~GS1, 1, 3);
assert IsConnected(G1);
assert IsConnected(GS1);
assert HasDenseRepOnly(G1);
assert HasSparseRepOnly(GS1);


//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);



procedure faces_ok(G, GS)
    
    assert IsPlanar(G);
    assert IsPlanar(GS);
    assert #Faces(G) eq NFaces(G);
    assert #Faces(GS) eq NFaces(G);
    assert #Faces(GS) eq NFaces(GS);
    F := Faces(G);
    E := Embedding(G);
    for f in F do
	if #f gt 1 then
	    e := f[1];
	    assert Type(e) eq GrphEdge;
	    assert Face(e) eq f;
	end if;
    end for;
    ff := 0;
    for f in F do
	if #f gt 1 then
	    ff +:= #f;
	end if;
    end for;
    assert ff eq 2 * Size(G);
    ee := 0;
    for e in E do
	ee +:= #e;
    end for;
    assert ee eq 2 * Size(G);
    assert HasSparseRepOnly(GS);
    assert HasDenseAndSparseRep(G);

end procedure;


G := Graph< 5 | [ {2, 3, 4, 5}, {1, 3}, {1, 2},
{1, 5}, {1, 4} ] >;
GS := Graph< 5 | G : SparseRep := true >;
faces_ok(G, GS);


n := 20;
d := 0.01;
for i in [1..100] do
    //GetSeed();
    G := RandomGraph(n, d);
    GS := Graph< n | G : SparseRep := true >;
    // IsConnected(G);
    if IsPlanar(GS) then
	faces_ok(G, GS);
    end if;
end for;



//clear;
//ShowActive();
//ShowActive();

////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(68468,true);
//SetMark(true);



procedure faces_ok(GS)
    
    assert IsPlanar(GS);
    assert #Faces(GS) eq NFaces(GS);
    F := Faces(GS);
    E := Embedding(GS);
    for f in F do
	if #f gt 1 then
	    e := f[1];
	    assert Type(e) eq GrphEdge;
	    assert Face(e) eq f;
	end if;
    end for;
    ff := 0;
    for f in F do
	if #f gt 1 then
	    ff +:= #f;
	end if;
    end for;
    assert ff eq 2 * Size(GS);
    ee := 0;
    for e in E do
	ee +:= #e;
    end for;
    assert ee eq 2 * Size(GS);
    assert HasSparseRepOnly(GS);

end procedure;



//clear;
//ShowActive();
//ShowActive();

////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(65992,true);
//SetMark(true);

n := 20;
d := 0.1;
for i in [1..100] do

    a, b := GetSeed();
    //print ""; a, b;
    G := RandomGraph(n, d);
    SetSeed(a, b);
    GS := RandomGraph(n, d : SparseRep := true);
    assert G eq GS;
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);

    SE := {};
    SES := {};
    size := Random(1, Size(GS));

    while #SE lt size do
	for u in [1..n] do
	    for v in [u+1..n] do
		if VertexSet(G)!u adj VertexSet(G)!v then
		    Include(~SE, EdgeSet(G)!{u, v});
		    Include(~SES, EdgeSet(GS)!{u, v});
		end if;
	    end for;
	end for;
    end while;

    H := sub< G | SE >;
    HS := sub< GS | SES >;
    assert H eq HS;
    assert HasDenseRepOnly(H);
    assert HasSparseRepOnly(HS);

    assert EdgeSet(H) subset EdgeSet(G);
    assert EdgeSet(HS) subset EdgeSet(GS);
    assert EdgeSet(H) subset EdgeSet(GS);
    assert EdgeSet(HS) subset EdgeSet(G);
    
    a, b := GetSeed();
     G := RandomDigraph(n, d);
    SetSeed(a, b);
     GS := RandomDigraph(n, d : SparseRep := true);
    assert G eq GS;
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);

    SE := {};
    SES := {};
    size := Random(1, Size(GS));

    while #SE lt size do
	for u in [1..n] do
	    for v in [1..n] do
		if VertexSet(G)!u adj VertexSet(G)!v then
		    Include(~SE, EdgeSet(G)![u, v]);
		    Include(~SES, EdgeSet(GS)![u, v]);
		end if;
	    end for;
	end for;
    end while;

    H := sub< G | SE >;
    HS := sub< GS | SES >;
    assert H eq HS;
    assert HasDenseRepOnly(H);
    assert HasSparseRepOnly(HS);

    assert EdgeSet(H) subset EdgeSet(G);
    assert EdgeSet(HS) subset EdgeSet(GS);
    assert EdgeSet(H) subset EdgeSet(GS);
    assert EdgeSet(HS) subset EdgeSet(G);
    
    if i mod 5 eq 0 then
	d +:= 0.02;
    end if;
end for;


//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(65992,true);
//SetMark(true);


n := 5;
for i in [1..30] do

    //print "";
    //print "             n ", n;
    G := EmptyGraph(n);
    GS := EmptyGraph(n : SparseRep := true);
    assert G eq GS;
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);
    assert Size(G) eq Size(GS);

     G := PathGraph(n);
     GS := PathGraph(n : SparseRep := true);
    assert G eq GS;
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);
    assert Size(G) eq Size(GS);

     G := PolygonGraph(n);
     GS := PolygonGraph(n : SparseRep := true);
    assert G eq GS;
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);
    assert Size(G) eq Size(GS);

    G := EmptyDigraph(n);
    GS := EmptyDigraph(n : SparseRep := true);
    assert G eq GS;
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);
    assert Size(G) eq Size(GS);

    n +:= 10;
    
end for;


//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(65992,true);
//SetMark(true);


n := 5;
for i in [1..20] do

    //print "";
    //print "             n ", n;
    a, b := GetSeed();
    //print ""; a, b;
     G := RandomTree(n);
    assert IsTree(G);
    SetSeed(a, b);
     GS := RandomTree(n : SparseRep := true);
    assert IsTree(GS);
    assert G eq GS;
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);

    SE := {};
    SES := {};
    size := Random(1, Size(GS));

    while #SE lt size do
	for u in [1..n] do
	    for v in [1..n] do
		if VertexSet(G)!u adj VertexSet(G)!v then
		    Include(~SE, EdgeSet(G)!{u, v});
		    Include(~SES, EdgeSet(GS)!{u, v});
		end if;
	    end for;
	end for;
    end while;

    H := sub< G | SE >;
    HS := sub< GS | SES >;
    assert H eq HS;
    assert HasDenseRepOnly(H);
    assert HasSparseRepOnly(HS);

    assert EdgeSet(H) subset EdgeSet(G);
    assert EdgeSet(HS) subset EdgeSet(GS);
    assert EdgeSet(H) subset EdgeSet(GS);
    assert EdgeSet(HS) subset EdgeSet(G);
    
 
    n +:= 10;
    
end for;


//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(65992,true);
//SetMark(true);

k := 1;
for i in [1..8] do

    //print "";
    //print "             k ", k;
    //print "             n ", 2^k;
    //print "             e ", k * 2^(k-1);
     G := KCubeGraph(k);
     GS := KCubeGraph(k : SparseRep := true);
    assert G eq GS;
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);

    SE := {};
    SES := {};
    size := Random(1, Size(GS));

    n := Order(GS);
    while #SE lt size do
	for u in [1..n] do
	    for v in [1..n] do
		if VertexSet(G)!u adj VertexSet(G)!v then
		    Include(~SE, EdgeSet(G)!{u, v});
		    Include(~SES, EdgeSet(GS)!{u, v});
		end if;
	    end for;
	end for;
    end while;

    H := sub< G | SE >;
    HS := sub< GS | SES >;
    assert H eq HS;
    assert HasDenseRepOnly(H);
    assert HasSparseRepOnly(HS);

    assert EdgeSet(H) subset EdgeSet(G);
    assert EdgeSet(HS) subset EdgeSet(GS);
    assert EdgeSet(H) subset EdgeSet(GS);
    assert EdgeSet(HS) subset EdgeSet(G);
    
    k +:= 1;
    
end for;



//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(65992,true);
//SetMark(true);

n := 20;
d := 0.1;
for i in [1..100] do

    //GetSeed();
    G := RandomGraph(n, d);
    GS := Graph< n | AdjacencyMatrix(G)
    : SparseRep := true >;
    assert G eq GS;
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);
end for;
    
n := 20;
d := 0.1;
for i in [1..100] do

    //GetSeed();
    G := RandomDigraph(n, d);
    GS := Digraph< n | AdjacencyMatrix(G)
    : SparseRep := true >;
    assert G eq GS;
    assert HasDenseRepOnly(G);
    assert HasSparseRepOnly(GS);
end for;


//clear;
//ShowActive();
//ShowActive();

////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(65992,true);
//SetMark(true);

n := 100;
d := 0.1;
for i in [1..100] do

    //GetSeed();
    G := RandomGraph(n, d);
    E := EdgeSet(G);
    NE := {};
    for e in E do
	r := Random(0, 1);
	if r eq 1 then
	    Include(~NE, e);
	end if;
    end for;
    assert NE subset E;
    NG := Graph< n | NE >;
    assert IsSubgraph(G, NG);
    assert HasDenseRepOnly(G);
    assert HasDenseRepOnly(NG);
end for;
    

n := 100;
d := 0.1;
for i in [1..100] do

    //GetSeed();
    G := RandomGraph(n, d : SparseRep := true);
    E := EdgeSet(G);
    NE := {};
    for e in E do
	r := Random(0, 1);
	if r eq 1 then
	    Include(~NE, e);
	end if;
    end for;
    assert NE subset E;
    NG := Graph< n | NE >;
    assert IsSubgraph(G, NG);
    assert HasSparseRepOnly(G);
    assert HasDenseRepOnly(NG);
end for;
    


n := 100;
d := 0.1;
for i in [1..100] do

    //GetSeed();
    G := RandomGraph(n, d);
    E := EdgeSet(G);
    NE := {};
    for e in E do
	r := Random(0, 1);
	if r eq 1 then
	    Include(~NE, e);
	end if;
    end for;
    assert NE subset E;
    NG := Graph< n | NE : SparseRep := true >;
    assert IsSubgraph(G, NG);
    assert HasSparseRepOnly(NG);
    assert HasDenseRepOnly(G);
end for;
    



n := 100;
d := 0.1;
for i in [1..100] do

    //GetSeed();
    G := RandomGraph(n, d : SparseRep := true );
    E := EdgeSet(G);
    NE := {};
    for e in E do
	r := Random(0, 1);
	if r eq 1 then
	    Include(~NE, e);
	end if;
    end for;
    assert NE subset E;
    NG := Graph< n | NE : SparseRep := true >;
    assert IsSubgraph(G, NG);
    assert HasSparseRepOnly(NG);
    assert HasSparseRepOnly(G);
end for;


//clear;
//ShowActive();
//ShowActive();

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// The Tutte 8-cage
/// 2 ways of constructing the Tutte cage



//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(69632,true);
//SetMark(true);

K6 := CompleteGraph(6);
VEdges := {@ EdgeSet(K6)
          | e : e in EdgeSet(K6) @};
Factors := 
[ 
  { EdgeSet(K6) | {1, 2}, {5, 6}, {3, 4} },
  { EdgeSet(K6) | {4, 6}, {1, 2}, {3, 5} },
  { EdgeSet(K6) | {4, 5}, {1, 2}, {3, 6} },
  { EdgeSet(K6) | {1, 3}, {5, 6}, {2, 4} },
  { EdgeSet(K6) | {1, 3}, {4, 6}, {2, 5} },
  { EdgeSet(K6) | {4, 5}, {1, 3}, {2, 6} },
  { EdgeSet(K6) | {2, 3}, {5, 6}, {1, 4} },
  { EdgeSet(K6) | {1, 4}, {3, 6}, {2, 5} },
  { EdgeSet(K6) | {2, 6}, {1, 4}, {3, 5} },
  { EdgeSet(K6) | {2, 3}, {4, 6}, {1, 5} },
  { EdgeSet(K6) | {1, 5}, {3, 6}, {2, 4} },
  { EdgeSet(K6) | {1, 5}, {2, 6}, {3, 4} },
  { EdgeSet(K6) | {2, 3}, {4, 5}, {1, 6} },
  { EdgeSet(K6) | {2, 4}, {3, 5}, {1, 6} },
  { EdgeSet(K6) | {1, 6}, {2, 5}, {3, 4} }
]
;

LS := NearLinearSpace< VEdges | Factors >;
#Points(LS);
#Blocks(LS);

tutte1 := IncidenceGraph(LS);
Valence(tutte1);
assert IsBipartite(tutte1);
assert IsSymmetric(tutte1);

A := AutomorphismGroup(tutte1);
CompositionFactors(A);


////////////////////////////

G := PermutationGroup< 30 |
(1, 2)(3, 4)(5, 7)(6, 8)(9, 13)(10, 12)(11, 15)
(14, 19)(16, 23)(17, 22)(18, 21)(20, 27)
(24, 29)(25, 28)(26, 30),(1, 24, 28, 8)
(2, 9, 17, 22)(3, 29, 19, 15)(4, 5, 21, 25)
(6, 18, 7, 16)(10, 13, 30, 11)(12, 14)(20, 23)
(26, 27) >;
N1 := rep{ o : o in Orbits(Stabilizer(G, 1))
      | #o eq 3 };

tutte2 := Graph< 30 | <1, N1>^G >;
assert IsIsomorphic(tutte1, tutte2);
assert IsIsomorphic(A, G);

//clear;
//ShowActive();
//ShowActive();

	    
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// a family of projective planes (generalized triangles)

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);


q := 3;
P := FiniteProjectivePlane(q);
X := IncidenceGraph(P);

Order(X);
assert Valence(X) eq 4;
assert Diameter(X) eq 3;
assert Girth(X) eq 6;
assert IsSymmetric(X);




//clear;
//ShowActive();
//ShowActive();

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// a family of generalized quadrangles
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);



/////////////////    various useful functions 

function is_isotropic(F, H, u, v)
    // Is u * H * v^T = 0?

    return Matrix(F, 1, 4,  Eltseq(u)) * H *
    Transpose(Matrix(F, 1, 4,  Eltseq(v)))
    eq Matrix(F, 1, 1, [0]);
end function;

function one_subspaces(F, dim)
    // Finds 1-D subspaces of V(F, dim)
    
    S := Set(F);
    
    list := [ ];
    for i in [1..dim] do
        a := CartesianPower(S, dim - i);
        for c in a do
            m := [F | 0 : x in [1..i-1] ] cat [1] cat
            [c[x-i] : x in [i+1..dim] ];
            
            Append(~list, Matrix(F, 1, dim, m));
        end for;
    end for;
    
    return list;
end function;  

function two_subspaces(F, dim)
    // Finds 2-D subspaces of V(F, dim)
    
    S := Set(F);
    
    list := [ ];
    for i in [1..dim-1] do
        for j in [i+1..dim] do
            a := CartesianPower(S, 2*dim - i-j-1);
            for c in a do
                m := [F | 0 : x in [1..i-1] ]
                cat [1] cat
                [c[x-i] : x in [i+1..j-1] ] cat [0] cat
                [c[x-i-1] : x in [j+1..dim] ] cat 
                
                [ F | 0 : x in [1..j-1] ] cat [1] cat
                [ c[x + dim - i -j -1] : x in [j+1..dim] ];
                
                Append(~list, Matrix(F, 2, dim, m));
            end for;
        end for;
    end for;
    
    return list;
end function;  
////////////////////////////////////

q := 3;
F := GF(q);
V := VectorSpace(F, 4);

// Find an invertible matrix with
// diagonal elements 0 such that H^T = -H
H := GL(4, F)![0,2,2,1,1,0,2,2,1,1,0,0,2,1,0,0];
assert IsUnit(H);
assert Transpose(H) eq -H;

// Get points of the incidence structures:
// 1-D spaces of V
Points := {@ @};
Onesub := one_subspaces(F, 4); // not shown here
for m in Onesub do
    u := V!m[1];
    Include(~Points, sub< V | u>);
end for;
assert #Points eq (q^2 + 1) * (q + 1);

// Get lines: the 2-D isotropic spaces of V
Ls := [];
Twosub := two_subspaces(F, 4); // not shown here
for m in Twosub do
    u := V!m[1];
    v := V!m[2];
    // if u and v are isotropic then
    // include the subspace <u,v> in Lines
    // (function is_isotropic not shown here)
    if is_isotropic(F, H, u, v) then
	Include(~Ls, sub< V | u, v>);
    end if;
end for;

// Get the lines as blocks of points
Lines := [];
for l in Ls do
    B := {};
    for u in l do
	if u ne Zero(V) then
	    Include(~B, sub< V | u >);
	end if;
    end for;
    Include(~Lines, B);
end for;
assert #Lines eq (q^2 + 1) * (q + 1);

// The graph as an incidence graph
I := NearLinearSpace< Points | Lines >;
G := IncidenceGraph(I);

Order(G);
assert Valence(G) eq 4;
assert Diameter(G) eq 4;
assert Girth(G) eq 8;


//clear;
//ShowActive();
//ShowActive();

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// generalized hexagon

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);

// Get a (bipartite) cubic graph
VertexNeighours := [
{2, 8, 26}, {1, 3, 9}, {2, 4, 28}, {3, 5, 11},
{4, 6, 30}, {5, 7, 13}, {6, 8, 32}, {7, 15},
{2, 10, 16}, {9, 11, 17}, {4, 10, 12},
{11, 13, 19}, {6, 12, 14}, {13, 15, 21},
{8, 14, 16}, {15, 23}, {10, 18}, {17, 19, 25},
{12, 18, 20}, {19, 21, 27}, {14, 20, 22},
{21, 23, 29}, {16, 22, 24}, {17, 23, 31},
{18, 26}, {25, 27}, {20, 26, 28}, {27, 29},
{22, 28, 30}, {29, 31}, {24, 30, 32}, {31, 25} ];
Y := Graph< 32 | VertexNeighours >;

Order(Y);
assert IsBipartite(Y);
assert Valence(Y) eq 3;

// We'll need to add 94 (isolated) vertices
// (Trick in order to subdivide Y later)
AddVertices(~Y, 94);

// Find Y's 1-factors (there are 3 of them)
// Actually, the 1-factors' edges are ordered
// distance-wise.
// See Godsil's Royle p. 89 for more details,
// and the original paper.
Es := EdgeSet(Y);

F1 := [ Es |
{1, 8}, {17, 24}, {12, 13}, {28, 29},
{4, 5}, {20, 21}, {9, 16}, {25, 32},
{2, 3}, {18, 19}, {14, 15}, {30, 31},
{6, 7}, {22, 23}, {10, 11}, {26, 27} ];

F2 := [ Es |
{1, 26}, {5, 30}, {12, 19}, {16, 23},
{10, 17}, {14, 21}, {3, 28}, {7, 32},
{20, 27}, {24, 31}, {2, 9}, {6, 13},
{4, 11}, {8, 15}, {18, 25}, {22, 29} ];

F3 := [ Es |
{21, 22}, {1, 2}, {11, 12}, {31, 32},
{5, 6}, {17, 18}, {15, 16}, {27, 28},
{23, 24}, {3, 4}, {13, 14}, {25, 26},
{7, 8}, {19, 20}, {9, 10}, {29, 30} ];

// So, this gives us Y.
// Now, get X: Here too we add Order(Y) isolated
// vertices (the ones in EX)
// Forgetting these isolated vertices for now, X
// is the subgraph induced by the union of 
// $X_i(u)$, 0 <= i <= 5,
// of a regular generalized hexagon with valency 3.
// The $X_i(u)$ are the sets of vertices
// at distance i of vertex u.
EX := {@ "n" cat IntegerToString(n)
       : n in [1..32] @};
S := {@
"u",                           // X_0
"r", "g", "b",                 // X_1
"r0","r1","g0","g1","b0","b1", // X_2
"r00","r01","r10","r11",
"g00","g01","g10","g11",
"b00","b01","b10","b11",       // X_3
"r000","r001","r010","r011",
"r100","r101","r110","r111",
"g000","g001","g010","g011",
"g100","g101","g110","g111",
"b000","b001","b010","b011",
"b100","b101","b110","b111",   // X_4
"r0000","r0001","r0010","r0011",
"r0100","r0101","r0110","r0111",
"r1000","r1001","r1010","r1011",
"r1100","r1101","r1110","r1111",
"g0000","g0001","g0010","g0011",
"g0100","g0101","g0110","g0111",
"g1000","g1001","g1010","g1011",
"g1100","g1101","g1110","g1111",
"b0000","b0001","b0010","b0011",
"b0100","b0101","b0110","b0111",
"b1000","b1001","b1010","b1011",
"b1100","b1101","b1110","b1111" // X_5
@};

// Form the graph
X := Graph< EX join S | {
{"u","r"},{"u","g"},{"u","b"},
{"r", "r0"},{"r","r1"},
{"g", "g0"},{"g","g1"},
{"b", "b0"},{"b","b1"},
{"r0","r00"},{"r0","r01"},{"r1","r10"},{"r1","r11"},
{"g0","g00"},{"g0","g01"},{"g1","g10"},{"g1","g11"},
{"b0","b00"},{"b0","b01"},{"b1","b10"},{"b1","b11"},
{"r00","r000"},{"r00","r001"},
{"r01","r010"},{"r01","r011"},
{"r10","r100"},{"r10","r101"},
{"r11","r110"},{"r11","r111"},
{"g00","g000"},{"g00","g001"},
{"g01","g010"},{"g01","g011"},
{"g10","g100"},{"g10","g101"},
{"g11","g110"},{"g11","g111"},
{"b00","b000"},{"b00","b001"},
{"b01","b010"},{"b01","b011"},
{"b10","b100"},{"b10","b101"},
{"b11","b110"},{"b11","b111"},
{"r000","r0000"},{"r000","r0001"},
{"r001","r0010"},{"r001","r0011"},
{"r010","r0100"},{"r010","r0101"},
{"r011","r0110"},{"r011","r0111"},
{"r100","r1000"},{"r100","r1001"},
{"r101","r1010"},{"r101","r1011"},
{"r110","r1100"},{"r110","r1101"},
{"r111","r1110"},{"r111","r1111"},
{"g000","g0000"},{"g000","g0001"},
{"g001","g0010"},{"g001","g0011"},
{"g010","g0100"},{"g010","g0101"},
{"g011","g0110"},{"g011","g0111"},
{"g100","g1000"},{"g100","g1001"},
{"g101","g1010"},{"g101","g1011"},
{"g110","g1100"},{"g110","g1101"},
{"g111","g1110"},{"g111","g1111"},
{"b000","b0000"},{"b000","b0001"},
{"b001","b0010"},{"b001","b0011"},
{"b010","b0100"},{"b010","b0101"},
{"b011","b0110"},{"b011","b0111"},
{"b100","b1000"},{"b100","b1001"},
{"b101","b1010"},{"b101","b1011"},
{"b110","b1100"},{"b110","b1101"},
{"b111","b1110"},{"b111","b1111"} } >;

DistancePartition(VertexSet(X)!("u"));
#Sphere(VertexSet(X)!("u"), 1);
#Sphere(VertexSet(X)!("u"), 2);
#Sphere(VertexSet(X)!("u"), 3);
#Sphere(VertexSet(X)!("u"), 4);
#Sphere(VertexSet(X)!("u"), 5);

// Subdivide the edges of Y with the
// last 48 vertices of X.
// This is achieved correctly by using the order
// of a) the vertices of X and
// b) the edges of Y as ordered in the
// 3 1-factors
W := EdgeUnion(StandardGraph(X), Y);
F := F1 cat F2 cat F3;
v := 79;
for e in F do
    es := SetToSequence(EndVertices(e));
    e1 := Index(es[1]);
    e2 := Index(es[2]);
    RemoveEdge(~W, e1, e2);
    AddEdge(~W, e1, v);
    AddEdge(~W, e2, v);
    v +:= 1;
end for;

Order(W);
assert IsBipartite(W);
assert Valence(W) eq 3;
assert not IsTransitive(W);
assert IsEdgeTransitive(W);
assert not IsSymmetric(W);
assert Diameter(W) eq 6;
assert Girth(W) eq 12;

A := AutomorphismGroup(W);
CompositionFactors(A);
Orbits(A);

//clear;
//ShowActive();
//ShowActive();

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// a Moore graph: the Hoffman-Singleton graph

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);

Points := {@ s : s in Subsets({ 1 .. 7 }, 3) @};
heptad := { {1,2,4}, {2,3,5}, {3,4,6}, {4,5,7}, {5,6,1}, {6,7,2}, {7,1,3} };
A := AlternatingGroup(7);

// Get an orbit of heptad in A
Blocks := {};
for a in A do
    Include(~Blocks, heptad^a);
end for;

I := IncidenceStructure< Points | Blocks >;
HS1 := IncidenceGraph(I);

// Now triples are adjacent iff they are disjoint
for u in [1 .. 35] do
    for v in [u+1 .. 35] do
	if IsEmpty(Points[u] meet Points[v]) then
	    AddEdge(~HS1, u, v);
	end if;
    end for;
end for;

assert Valence(HS1) eq 7;
assert Diameter(HS1) eq 2;
assert Girth(HS1) eq 5;
assert IsTransitive(HS1);
assert IsSymmetric(HS1);


///////////////////
/// another way of constructing the HS graph:

pentagram := Graph< 5 |
{ {1,3}, {3,5}, {5,2}, {2,4}, {4,1} } >;
pentagon := PolygonGraph(5);
PP := pentagram join pentagon;
HS2 := &join [ PP : i in [1..5] ];
HS2 := HS2 + { { Vertices(HS2) |
           i + j*10, k*10 + 6 + (i+j*k) mod 5 } :
	   i in [1..5], j in [0..4], k in [0..4] };

assert IsIsomorphic(HS1, HS2);


//clear;
//ShowActive();
//ShowActive();
 
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// The Heawood graph

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);

// The Fano plane
F := Design< 2, 7 |
           {1,2,3}, {1,4,5}, {1,6,7}, {2,4,7},
	   {2,5,6}, {3,5,7}, {3,4,6} >;
F;
	   
G := IncidenceGraph(F);
assert Valence(G) eq 3;
assert IsDistanceRegular(G);
assert Diameter(G) eq 3;


// A Steiner triple system on 9 points
F := Design< 2, 9 |
           {1,2,8}, {1,4,7}, {2,3,4}, {2,7,9},
   	   {3,8,9}, {4,6,8}, {1,3,5}, {1,6,9},
	   {2,5,6}, {3,6,7}, {4,5,9}, {5,7,8} >;
F;
	   
G := BlockGraph(F);
assert Valence(G) eq 9;
assert IsDistanceRegular(G);
assert Diameter(G) eq 2;


//clear;
//ShowActive();
//ShowActive();

///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);


G := Graph<5 | { {1,2}, {2,3}, {3,4}, {4,5}, {5,1} }>; 

AssignLabels(VertexSet(G), ["a", "b", "a", "b", "b"]);
A, _, _, _, _, C1 := AutomorphismGroup(G);
A;
C1;


B, _, _, _, _, C2 := AutomorphismGroup(G : IgnoreLabels := true);
B;
C2;



C, _, _, _, _, C3 := AutomorphismGroup(G : Stabilizer :=
[ { VertexSet(G) | 1, 2 } ]);
C;
C3;


C4 := CanonicalGraph(G);
assert C1 eq C4;


//clear;
//ShowActive();
//ShowActive();



///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);


G1 := CompleteGraph(5);
G2 := CompleteGraph(5);
assert IsIsomorphic(G1, G2);


G1 := CompleteGraph(5);
AssignLabels(VertexSet(G1), ["a", "a", "b", "b", "b"]);
G2 := CompleteGraph(5);
assert not IsIsomorphic(G1, G2);


G1 := CompleteGraph(5);
AssignLabels(VertexSet(G1), ["b", "b", "b", "a", "a"]);
G2 := CompleteGraph(5);
AssignLabels(VertexSet(G2), ["a", "a", "b", "b", "b"]);
assert IsIsomorphic(G1, G2);



G1 := CompleteGraph(5);
AssignLabels(VertexSet(G1), ["a", "b", "b", "c", "c"]);
G2 := CompleteGraph(5);
AssignLabels(VertexSet(G2), ["a", "c", "b", "b", "c"]);
assert IsIsomorphic(G1, G2);


G1 := CompleteGraph(5);
G2 := CompleteGraph(5);
AssignLabels(VertexSet(G1), ["a", "a", "b", "b", "b"]);
AssignLabels(VertexSet(G2), ["a", "b", "a", "b", "a"]);
assert not IsIsomorphic(G1, G2);


G1 := CompleteGraph(5);
AssignLabels(VertexSet(G1), ["b", "b", "b", "a", "a"]);
G2 := CompleteGraph(5);
AssignLabels(VertexSet(G2), ["b", "b", "c", "c", "c"]);
assert not IsIsomorphic(G1, G2);


G1 := CompleteGraph(5);
AssignLabels(VertexSet(G1), ["b", "b", "b", "a", "a"]);
G2 := CompleteGraph(5);
AssignLabels(VertexSet(G2), ["b", "b", "a", "a", "a"]);
assert not IsIsomorphic(G1, G2);



//clear;
//ShowActive();
//ShowActive();

///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);


q := 9;
P := FiniteProjectivePlane(q);
X := IncidenceGraph(P);

Order(X);
assert Valence(X) eq 10;
assert Diameter(X) eq 3;
assert Girth(X) eq 6;
O1 := OrbitsPartition(X);
assert IsSymmetric(X);


Labels := [ "a" : i in [1..96] ];
#Labels;
AssignLabels(VertexSet(X), Labels);
O2 := OrbitsPartition(X);
assert not O2 eq O1;
assert not IsSymmetric(X);


//clear;
//ShowActive();
//ShowActive();

///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(62252,true);
//SetMark(true);


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
///// /home/paule/graph/multi/constr.m


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(72680,true);
//SetMark(true);

G := Graph< 5 | {1, 2}, {2, 3}, {3, 4}, {4, 5} > ;
GS := Graph< 5 | {1, 2}, {2, 3}, {3, 4}, {4, 5} :
SparseRep := true > ;
assert GS eq G;
assert UnderlyingGraph(G) eq G;
assert UnderlyingGraph(GS) eq GS;

GG := Graph< 5 | G >;
GGS := Graph< 5 | GS >;
assert GG eq G;
assert GGS eq GG;

DG := Digraph< 5 | G >;
DGS := Digraph< 5 | GS >;
assert DGS eq DG;
assert UnderlyingGraph(DG) eq G;
assert UnderlyingDigraph(G) eq DG;


MG := MultiGraph< 5 | G >;
MGS := MultiGraph< 5 | GS >;
assert MGS eq MG;
assert UnderlyingGraph(MG) eq G;
assert UnderlyingDigraph(MG) eq DG;
assert UnderlyingDigraph(MG) eq UnderlyingDigraph(G);

MG := MultiGraph< 5 | G, G >;
MGS := MultiGraph< 5 | GS, GS >;
assert MGS eq MG;
assert UnderlyingGraph(MG) eq G;

MD := MultiDigraph< 5 | G >;
MDS := MultiDigraph< 5 | GS >;
assert MDS eq MD;
assert UnderlyingGraph(MD) eq G;
assert UnderlyingDigraph(MD) eq DG;

MD := MultiDigraph< 5 | G, G >;
MDS := MultiDigraph< 5 | GS, GS >;
assert MDS eq MD;

NG := Network< 5 | G, G >;
NGS := Network< 5 | GS, GS >;
assert NGS eq NG;
assert UnderlyingGraph(NG) eq G;
assert IsSubgraph(NG, UnderlyingNetwork(G));
assert IsSubgraph(NG, UnderlyingNetwork(GS));

S := { e: e in EdgeSet(G) };
NGS := Network< 5 | S, S>;
assert NGS eq NG;

a, b, c := get_3_rand(S);

NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := [ < [i, j], 1 > : i, j in VertexSet(G) | i adj j ];
NGS := Network< 5 | S, S>;
assert NGS eq NG;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := { < [Index(i), Index(j)], 1 > : i, j in VertexSet(G)
| i adj j };
NGS := Network< 5 | S, S>;
assert NGS eq NG;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := { < [i, j], 2 > : i, j in VertexSet(G) | i adj j };
NGS := Network< 5 | S >;
assert IsSubgraph(NG, NGS);
//assert NGS eq NG;

assert HasDenseAndSparseRep(G);
assert HasSparseRepOnly(GS);

//clear;
//ShowActive();
//ShowActive();
////////////////////////////////////////////////////

G := Digraph< 5 | [1, 2], [2, 3], [3, 4], [4, 5] > ;
GS := Digraph< 5 | [1, 2], [2, 3], [3, 4], [4, 5] :
SparseRep := true > ;
assert GS eq G;
assert UnderlyingDigraph(G) eq G;
assert UnderlyingDigraph(GS) eq GS;


GG := Graph< 5 | G >;
GGS := Graph< 5 | GS >;
assert GGS eq GG;
assert UnderlyingGraph(G) eq GG;
assert UnderlyingGraph(GS) eq GGS;


DG := Digraph< 5 | G >;
DGS := Digraph< 5 | GS >;
assert G eq DG;
assert GS eq DGS;
assert DGS eq DG;

MG := MultiGraph< 5 | G >;
MGS := MultiGraph< 5 | GS >;
assert UnderlyingGraph(MG) eq GG;
assert MGS eq MG;
assert UnderlyingDigraph(GG) eq UnderlyingDigraph(GG);


MG := MultiGraph< 5 | G, G >;
MGS := MultiGraph< 5 | GS, GS >;
assert MGS eq MG;
assert UnderlyingDigraph(MG) eq UnderlyingDigraph(GG);

MD := MultiDigraph< 5 | G >;
MDS := MultiDigraph< 5 | GS >;
assert DG eq UnderlyingDigraph(MD);
assert DGS eq UnderlyingDigraph(MDS);
assert MDS eq MD;
assert UnderlyingDigraph(MD) eq G;

MD := MultiDigraph< 5 | G, G >;
MDS := MultiDigraph< 5 | GS, GS >;
assert MDS eq MD;
assert UnderlyingDigraph(MD) eq G;

NG := Network< 5 | G, G >;
NGS := Network< 5 | GS, GS >;
assert NGS eq NG;
assert UnderlyingDigraph(NG) eq G;
assert IsSubgraph(NG, UnderlyingNetwork(G));
assert IsSubgraph(NG, UnderlyingNetwork(GS));

S := { e : e in EdgeSet(G) };
NGS := Network< 5 | S, S>;
assert NGS eq NG;


a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := [ < [i, j], 1 > : i, j in VertexSet(G) | i adj j ];
NGS := Network< 5 | S, S>;
assert NGS eq NG;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := { < [Index(i), Index(j)], 1 > : i, j in VertexSet(G)
| i adj j };
NGS := Network< 5 | S, S>;
assert NGS eq NG;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := { < [i, j], 2 > : i, j in VertexSet(G) | i adj j };
NGS := Network< 5 | S >;
assert IsSubgraph(NG, NGS);
//assert NGS eq NG;


assert HasDenseAndSparseRep(G);
assert HasSparseRepOnly(GS);

//clear;
//ShowActive();
//ShowActive();

////////////////////////////////////////////////////

G := MultiGraph< 5 | {1, 2}, {2, 3}, {3, 4}, {4, 5},
{1, 2}, {2, 3}, {3, 4}, {4, 5} > ;
assert UnderlyingMultiGraph(G) eq G;

GG := Graph< 5 | G >;
assert UnderlyingGraph(G) eq GG;

DG := Digraph< 5 | G >;
assert UnderlyingGraph(DG) eq UnderlyingGraph(G);
assert UnderlyingDigraph(DG) eq DG;

MG := MultiGraph< 5 | G >;
assert MG eq G;
assert UnderlyingGraph(MG) eq UnderlyingGraph(G);

MG := MultiGraph< 5 | G, G >;
assert UnderlyingGraph(MG) eq UnderlyingGraph(G);
assert UnderlyingMultiGraph(MG) eq MG;

MD := MultiDigraph< 5 | G >;
assert UnderlyingDigraph(MD) eq DG;
assert UnderlyingGraph(MD) eq UnderlyingGraph(G);
assert UnderlyingMultiDigraph(MD) eq MD;

MD := MultiDigraph< 5 | G, G >;
assert UnderlyingGraph(MD) eq UnderlyingGraph(G);

NG := Network< 5 | G, G >;
assert UnderlyingGraph(NG) eq UnderlyingGraph(G);
assert IsSubgraph(NG, UnderlyingNetwork(G));

S := { e: e in EdgeSet(G) };
NGS := Network< 5 | S, S>;
assert NGS eq NG;


a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := [ < [i, j], 1 > : i, j in VertexSet(G) | i adj j ];
NG := Network< 5 | S, S>;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := { < [Index(i), Index(j)], 1 > : i, j in VertexSet(G)
| i adj j };
NGS := Network< 5 | S, S>;
assert NGS eq NG;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := { < [i, j], 2 > : i, j in VertexSet(G) | i adj j };
NGS := Network< 5 | S >;
assert IsSubgraph(NG, NGS);
//assert NGS eq NG;

assert HasSparseRepOnly(G);

//clear;
//ShowActive();
//ShowActive();
////////////////////////////////////////////////////

G := MultiDigraph< 5 | [1, 2], [2, 3], [3, 4], [4, 5],
[1, 2], [2, 3], [3, 4], [4, 5] > ;
assert UnderlyingMultiDigraph(G) eq G;

GG := Graph< 5 | G >;
assert GG eq UnderlyingGraph(G);

DG := Digraph< 5 | G >;
assert UnderlyingGraph(DG) eq UnderlyingGraph(G);
assert DG eq UnderlyingDigraph(G);


MG := MultiGraph< 5 | G >;
assert UnderlyingGraph(MG) eq UnderlyingGraph(G);

MG := MultiGraph< 5 | G, G >;
assert UnderlyingGraph(MG) eq UnderlyingGraph(G);

MD := MultiDigraph< 5 | G >;
assert MD eq G;
assert UnderlyingDigraph(MD) eq UnderlyingDigraph(G);

MD := MultiDigraph< 5 | G, G >;
assert UnderlyingDigraph(MD) eq UnderlyingDigraph(G);
assert UnderlyingMultiDigraph(MD) eq MD;

NG := Network< 5| G, G >;
assert UnderlyingDigraph(NG) eq UnderlyingDigraph(G);
assert UnderlyingGraph(NG) eq UnderlyingGraph(G);
assert IsSubgraph(NG, UnderlyingNetwork(G));


S := { e: e in EdgeSet(G) };
NGS := Network< 5 | S, S>;
assert NGS eq NG;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := [ < [i, j], 1 > : i, j in VertexSet(G) | i adj j ];
NG := Network< 5 | S, S>;
assert NG eq Network< 5 | G >;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := { < [Index(i), Index(j)], 1 > : i, j in VertexSet(G)
| i adj j };
NGS := Network< 5 | S, S>;
assert NGS eq NG;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := { < [i, j], 2 > : i, j in VertexSet(G) | i adj j };
NGS := Network< 5 | S >;
assert IsSubgraph(NG, NGS);
//assert NGS eq NG;

assert HasSparseRepOnly(G);

//clear;
//ShowActive();
//ShowActive();
////////////////////////////////////////////////////

G := Network< 5 | [1, 2], [2, 3], [3, 4], [4, 5],
[1, 2], [2, 3], [3, 4], [4, 5] > ;
assert UnderlyingNetwork(G) eq G;


GG := Graph< 5 | G >;
assert GG eq UnderlyingGraph(G);
assert UnderlyingDigraph(G) eq UnderlyingDigraph(G);

DG := Digraph< 5 | G >;
assert UnderlyingGraph(DG) eq UnderlyingGraph(G);


MG := MultiGraph< 5 | G >;
assert UnderlyingGraph(MG) eq GG;
assert UnderlyingGraph(MG) eq UnderlyingGraph(G);


MG := MultiGraph< 5 | G, G >;
assert UnderlyingGraph(MG) eq UnderlyingGraph(G);


MD := MultiDigraph< 5 | G >;
assert UnderlyingDigraph(MD) eq DG;
assert UnderlyingGraph(MD) eq UnderlyingGraph(G);
assert UnderlyingDigraph(MD) eq UnderlyingDigraph(G);

MD := MultiDigraph< 5 | G, G >;
assert UnderlyingGraph(MD) eq UnderlyingGraph(G);
assert UnderlyingDigraph(MD) eq UnderlyingDigraph(G);

NG := Network< 5| G, G >;
assert UnderlyingGraph(NG) eq UnderlyingGraph(G);
assert UnderlyingDigraph(NG) eq UnderlyingDigraph(G);

S := { e : e in EdgeSet(G) };
NGS := Network< 5 | S, S>;
assert NGS eq NG;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := [ < [i, j], 1 > : i, j in VertexSet(G) | i adj j ];
NG := Network< 5 | S, S>;
assert NG eq Network< 5 | G >;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := { < [Index(i), Index(j)], 1 > : i, j in VertexSet(G)
| i adj j };
NGS := Network< 5 | S, S>;
assert NGS eq NG;

a, b, c := get_3_rand(S);
NGS := Network< 5 | a, b, c >;
assert IsSubgraph(NG, NGS);

S := { < [i, j], 2 > : i, j in VertexSet(G) | i adj j };
NGS := Network< 5 | S >;
assert IsSubgraph(NG, NGS);
//assert NGS eq NG;


assert Network< 5 | G > eq G;
assert Network< 5 | NGS > eq NGS;


assert HasSparseRepOnly(G);

//clear;
//ShowActive();
//ShowActive();
////////////////////////////////////////////////////
//SetMark(true);

V := {@ "a", "b", "c", "d", "e" @};
G := Network< V |
< [ V[1], V[2] ], 2 >, < [ V[1], V[2] ], 3 >,
< [ V[1], V[3] ], 3 >, < [ V[1], V[5] ], 4 >,
< [ V[2], V[3] ], 3 >, < [ V[2], V[4] ], 2 >,
< [ V[4], V[5] ], 5 > >;

G;
Edges(G);
G + 1;
G - VertexSet(G)!5;
G + < [ VertexSet(G)!5, VertexSet(G)!3 ], 2 >;
G - EdgeSet(G)!< [ "a", "b" ], 1 >;
G - EdgeSet(G)!< [ 1, 2 ], 1 >;
G - { [VertexSet(G)!"a", VertexSet(G)!"b"] };

//clear;
//ShowActive();
//ShowActive();
////////////////////////////////////////////////////


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////  /home/paule/graph/multi/add_remove.m


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(72680,true);
//SetMark(true);

n := 10;
d := 0.5;

G := RandomGraph(n, d);
GS := Graph< Order(G) | G : SparseRep := true>;
m := n div 5;
/////////////////
H1 := G;
H2 := G;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    H1 := H1 - VertexSet(H1)!(n+1);
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
for v in [1..m] do
    H1 -:= VertexSet(H1)!(n+1);
    H2 -:= VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
H1 +:= m;
H2 := H2 + m;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 := H1 - S1;
H2 := H2 - S2;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 -:= S1;
H2 -:= S2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert H1 eq G;
assert H2 eq G;
/////////////////
H1 := GS;
H2 := GS;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    H1 := H1 - VertexSet(H1)!(n+1);
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq GS;
assert H2 eq GS;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
for v in [1..m] do
    H1 -:= VertexSet(H1)!(n+1);
    H2 -:= VertexSet(H2)!(n+1);
end for;
assert H1 eq GS;
assert H2 eq GS;
H1 +:= m;
H2 := H2 + m;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 := H1 - S1;
H2 := H2 - S2;
assert H1 eq GS;
assert H2 eq GS;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 -:= S1;
H2 -:= S2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert H1 eq GS;
assert H2 eq GS;
/////////////////
/////////////////
G := RandomDigraph(n, d);
GS := Digraph< Order(G) | G : SparseRep := true>;
m := n div 5;
/////////////////
H1 := G;
H2 := G;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    H1 := H1 - VertexSet(H1)!(n+1);
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
for v in [1..m] do
    H1 -:= VertexSet(H1)!(n+1);
    H2 -:= VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
H1 +:= m;
H2 := H2 + m;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 := H1 - S1;
H2 := H2 - S2;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 -:= S1;
H2 -:= S2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert H1 eq G;
assert H2 eq G;
/////////////////
H1 := GS;
H2 := GS;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    H1 := H1 - VertexSet(H1)!(n+1);
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq GS;
assert H2 eq GS;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
for v in [1..m] do
    H1 -:= VertexSet(H1)!(n+1);
    H2 -:= VertexSet(H2)!(n+1);
end for;
assert H1 eq GS;
assert H2 eq GS;
H1 +:= m;
H2 := H2 + m;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 := H1 - S1;
H2 := H2 - S2;
assert H1 eq GS;
assert H2 eq GS;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 -:= S1;
H2 -:= S2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert H1 eq GS;
assert H2 eq GS;
/////////////////
/////////////////
G := RandomGraph(n, d);
G := MultiGraph< Order(G) | G, G >;
m := n div 5;
/////////////////
H1 := G;
H2 := G;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    H1 := H1 - VertexSet(H1)!(n+1);
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
for v in [1..m] do
    H1 -:= VertexSet(H1)!(n+1);
    H2 -:= VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
H1 +:= m;
H2 := H2 + m;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 := H1 - S1;
H2 := H2 - S2;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 -:= S1;
H2 -:= S2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert H1 eq G;
assert H2 eq G;
/////////////////
/////////////////
G := RandomDigraph(n, d);
G := MultiDigraph< Order(G) | G, G >;
m := n div 5;
/////////////////
H1 := G;
H2 := G;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    H1 := H1 - VertexSet(H1)!(n+1);
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
for v in [1..m] do
    H1 -:= VertexSet(H1)!(n+1);
    H2 -:= VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
H1 +:= m;
H2 := H2 + m;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 := H1 - S1;
H2 := H2 - S2;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 -:= S1;
H2 -:= S2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert H1 eq G;
assert H2 eq G;
/////////////////
/////////////////
G := RandomDigraph(n, d);
G := MultiDigraph< Order(G) | G, G >;
c := n div 2;
t := n div 3;
E := [];
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v then
	    s := Random(0, t);
	    for i in [1..s] do
		cap := Random(0, c);
		Append(~E, <[u, v], c>);
	    end for;
	end if;
    end for;
end for;
G := Network< Order(G) | E >;
m := n div 5;
/////////////////
H1 := G;
H2 := G;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    H1 := H1 - VertexSet(H1)!(n+1);
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
for v in [1..m] do
    H1 -:= VertexSet(H1)!(n+1);
    H2 -:= VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
H1 +:= m;
H2 := H2 + m;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 := H1 - S1;
H2 := H2 - S2;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 +:= m;
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
H1 -:= S1;
H2 -:= S2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert H1 eq G;
assert H2 eq G;
//clear;
//ShowActive();
//ShowActive();
/////////////////
/////////////////
/////////////////
/////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(77032,true);
//SetTrace(77024,true);
//SetMark(true);
n := 10;
d := 0.5;

G := RandomGraph(n, d);
GS := Graph< Order(G) | G : SparseRep := true>;
/////////////////
EP := {};
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v and not u adj v and not {v,u} in EP
	    then
	    Include(~EP, {u,v});
	end if;
    end for;
end for;
H1 := G;
H2 := G;
for e in EP do
    H1 +:= e;
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    H1 -:= EdgeSet(H1)!e;
    H2 := H2 - EdgeSet(H2)!e;
end for;
assert H1 eq H2;
assert H1 eq G;
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
H1 -:= EP;
H2 := H2 - EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    H1 -:= {e};
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert H1 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
E1 := { EdgeSet(H1)!e : e in EP };
E2 := { EdgeSet(H2)!e : e in EP };
H1 -:= E1;
H2 := H2 - E2;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
/////////////////
H1 := GS;
H2 := GS;
for e in EP do
    H1 +:= e;
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    H1 -:= EdgeSet(H1)!e;
    H2 := H2 - EdgeSet(H2)!e;
end for;
assert H1 eq H2;
assert H1 eq GS;
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(G)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
H1 -:= EP;
H2 := H2 - EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, G);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    H1 -:= {e};
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert H1 eq G;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
E1 := { EdgeSet(H1)!e : e in EP };
E2 := { EdgeSet(H2)!e : e in EP };
H1 -:= E1;
H2 := H2 - E2;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
/////////////////
/////////////////
G := RandomDigraph(n, d);
GS := Digraph< Order(G) | G : SparseRep := true>;
/////////////////
EP := {};
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v and not u adj v 
	    then
	    Include(~EP, [u,v]);
	end if;
    end for;
end for;
H1 := G;
H2 := G;
for e in EP do
    H1 +:= e;
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    H1 -:= EdgeSet(H1)!e;
    H2 := H2 - EdgeSet(H2)!e;
end for;
assert H1 eq H2;
assert H1 eq G;
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
H1 -:= EP;
H2 := H2 - EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    H1 -:= {e};
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert H1 eq G;
/////////////////
H1 := GS;
H2 := GS;
for e in EP do
    H1 +:= e;
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    H1 -:= EdgeSet(H1)!e;
    H2 := H2 - EdgeSet(H2)!e;
end for;
assert H1 eq H2;
assert H1 eq GS;
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
assert IsComplete(H1);
assert IsComplete(H2);
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
H1 -:= EP;
H2 := H2 - EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    H1 -:= {e};
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert H1 eq GS;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
E1 := { EdgeSet(H1)!e : e in EP };
E2 := { EdgeSet(H2)!e : e in EP };
H1 -:= E1;
H2 := H2 - E2;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
/////////////////
/////////////////
n := 10;
d := 0.5;
G := RandomGraph(n, d);
G := MultiGraph< Order(G) | G, G >;
/////////////////
EP := [];
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v then
	    Append(~EP, {u, v});
	end if;
    end for;
end for;
H1 := G;
H2 := G;
for e in EP do
    H1 +:= e;
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 -:= SequenceToSet(EP);
H2 := H2 - SequenceToSet(EP);
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
for e in EP do
    H1 -:= {e};
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
for i in [1..10] do
    H1 -:= Random(EdgeSet(H1));
    H2 := H2 - Random(EdgeSet(H2));
end for;
H1 +:= EP;
H2 := H2 + EP;
S1 := {};
S2 := {};
for i in [1..10] do
    Include(~S1, Random(EdgeSet(H1)));
    Include(~S2, Random(EdgeSet(H2)));
end for;
H1 -:= S1;
H2 := H2 - S2;
/////////////////
/////////////////
n := 10;
d := 0.5;
G := RandomDigraph(n, d);
G := MultiDigraph< Order(G) | G, G >;
/////////////////
EP := [];
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v then
	    Append(~EP, [u,v]);
	end if;
    end for;
end for;
H1 := G;
H2 := G;
for e in EP do
    H1 +:= e;
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
H1 -:= SequenceToSet(EP);
H2 := H2 - SequenceToSet(EP);
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
for e in EP do
    H1 -:= {e};
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
for i in [1..10] do
    H1 -:= Random(EdgeSet(H1));
    H2 := H2 - Random(EdgeSet(H2));
end for;
H1 +:= EP;
H2 := H2 + EP;
S1 := {};
S2 := {};
for i in [1..10] do
    Include(~S1, Random(EdgeSet(H1)));
    Include(~S2, Random(EdgeSet(H2)));
end for;
H1 -:= S1;
H2 := H2 - S2;
/////////////////
/////////////////
n := 10;
d := 0.5;
G := RandomDigraph(n, d);
G := MultiDigraph< Order(G) | G, G >;
c := n div 2;
t := n div 3;
E := [];
for u in VertexSet(G) do
    for v in VertexSet(G) do
        if not u eq v then
            s := Random(0, t);
            for i in [1..s] do
                cap := Random(0, c);
                Append(~E, <[u, v], c>);
            end for;
        end if;
    end for;
end for;
G := Network< Order(G) | E >;
/////////////////
EP := {};
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v then
	    cap := Random(0, c);
	    Include(~EP, < [u, v], c >);
	end if;
    end for;
end for;
H1 := G;
H2 := G;
for e in EP do
    H1 +:= e;
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
ES := { t[1] :  t in EP };
H1 -:= ES;
H2 := H2 - ES;
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
for t in EP do
    H1 -:= {t[1]};
    H2 := H2 - {t[1]};
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
H1 +:= EP;
H2 := H2 + EP;
assert H1 eq H2;
for i in [1..10] do
    H1 -:= Random(EdgeSet(H1));
    H2 := H2 - Random(EdgeSet(H2));
end for;
H1 +:= EP;
H2 := H2 + EP;
S1 := {};
S2 := {};
for i in [1..10] do
    Include(~S1, Random(EdgeSet(H1)));
    Include(~S2, Random(EdgeSet(H2)));
end for;
H1 -:= S1;
H2 := H2 - S2;
//clear;
//ShowActive();
//ShowActive();
/////////////////
/////////////////
/////////////////
/////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(77032,true);
//SetTrace(77024,true);
//SetMark(true);

n := 10;
d := 0.5;

G := RandomGraph(n, d);
GS := Graph< Order(G) | G : SparseRep := true>;
m := n div 5;
/////////////////
H1 := G;
H2 := G;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
H2 := H2 - S2;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
L := [];
for i in [1..m] do
    Append(~L, IntegerToString(i));
end for;
for i in [1..m] do
    AddVertex(~H1, L[i]);
end for;
for i in [1..m] do
    assert IsLabelled(VertexSet(H1)!(n+i));
end for;
for i in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
end for;
assert not IsVertexLabelled(H1);
assert H1 eq G;
AddVertices(~H1, m, L);
for i in [1..m] do
    assert IsLabelled(VertexSet(H1)!(n+i));
end for;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
assert not IsVertexLabelled(H1);
assert H1 eq G;
/////////////////
H1 := GS;
H2 := GS;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq GS;
assert H2 eq GS;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
H2 := H2 - S2;
assert H1 eq GS;
assert H2 eq GS;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
L := [];
for i in [1..m] do
    Append(~L, IntegerToString(i));
end for;
for i in [1..m] do
    AddVertex(~H1, L[i]);
end for;
for i in [1..m] do
    assert IsLabelled(VertexSet(H1)!(n+i));
end for;
for i in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
end for;
assert not IsVertexLabelled(H1);
assert H1 eq G;
AddVertices(~H1, m, L);
for i in [1..m] do
    assert IsLabelled(VertexSet(H1)!(n+i));
end for;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
assert not IsVertexLabelled(H1);
assert H1 eq GS;
/////////////////
/////////////////
G := RandomDigraph(n, d);
GS := Digraph< Order(G) | G : SparseRep := true>;
m := n div 5;
/////////////////
/////////////////
H1 := G;
H2 := G;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
H2 := H2 - S2;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
L := [];
for i in [1..m] do
    Append(~L, IntegerToString(i));
end for;
for i in [1..m] do
    AddVertex(~H1, L[i]);
end for;
for i in [1..m] do
    assert IsLabelled(VertexSet(H1)!(n+i));
end for;
for i in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
end for;
assert not IsVertexLabelled(H1);
assert H1 eq G;
AddVertices(~H1, m, L);
for i in [1..m] do
    assert IsLabelled(VertexSet(H1)!(n+i));
end for;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
assert not IsVertexLabelled(H1);
assert H1 eq G;
/////////////////
H1 := GS;
H2 := GS;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq GS;
assert H2 eq GS;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
H2 := H2 - S2;
assert H1 eq GS;
assert H2 eq GS;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
L := [];
for i in [1..m] do
    Append(~L, IntegerToString(i));
end for;
for i in [1..m] do
    AddVertex(~H1, L[i]);
end for;
for i in [1..m] do
    assert IsLabelled(VertexSet(H1)!(n+i));
end for;
for i in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
end for;
assert not IsVertexLabelled(H1);
assert H1 eq G;
AddVertices(~H1, m, L);
for i in [1..m] do
    assert IsLabelled(VertexSet(H1)!(n+i));
end for;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
assert not IsVertexLabelled(H1);
assert H1 eq GS;
/////////////////
/////////////////
/////////////////
G := RandomGraph(n, d);
G := MultiGraph< Order(G) | G, G >;
m := n div 5;
/////////////////
H1 := G;
H2 := G;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
H2 := H2 - S2;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
/////////////////
/////////////////
G := RandomDigraph(n, d);
G := MultiDigraph< Order(G) | G, G >;
m := n div 5;
/////////////////
H1 := G;
H2 := G;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
H2 := H2 - S2;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
L := [];
for i in [1..m] do
    Append(~L, IntegerToString(i));
end for;
for i in [1..m] do
    AddVertex(~H1, L[i]);
end for;
for i in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
end for;
assert H1 eq G;
AddVertices(~H1, m, L);
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
assert H1 eq G;
/////////////////
/////////////////
G := RandomDigraph(n, d);
G := MultiDigraph< Order(G) | G, G >;
c := n div 2;
t := n div 3;
E := [];
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v then
	    s := Random(0, t);
	    for i in [1..s] do
		cap := Random(0, c);
		Append(~E, <[u, v], c>);
	    end for;
	end if;
    end for;
end for;
G := Network< Order(G) | E >;
m := n div 5;
/////////////////
H1 := G;
H2 := G;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
for v in [1..m] do
    RemoveVertex(~H1, VertexSet(H1)!(n+1));
    H2 := H2 - VertexSet(H2)!(n+1);
end for;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
AddVertices(~H1, m);
H2 := H2 + m;
assert H1 eq H2;
S1 := { VertexSet(H1)!(n+i) : i in [1..m] };
S2 := { VertexSet(H2)!(n+i) : i in [1..m] };
RemoveVertices(~H1, S1);
H2 := H2 - S2;
assert H1 eq G;
assert H2 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
//clear;
//ShowActive();
//ShowActive();
/////////////////
/////////////////
/////////////////
/////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(77032,true);
//SetTrace(77024,true);
//SetMark(true);
n := 10;
d := 0.5;

G := RandomGraph(n, d);
GS := Graph< Order(G) | G : SparseRep := true>;
/////////////////
EP := {};
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v and not u adj v and not {v,u} in EP
	    then
	    Include(~EP, {u,v});
	end if;
    end for;
end for;
H1 := G;
H2 := G;
for e in EP do
    AddEdge(~H1, SetToSequence(e)[1], SetToSequence(e)[2]);
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    RemoveEdge(~H1, EdgeSet(H1)!e);
    H2 := H2 - EdgeSet(H2)!e;
end for;
assert H1 eq H2;
assert H1 eq G;
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
RemoveEdges(~H1, EP);
H2 := H2 - EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    RemoveEdge(~H1, SetToSequence(e)[1], SetToSequence(e)[2]);
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert H1 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
E1 := { EdgeSet(H1)!e : e in EP };
E2 := { EdgeSet(H2)!e : e in EP };
RemoveEdges(~H1, E1);
H2 := H2 - E2;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
L := [];
for i in [1..10] do
    Append(~L, IntegerToString(i));
end for;
EPL := SetToSequence(EP);
EPL := [ EPL[i] : i in [1..10] ];
for i in [1..10] do
    e := EPL[i];
    AddEdge(~H1, SetToSequence(e)[1], SetToSequence(e)[2], L[i]);
    assert IsLabelled(EdgeSet(H1)!e);
end for;
assert IsSubgraph(UnderlyingGraph(H1), G);
for i in [1..10] do
    e := EPL[i];
    RemoveEdge(~H1, SetToSequence(e)[1], SetToSequence(e)[2]);
end for;
assert H1 eq G;
AddEdges(~H1, EPL, L);
for i in [1..10] do
    e := EPL[i];
    assert IsLabelled(EdgeSet(H1)!e);
end for;

assert IsSubgraph(UnderlyingGraph(H1), G);
RemoveEdges(~H1, { EdgeSet(H1)!e : e in EPL } );
assert H1 eq G;
/////////////////
H1 := GS;
H2 := GS;
for e in EP do
    AddEdge(~H1, SetToSequence(e)[1], SetToSequence(e)[2]);
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    RemoveEdge(~H1, EdgeSet(H1)!e);
    H2 := H2 - EdgeSet(H2)!e;
end for;
assert H1 eq H2;
assert H1 eq GS;
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
RemoveEdges(~H1, EP);
H2 := H2 - EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    RemoveEdge(~H1, SetToSequence(e)[1], SetToSequence(e)[2]);
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert H1 eq GS;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
E1 := { EdgeSet(H1)!e : e in EP };
E2 := { EdgeSet(H2)!e : e in EP };
RemoveEdges(~H1, E1);
H2 := H2 - E2;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
L := [];
for i in [1..10] do
    Append(~L, IntegerToString(i));
end for;
EPL := SetToSequence(EP);
EPL := [ EPL[i] : i in [1..10] ];
for i in [1..10] do
    e := EPL[i];
    AddEdge(~H1, SetToSequence(e)[1], SetToSequence(e)[2], L[i]);
    assert IsLabelled(EdgeSet(H1)!e);
end for;
assert IsSubgraph(UnderlyingGraph(H1), GS);
for i in [1..10] do
    e := EPL[i];
    RemoveEdge(~H1, SetToSequence(e)[1], SetToSequence(e)[2]);
end for;
assert H1 eq GS;
AddEdges(~H1, EPL, L);
for i in [1..10] do
    e := EPL[i];
    assert IsLabelled(EdgeSet(H1)!e);
end for;
assert IsSubgraph(UnderlyingGraph(H1), GS);
RemoveEdges(~H1, { EdgeSet(H1)!e : e in EPL } );
assert H1 eq GS;
/////////////////
/////////////////
G := RandomDigraph(n, d);
GS := Digraph< Order(G) | G : SparseRep := true>;
/////////////////
EP := {};
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v and not u adj v 
	    then
	    Include(~EP, [u,v]);
	end if;
    end for;
end for;
H1 := G;
H2 := G;
for e in EP do
    AddEdge(~H1, e[1], e[2]);
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    RemoveEdge(~H1, EdgeSet(H1)!e);
    H2 := H2 - EdgeSet(H2)!e;
end for;
assert H1 eq H2;
assert H1 eq G;
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
RemoveEdges(~H1, EP);
H2 := H2 - EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    RemoveEdge(~H1, e[1], e[2]);
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert H1 eq G;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
E1 := { EdgeSet(H1)!e : e in EP };
E2 := { EdgeSet(H2)!e : e in EP };
RemoveEdges(~H1, E1);
H2 := H2 - E2;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
L := [];
for i in [1..10] do
    Append(~L, IntegerToString(i));
end for;
EPL := SetToSequence(EP);
EPL := [ EPL[i] : i in [1..10] ];
for i in [1..10] do
    e := EPL[i];
    AddEdge(~H1, e[1], e[2], L[i]);
    assert IsLabelled(EdgeSet(H1)!e);
end for;
assert IsSubgraph(UnderlyingDigraph(H1), G);
for i in [1..10] do
    e := EPL[i];
    RemoveEdge(~H1, e[1], e[2]);
end for;
assert H1 eq G;
AddEdges(~H1, EPL, L);
for i in [1..10] do
    e := EPL[i];
    assert IsLabelled(EdgeSet(H1)!e);
end for;
assert IsSubgraph(UnderlyingDigraph(H1), G);
RemoveEdges(~H1, { EdgeSet(H1)!e : e in EPL } );
assert H1 eq G;
/////////////////
H1 := GS;
H2 := GS;
for e in EP do
    AddEdge(~H1, e[1], e[2]);
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    RemoveEdge(~H1, EdgeSet(H1)!e);
    H2 := H2 - EdgeSet(H2)!e;
end for;
assert H1 eq H2;
assert H1 eq GS;
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
RemoveEdges(~H1, EP);
H2 := H2 - EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
for e in EP do
    RemoveEdge(~H1, e[1], e[2]);
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert H1 eq GS;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
for i in [1..Order(GS)] do
    assert VertexSet(GS)!i eq VertexSet(H1)!i;
    assert VertexSet(GS)!i eq VertexSet(H2)!i;
end for;
assert IsComplete(H1);
assert IsComplete(H2);
E1 := { EdgeSet(H1)!e : e in EP };
E2 := { EdgeSet(H2)!e : e in EP };
RemoveEdges(~H1, E1);
H2 := H2 - E2;
assert H1 eq H2;
assert IsSubgraph(H1, GS);
assert IsSubgraph(H2, GS);
L := [];
for i in [1..10] do
    Append(~L, IntegerToString(i));
end for;
EPL := SetToSequence(EP);
EPL := [ EPL[i] : i in [1..10] ];
for i in [1..10] do
    e := EPL[i];
    AddEdge(~H1, e[1], e[2], L[i]);
    assert IsLabelled(EdgeSet(H1)!e);
end for;
assert IsSubgraph(UnderlyingDigraph(H1), GS);
for i in [1..10] do
    e := EPL[i];
    RemoveEdge(~H1, e[1], e[2]);
end for;
assert H1 eq GS;
AddEdges(~H1, EPL, L);
for i in [1..10] do
    e := EPL[i];
    assert IsLabelled(EdgeSet(H1)!e);
end for;
assert IsSubgraph(UnderlyingDigraph(H1), GS);
RemoveEdges(~H1, { EdgeSet(H1)!e : e in EPL } );
assert H1 eq GS;
/////////////////
/////////////////
n := 10;
d := 0.5;
G := RandomGraph(n, d);
G := MultiGraph< Order(G) | G, G >;
/////////////////
EP := [];
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v then
	    Append(~EP, {u, v});
	end if;
    end for;
end for;
/////////////////
H1 := G;
H2 := G;
for e in EP do
    AddEdge(~H1, SetToSequence(e)[1], SetToSequence(e)[2]);
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
RemoveEdges(~H1, SequenceToSet(EP));
H2 := H2 - SequenceToSet(EP);
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
for e in EP do
    RemoveEdge(~H1, SetToSequence(e)[1], SetToSequence(e)[2]);
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
for i in [1..10] do
    RemoveEdge(~H1, Random(EdgeSet(H1)));
    H2 := H2 - Random(EdgeSet(H2));
end for;
AddEdges(~H1, EP);
H2 := H2 + EP;
S1 := {};
S2 := {};
for i in [1..10] do
    Include(~S1, Random(EdgeSet(H1)));
    Include(~S2, Random(EdgeSet(H2)));
end for;
RemoveEdges(~H1, S1);
H2 := H2 - S2;
/////////////////
n := 10;
d := 0.5;
G := RandomDigraph(n, d);
G := MultiDigraph< Order(G) | G, G >;
/////////////////
EP := [];
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v then
	    Append(~EP, [u,v]);
	end if;
    end for;
end for;
H1 := G;
H2 := G;
for e in EP do
    AddEdge(~H1, e[1], e[2]);
end for;
for e in EP do
    H2 := H2 + e;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
RemoveEdges(~H1, SequenceToSet(EP));
H2 := H2 - SequenceToSet(EP);
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
for e in EP do
    RemoveEdge(~H1, e[1], e[2]);
    H2 := H2 - {e};
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
for i in [1..10] do
    RemoveEdge(~H1, Random(EdgeSet(H1)));
    H2 := H2 - Random(EdgeSet(H2));
end for;
AddEdges(~H1, EP);
H2 := H2 + EP;
S1 := {};
S2 := {};
for i in [1..10] do
    Include(~S1, Random(EdgeSet(H1)));
    Include(~S2, Random(EdgeSet(H2)));
end for;
RemoveEdges(~H1, S1);
H2 := H2 - S2;
/////////////////
/////////////////
n := 10;
d := 0.5;
G := RandomDigraph(n, d);
G := MultiDigraph< Order(G) | G, G >;
c := n div 2;
t := n div 3;
E := [];
for u in VertexSet(G) do
    for v in VertexSet(G) do
        if not u eq v then
            s := Random(0, t);
            for i in [1..s] do
                cap := Random(0, c);
                Append(~E, <[u, v], c>);
            end for;
        end if;
    end for;
end for;
G := Network< Order(G) | E >;
/////////////////
EP := {};
for u in VertexSet(G) do
    for v in VertexSet(G) do
	if not u eq v then
	    cap := Random(0, c);
	    Include(~EP, < [u, v], c >);
	end if;
    end for;
end for;
H1 := G;
H2 := G;
for t in EP do
    AddEdge(~H1, t[1][1], t[1][2], t[2]);
end for;
for t in EP do
    H2 := H2 + t;
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G);
assert IsSubgraph(H2, G);
for i in [1..Order(G)] do
    assert VertexSet(G)!i eq VertexSet(H1)!i;
    assert VertexSet(G)!i eq VertexSet(H2)!i;
end for;
ES := { t[1] :  t in EP };
RemoveEdges(~H1, ES);
H2 := H2 - ES;
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
for t in EP do
    RemoveEdge(~H1, t[1][1], t[1][2]);
    H2 := H2 - {t[1]};
end for;
assert H1 eq H2;
assert IsSubgraph(H1, G) or IsSubgraph(G, H1);
assert IsSubgraph(H2, G) or IsSubgraph(G, H2);
AddEdges(~H1, EP);
H2 := H2 + EP;
assert H1 eq H2;
for i in [1..10] do
    RemoveEdge(~H1, Random(EdgeSet(H1)));
    H2 := H2 - Random(EdgeSet(H2));
end for;
AddEdges(~H1, EP);
H2 := H2 + EP;
S1 := {};
S2 := {};
for i in [1..10] do
    Include(~S1, Random(EdgeSet(H1)));
    Include(~S2, Random(EdgeSet(H2)));
end for;
RemoveEdges(~H1, S1);
H2 := H2 - S2;
//clear;
//ShowActive();
//ShowActive();
/////////////////
/////////////////
/////////////////
/////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(77032,true);
//SetTrace(77024,true);
//SetMark(true);


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////// /home/paule/graph/multi/planar.m




////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//////// /home/paule/graph/multi/tri.m

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(12345,true);
//SetMark(true);


procedure make_multi(~G)
    
    //Size(G);
    for i in [1..10] do
	u := Random(1, Order(G));
	v := Random(1, Order(G));
	V := VertexSet(G);
	AddEdge(~G, V!u, V!v);
    end for;
    //Size(G);

end procedure;


// very interesting!!!
G := MultiGraph< 6 |
{1, 6}, {1, 2},
{2, 6}, {2, 4}, {2, 3},
{3, 4},
{4, 6}, {4, 5},
{5, 6} >;
make_multi(~G);

if not IsTriconnected(G) then
    TS, PS := Splitcomponents(G);
    assert #TS gt 1;
end if;





// Vo's graph
G := MultiGraph< 11 |
{1, 3}, {1, 4}, {1, 7}, {1, 11}, {1, 2},
{2, 4}, {2, 3},
{3, 4},
{4, 7}, {4, 11}, {4, 7}, {4, 5},
{5, 10}, {5, 9}, {5, 8}, {5, 6},
{6, 8}, {6, 7},
{7, 8},
{9, 11}, {9, 10},
{10, 11} >;
make_multi(~G);

if not IsTriconnected(G) then
    TS, PS := Splitcomponents(G);
    assert #TS gt 1;
end if;



// 2 triangles
G := MultiGraph< 4 |
{1, 4}, {1, 3}, {1, 2},
{2, 3},
{3, 4} >;
make_multi(~G);


if not IsTriconnected(G) then
    TS, PS := Splitcomponents(G);
    assert #TS gt 1;
end if;


// a singleton edge
G := MultiGraph< 2 | {1, 2} >;
make_multi(~G);
if not IsTriconnected(G) then
    TS, PS := Splitcomponents(G);
    assert #TS gt 1;
end if;




// HT's graph
G := MultiGraph< 13 |
{1, 4}, {1, 8}, {1, 12}, {1, 13}, {1, 2}, 
{2, 13}, {2, 3}, 
{3, 13}, {3, 4}, 
{4, 6}, {4, 7}, {4, 5}, 
{5, 7}, {5, 8}, {5, 6}, 
{6, 7},
{8, 11}, {8, 12}, {8, 9}, 
{9, 11}, {9, 12}, {9, 10}, 
{10, 12}, {10, 11} >;
make_multi(~G);


if not IsTriconnected(G) then
    TS, PS := Splitcomponents(G);
    assert #TS gt 1;
end if;



G := MultiGraph< 3 | {1, 2}, {2, 3}, {1, 3} >;
make_multi(~G);
if not IsTriconnected(G) then
    TS, PS := Splitcomponents(G);
    assert #TS gt 1;
end if;



// HT's graph
G := MultiGraph< 13 |
{1, 4}, {1, 8}, {1, 12}, {1, 13}, {1, 2}, 
{2, 13}, {2, 3}, 
{3, 13}, {3, 4}, 
{4, 6}, {4, 7}, {4, 5}, 
{5, 7}, {5, 8}, {5, 6}, 
{6, 7},
{8, 11}, {8, 12}, {8, 9}, 
{9, 11}, {9, 12}, {9, 10}, 
{10, 12}, {10, 11} >;
make_multi(~G);


if not IsTriconnected(G) then
    TS, PS := Splitcomponents(G);
    assert #TS gt 1;
end if;



//clear;
//ShowActive();
//ShowActive();

////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(12345,true);
//SetMark(true);

procedure make_multi(~G)
    
    //Size(G);
    for i in [1..10] do
	u := Random(1, Order(G));
	v := Random(1, Order(G));
	V := VertexSet(G);
	AddEdge(~G, V!u, V!v);
    end for;
    //Size(G);

end procedure;

////load "/home/paule/graph/tri/test.m";
//SetLogFile("/home/paule/graph/tri/quick"
//: Overwrite := true);

n := 7;
d := 0.3;
for i in [1..50] do
    //print "new graph", n, d;
    //GetSeed();
    G := RandomGraph(n, d : SparseRep := true);
    M := MultiGraph< n | G >;
    make_multi(~M);
    if not IsTriconnected(M) then
	TS, PS := Splitcomponents(M);
	assert #TS gt 1
	or not IsConnected(UnderlyingGraph(M));
    end if;
end for;
n := 7;
d := 0.4;
for i in [1..50] do
    //print "new graph", n, d;
    //GetSeed();
    G := RandomGraph(n, d : SparseRep := true);
    M := MultiGraph< n | G >;
    make_multi(~M);
    if not IsTriconnected(M) then
	TS, PS := Splitcomponents(M);
	assert #TS gt 1
	or not IsConnected(UnderlyingGraph(M));
    end if;
end for;
n := 10;
d := 0.3;
for i in [1..50] do
    //print "new graph", n, d;
    //GetSeed();
    G := RandomGraph(n, d : SparseRep := true);
    M := MultiGraph< n | G >;
    make_multi(~M);
    if not IsTriconnected(M) then
	TS, PS := Splitcomponents(M);
	assert #TS gt 1
	or not IsConnected(UnderlyingGraph(M));
    end if;
end for;


//clear;
//ShowActive();
//ShowActive();

/////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(12345,true);
//SetMark(true);


procedure make_multi(~G)
    
    //Size(G);
    for i in [1..10] do
	u := Random(1, Order(G));
	v := Random(1, Order(G));
	AddEdge(~G, VertexSet(G)!u, VertexSet(G)!v);
    end for;
    //Size(G);

end procedure;

//SetLogFile("/home/paule/graph/tri/quick"
//: Overwrite := true);


l := 7;
u := 100;
for i in [1..10] do

    n := Random(l, u);
    d := Random(2, 6);
    d /:= 10;

    //print "new graph", n, d;
    //GetSeed();
    G := RandomGraph(n, d : SparseRep := true);
    M := MultiGraph< n | G >;
    make_multi(~M);
    if not IsTriconnected(M) then
	TS, PS := Splitcomponents(M);
	assert #TS gt 1;
    end if;
end for;



//clear;
//ShowActive();
//ShowActive();







////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//////////// /home/paule/graph/multi/union.m


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(12345,true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";

//SetSeed(1, 0);
for n in [20..25] do

    //print ">>>>>>>>>>>>>   n", n;

    d := 0.5;
    c := 10;

    //GetSeed();
    G1 := RandomGraph(n, d);
    G2 := RandomGraph(n, d);
    H := G1 join G2;
    assert HasDenseRepOnly(H);
    assert not IsConnected(H);
    check_join(H, G1, G2);
    
    //GetSeed();
    G1 := RandomGraph(n, d);
    G2 := RandomGraph(n, d : SparseRep := true);
    H := G1 join G2;
    assert HasDenseRepOnly(H);
    assert not IsConnected(H);
    check_join(H, G1, G2);
    
    //GetSeed();
    G1 := RandomGraph(n, d : SparseRep := true);
    G2 := RandomGraph(n, d);
    H := G1 join G2;
    assert HasDenseRepOnly(H);
    assert not IsConnected(H);
    check_join(H, G1, G2);
    
    //GetSeed();
    G1 := RandomGraph(n, d : SparseRep := true);
    G2 := RandomGraph(n, d : SparseRep := true);
    H := G1 join G2;
    assert HasSparseRepOnly(H);
    assert not IsConnected(H);
    check_join(H, G1, G2);
    
    //////////////////////////////////////////
    
    //GetSeed();
    G1 := RandomDigraph(n, d);
    G2 := RandomDigraph(n, d);
    H := G1 join G2;
    assert HasDenseRepOnly(H);
    assert not IsWeaklyConnected(H);
    check_join(H, G1, G2);
    
    //GetSeed();
    G1 := RandomDigraph(n, d);
    G2 := RandomDigraph(n, d : SparseRep := true);
    H := G1 join G2;
    assert HasDenseRepOnly(H);
    assert not IsWeaklyConnected(H);
    check_join(H, G1, G2);
    
    //GetSeed();
    G1 := RandomDigraph(n, d : SparseRep := true);
    G2 := RandomDigraph(n, d);
    H := G1 join G2;
    assert HasDenseRepOnly(H);
    assert not IsWeaklyConnected(H);
    check_join(H, G1, G2);
    
    //GetSeed();
    G1 := RandomDigraph(n, d : SparseRep := true);
    G2 := RandomDigraph(n, d : SparseRep := true);
    H := G1 join G2;
    assert HasSparseRepOnly(H);
    assert not IsWeaklyConnected(H);
    check_join(H, G1, G2);
    
    //////////////////////////////////////////
    
    //GetSeed();
    G1 := rand_multi_graph(n, d);
    G2 := rand_multi_graph(n, d);
    H := G1 join G2;
    assert HasSparseRepOnly(H);
    check_join(H, G1, G2);
    
    //GetSeed();
    G1 := rand_multi_digraph(n, d);
    G2 := rand_multi_digraph(n, d);
    H := G1 join G2;
    assert HasSparseRepOnly(H);
    check_join(H, G1, G2);
    
    //GetSeed();
    G1 := rand_net(n, d, c, 3);
    G2 := rand_net(n, d, c, 3);
    H := G1 join G2;
    assert HasSparseRepOnly(H);
    check_join(H, G1, G2);

end for;




//clear;
//ShowActive();
//ShowActive();



////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////// /home/paule/graph/multi/degree.m


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetMark(true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";


//SetSeed(1, 0);
for n in [10..12] do
for i in [1..1] do


    d := 0.5;
    c := 10;

    //print "";
    //print ">>    n", n, "d", d, "c", c;

    //GetSeed();

    G := rand_graph(n, d, c);

    d5, u5 := MinimumDegree(G);
    d6, u6 := MaximumDegree(G);

    assert u5 in Alldeg(G, d5);
    assert u6 in Alldeg(G, d6);
    
    if IsDirected(G) then

	d1, u1 := MinimumInDegree(G);
	d2, u2 := MaximumInDegree(G);
	d3, u3 := MinimumOutDegree(G);
	d4, u4 := MaximumOutDegree(G);
	
	if IsSimple(G) then 
	    for v in Vertices(G) do
		assert InDegree(v) eq #InNeighbours(v);
		assert OutDegree(v) eq  #OutNeighbours(v);
	    end for;
	end if;
	
	for v in Vertices(G) do

	    assert Degree(v) eq InDegree(v) + OutDegree(v);

	    I := InNeighbours(v);
	    O := OutNeighbours(v);

	    m1 := 0;
	    for u in I do
		m1 +:= EdgeMultiplicity(u, v);
	    end for;
	    assert InDegree(v) eq m1;
	    
	    m2 := 0;
	    for u in O do
		m2 +:= EdgeMultiplicity(v, u);
	    end for;
	    assert OutDegree(v) eq m2;

	    m := 0;
	    for e in Edges(G) do
		if v in e then
		    m +:= 1;
		end if;
		if v eq EndVertices(e)[1]
		    and EndVertices(e)[1]
		    eq EndVertices(e)[2]
		    then m +:= 1;
		end if;
	    end for;
	    assert m eq m1 + m2;

	    I1 := [];
	    I2 := [];
	    for v1 in I do
		for v2 in O do
		    if not IsSimple(G) then
			I1 := I1 cat Edges(v1, v);
			I2 := I2 cat Edges(v, v2);
		    else
			I1 := I1 cat [ EdgeSet(G)![v1, v] ];
			I2 := I2 cat [ EdgeSet(G)![v, v2] ];
		    end if;
		end for;
	    end for;
	    for e1 in I1 do
		for e2 in I2 do
		    assert e1 adj e2;
		end for;
	    end for;
	    
	end for;

    else
	assert IsUndirected(G);
	
	if IsSimple(G) then 
	    for v in Vertices(G) do
		assert Degree(v) eq #Neighbours(v);
	    end for;
	end if;
	
	for v in Vertices(G) do

	    N := Neighbours(v);

	    m1 := 0;
	    for u in N do
		m1 +:= EdgeMultiplicity(v, u);
	    end for;
	    assert Degree(v) eq m1;

	    m := 0;
	    for e in Edges(G) do
		if v in e then
		    m +:= 1;
		end if;
	    end for;
	    assert m eq m1;

	    I1 := [];
	    for v1 in N do
		if not IsSimple(G) then
		    I1 := I1 cat Edges(v1, v);
		else
		    I1 := I1 cat [ EdgeSet(G)!{v1, v} ];
		end if;
	    end for;

	    for e1 in I1 do
		for e2 in I1 do
		    assert e1 adj e2;
		end for;
	    end for;
	    
	end for;
    end if;

end for;
end for;

//clear;
//ShowActive();
//ShowActive();





////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//////////  /home/paule/graph/multi/labels.m

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/multi/func.m";

for n in [10..12] do

    //print "n", n;
    //print "Graph", //GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    test_sup_labels(G);
    
    //print "n", n;
    //print "MultiGraph";

    G := MultiGraph< n | G, G >;
    test_sup_labels(G);

    //print "n", n;
    //print "Digraph", //GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    test_sup_labels(D);
    
    //print "n", n;
    //print "MultiDigraph";

    D := MultiDigraph< n | D, D >;
    test_sup_labels(D);

    //print "n", n;
    //print "Network";

    N := Network< n | D >;
    test_sup_labels(N);
    
end for;

//clear;
//ShowActive();
//ShowActive();


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(150952,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/multi/func.m";

for n in [15..15] do

    //print "n", n;
    //print "Graph", //GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    test_sup_labels_add_remove(G);
    
    //print "n", n;
    //print "MultiGraph", //GetSeed();;

    G := MultiGraph< n | G, G >;
    test_sup_labels_add_remove(G);

    //print "n", n;
    //print "Digraph", //GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    test_sup_labels_add_remove(D);
    
    //print "n", n;
    //print "MultiDigraph", //GetSeed();;

    D := MultiDigraph< n | D, D >;
    test_sup_labels_add_remove(D);

    //print "n", n;
    //print "Network", //GetSeed();;

    N := Network< n | D >;
    test_sup_labels_add_remove(N);
    
end for;

//clear;
//ShowActive();
//ShowActive();


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(150952,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/multi/func.m";

for n in [10..12] do

    //print "n", n;
    //print "Graph", //GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    test_sup_labels_eq(G);
    
    //print "n", n;
    //print "MultiGraph", //GetSeed();;

    G := MultiGraph< n | G, G >;
    test_sup_labels_eq(G);

    //print "n", n;
    //print "Digraph", //GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    test_sup_labels_eq(D);
    
    //print "n", n;
    //print "MultiDigraph", //GetSeed();;

    D := MultiDigraph< n | D, D >;
    test_sup_labels_eq(D);

    //print "n", n;
    //print "Network", //GetSeed();;

    N := Network< n | D >;
    test_sup_labels_eq(N);
    
end for;



//clear;
//ShowActive();
//ShowActive();






////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////// /home/paule/graph/multi/caps.m

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/multi/func_cap.m";

for n in [10..12] do

    //print "n", n;
    //print "Graph", //GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    test_sup_caps(G);
    
    //print "n", n;
    //print "MultiGraph";

    G := MultiGraph< n | G, G >;
    test_sup_caps(G);

    //print "n", n;
    //print "Digraph", //GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    test_sup_caps(D);
    
    //print "n", n;
    //print "MultiDigraph";

    D := MultiDigraph< n | D, D >;
    test_sup_caps(D);

    //print "n", n;
    //print "Network";

    N := Network< n | D >;
    test_sup_caps(N);
    
end for;

//clear;
//ShowActive();
//ShowActive();


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(150952,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/multi/func_cap.m";

for n in [15..15] do

    //print "n", n;
    //print "Graph", //GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    test_sup_caps_add_remove(G);
    
    //print "n", n;
    //print "MultiGraph", //GetSeed();;

    G := MultiGraph< n | G, G >;
    test_sup_caps_add_remove(G);

    //print "n", n;
    //print "Digraph", //GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    test_sup_caps_add_remove(D);
    
    //print "n", n;
    //print "MultiDigraph", //GetSeed();;

    D := MultiDigraph< n | D, D >;
    test_sup_caps_add_remove(D);

    //print "n", n;
    //print "Network", //GetSeed();;

    N := Network< n | D >;
    test_sup_caps_add_remove(N);
    
end for;

//clear;
//ShowActive();
//ShowActive();


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(150952,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/multi/func_cap.m";

for n in [10..12] do

    //print "n", n;
    //print "Graph", //GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    test_sup_caps_eq(G);
    
    //print "n", n;
    //print "MultiGraph", //GetSeed();;

    G := MultiGraph< n | G, G >;
    test_sup_caps_eq(G);

    //print "n", n;
    //print "Digraph", //GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    test_sup_caps_eq(D);
    
    //print "n", n;
    //print "MultiDigraph", //GetSeed();;

    D := MultiDigraph< n | D, D >;
    test_sup_caps_eq(D);

    //print "n", n;
    //print "Network", //GetSeed();;

    N := Network< n | D >;
    test_sup_caps_eq(N);
    
end for;



//clear;
//ShowActive();
//ShowActive();







////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//////////// /home/paule/graph/multi/weights.m


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/multi/func_weight.m";

for n in [10..12] do

    //print "n", n;
    //print "Graph", //GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    test_sup_weights(G);
    
    //print "n", n;
    //print "MultiGraph";

    G := MultiGraph< n | G, G >;
    test_sup_weights(G);

    //print "n", n;
    //print "Digraph", //GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    test_sup_weights(D);
    
    //print "n", n;
    //print "MultiDigraph";

    D := MultiDigraph< n | D, D >;
    test_sup_weights(D);

    //print "n", n;
    //print "Network";

    N := Network< n | D >;
    test_sup_weights(N);
    
end for;

//clear;
//ShowActive();
//ShowActive();


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(150952,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/multi/func_weight.m";

for n in [15..15] do

    //print "n", n;
    //print "Graph", //GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    test_sup_weights_add_remove(G);
    
    //print "n", n;
    //print "MultiGraph", //GetSeed();;

    G := MultiGraph< n | G, G >;
    test_sup_weights_add_remove(G);

    //print "n", n;
    //print "Digraph", //GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    test_sup_weights_add_remove(D);
    
    //print "n", n;
    //print "MultiDigraph", //GetSeed();;

    D := MultiDigraph< n | D, D >;
    test_sup_weights_add_remove(D);

    //print "n", n;
    //print "Network", //GetSeed();;

    N := Network< n | D >;
    test_sup_weights_add_remove(N);
    
end for;

//clear;
//ShowActive();
//ShowActive();


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(150952,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/multi/func_weight.m";

for n in [10..12] do

    //print "n", n;
    //print "Graph", //GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    test_sup_weights_eq(G);
    
    //print "n", n;
    //print "MultiGraph", //GetSeed();;

    G := MultiGraph< n | G, G >;
    test_sup_weights_eq(G);

    //print "n", n;
    //print "Digraph", //GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    test_sup_weights_eq(D);
    
    //print "n", n;
    //print "MultiDigraph", //GetSeed();;

    D := MultiDigraph< n | D, D >;
    test_sup_weights_eq(D);

    //print "n", n;
    //print "Network", //GetSeed();;

    N := Network< n | D >;
    test_sup_weights_eq(N);
    
end for;



//clear;
//ShowActive();
//ShowActive();






////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////////// /home/paule/graph/multi/decs.m

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetMark(true);


//load "/home/paule/graph/multi/func_decs.m";
for n in [10..20] do

    //print "n", n;
    //print "Graph", GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    check_un_decs(G);
    
    //print "n", n;
    //print "MultiGraph", GetSeed();

    G := MultiGraph< n | G, G >;
    check_un_decs(G);

    //print "n", n;
    //print "Digraph", GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    check_un_decs(D);
    
    //print "n", n;
    //print "MultiDigraph", GetSeed();

    D := MultiDigraph< n | D, D >;
    check_un_decs(D);
    
    //print "n", n;
    //print "Network", GetSeed();

    N := Network< n | D >;
    check_un_decs(N);

end for;

//clear;
//ShowActive();
//ShowActive();


//load "/home/paule/graph/multi/func_decs.m";
for n in [10..12] do

    //print "n", n;
    //print "Graph", //GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    check_decs(G);
    check_decs_eq(G);
    
    //print "n", n;
    //print "MultiGraph", //GetSeed();

    G := MultiGraph< n | G, G >;
    check_decs(G);
    check_decs_eq(G);

    //print "n", n;
    //print "Digraph", //GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    check_decs(D);
    check_decs_eq(D);
    
    //print "n", n;
    //print "MultiDigraph", //GetSeed();

    D := MultiDigraph< n | D, D >;
    check_decs(D);
    check_decs_eq(D);
    
    //print "n", n;
    //print "Network", //GetSeed();

    N := Network< n | D >;
    check_decs_eq(N);

end for;

//clear;
//ShowActive();
//ShowActive();



////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//////////  /home/paule/graph/multi/flow.m


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetMark(true);
//SetMark(true);


//load "/home/paule/graph/nf/test.m";


for n := 20 to 30 by 10 do

    d := 0.5;
    c := 10;

    //GetSeed();
    //print "";
    //print "network with n", n, "d", d, "c", c;

    N := rand_net(n, d, c, 3);
    D := copy_net(N);
    
    V := VertexSet(N);
    VD := VertexSet(D);
    
    source := Random(1, n);
    sink := source;
    while sink eq source do
	sink := Random(1, n);
    end while;
    assert not sink eq source;

    F, C := MaximumFlow(V!source, V!sink);
    F1 := MaximumFlow(VD!source, VD!sink);
    assert F1 eq F;

end for;

//clear;
//ShowActive();
//ShowActive();



//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetMark(true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";
    
for n in [10..12] do

    d := 0.5;
    c := 10;
    for i in [1..5] do
    
	//GetSeed();
	//print "";
	N := rand_net(n, d, c, 3);
	D := copy_net(N);
	
	//print "        network with n", n, "size", \
        Size(N), "d", RealField(4)!d;

	V := VertexSet(N);
	VD := VertexSet(D);
	
        F := 0;
        while F eq 0 do
            source, sink := get_2_rand_int(n);
            F := MaximumFlow(V!source, V!sink);
        end while;
        //print "s", source, "t", sink, "F", F;
	
	F, C := MaximumFlow([V!source], [V!sink]);
	F1 := MaximumFlow([VD!source], [VD!sink]);

	assert F1 eq F;

	d /:= 10;
    end for;
	
end for;

//clear;
//ShowActive();
//ShowActive();

////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetMark(true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";
   
    
for n := 10 to 20 by 10 do

    d := 0.6;
    c := 10;
    
	//GetSeed();
	//print "";
	N := rand_net(n, d, c, 3);
	D := copy_net(N);
	
        //print "        network with n", n, "size", \
        Size(N), "d", RealField(4)!d;

	s := Random(1, n-1);
	t := n - s;
	t := Random(1, t);
	assert t ge 1;
	
	V := VertexSet(N);
	VD := VertexSet(D);
	
	Vs := { Index(v) : v in V };
	S := [];
	SD := [];
	for i in [1..s] do
	    while true do
		x := Random(1, n);
		if x in Vs then
		    Exclude(~Vs, x);
		    Append(~S, V!x);
		    Append(~SD, VD!x);
		    break;
		end if;
	    end while;
	end for;
	
	T := [];
	TD := [];
	for i in [1..t] do
	    while true do
		x := Random(1, n);
		if x in Vs then
		    Exclude(~Vs, x);
		    Append(~T, V!x);
		    Append(~TD, VD!x);
		    break;
		end if;
	    end while;
	end for;
	
	F, C := MaximumFlow(S, T);
	F1 := MaximumFlow(SD, TD);
	assert F1 eq F;
	
	d -:= 0.1;
	
end for;

//clear;
//ShowActive();
//ShowActive();





////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
///////////////  /home/paule/graph/multi/contract.m

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetMark(true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";
//load "/home/paule/graph/multi/func_decs.m";

procedure check_contract(G, DECS)

    n := Order(G);
    
    //G := put_support(G);
    //G := put_labels(G);  //EdgeLabels(G);
    if DECS eq true then 
	G := put_weights(G); //EdgeWeights(G);
	G := put_caps(G);    //EdgeCapacities(G);
    end if;
    
    V := VertexSet(G);

    E := { EdgeSet(G) | };
    for nbre in [1..10] do
	e := Random(Edges(G));
	if Type(G) eq GrphUnd or Type(G) eq GrphDir then
	    Include(~E, e);
	else
	    u := InitialVertex(e);
	    v := TerminalVertex(e);
	    SE := Edges(u, v);
	    E := E join SequenceToSet(SE);
	end if;
    end for;
    
    H := InsertVertex(E);
    assert not IsSubgraph(H, G);

    SE := [EdgeSet(G) | ];
    /* this stupid thing is needed for proper ordering! */
    for e in E do
	Append(~SE, e);
    end for;
    for nn := #SE to 1 by -1 do
	e := SE[nn]; 
	u := InitialVertex(e); 
	H := Contract(VertexSet(H)!Index(u),
	VertexSet(H)!(n+nn));
    end for;
    assert IsSubgraph(H, G);

    E := { EdgeSet(G) | };
    for nbre in [1..10] do
	e := Random(Edges(G));
	Include(~E, e);
    end for;

    H := InsertVertex(E);

    SE := [EdgeSet(G) | ];
    /* this stupid thing is needed for proper ordering! */
    for e in E do
	Append(~SE, e);
    end for;
    for nn := #SE to 1 by -1 do
	e := SE[nn]; 
	u := InitialVertex(e); 
	H := Contract(VertexSet(H)!Index(u),
	VertexSet(H)!(n+nn));
    end for;
    assert IsSubgraph(H, G);

end procedure;



for n in [10..12] do

    //print "n", n;
    //print "Graph", //GetSeed();
    
    d := 0.5;
    G := RandomGraph(n, d : SparseRep := true);
    check_contract(G, false);
    check_contract(G, true);
    
    //print "n", n;
    //print "MultiGraph", //GetSeed();

    G := MultiGraph< n | G, G >;
    check_contract(G, false);
    check_contract(G, true);

    //print "n", n;
    //print "Digraph", //GetSeed();

    D := RandomDigraph(n, d : SparseRep := true);
    check_contract(G, false);
    check_contract(D, true);
    
    //print "n", n;
    //print "MultiDigraph", //GetSeed();

    D := MultiDigraph< n | D, D >;
    check_contract(G, false);
    check_contract(D, true);

end for;





//clear;
//ShowActive();
//ShowActive();











////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////////  /home/paule/graph/nf/vbsum.m


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetMark(true);


//load "/home/paule/graph/nf/test.m";
for n in [5..8] do

    G := EmptyGraph(n : SparseRep := true);
    cc, SS := VertexConnectivity(G);
    c, S := VertexConnectivity(G : Al := "Dinic");
    assert c eq cc;
    assert #S eq #SS;
    
    G := CompleteGraph(n);
    cc, SS := VertexConnectivity(G);
    c, S := VertexConnectivity(G : Al := "Dinic");
    assert c eq cc;
    assert #S eq #SS;
    check_separator(G, SS);
    check_separator(G, S);
    check_v_conn(G, cc);
    check_v_conn_dinic(G, cc);

end for;

//clear;
//ShowActive();
//ShowActive();


///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";

for n in [5..8] do
for i in [1..2] do

    d := 0.1;
    while d le 0.9 do
        
        for i in [1..1] do
            //print "new graph", n, RealField(4)!d;
            //GetSeed();
            G := RandomGraph(n, d : SparseRep := true);

            cc, SS := VertexConnectivity(G);
            c, S := VertexConnectivity(G : Al := "Dinic");
            assert c eq cc;
            assert #S eq #SS;
            check_separator(G, SS);
            check_separator(G, S);
            check_v_conn(G, cc);
            check_v_conn_dinic(G, cc);
        end for;

        d +:= 0.1;

    end while;

end for;
end for;

//clear;
//ShowActive();
//ShowActive();


///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetMark(true);


//load "/home/paule/graph/nf/test.m";


for n in [5..12] do

    G := EmptyDigraph(n : SparseRep := true);
    cc, SS := VertexConnectivity(G);
    c, S := VertexConnectivity(G : Al := "Dinic");
    assert c eq cc;
    assert #S eq #SS;
    check_separator(G, SS);
    check_separator(G, S);
    check_v_conn(G, cc);
    check_v_conn_dinic(G, cc);

    G := CompleteDigraph(n);
    cc, SS := VertexConnectivity(G);
    c, S := VertexConnectivity(G : Al := "Dinic");
    assert c eq cc;
    assert #S eq #SS;
    check_separator(G, SS);
    check_separator(G, S);
    check_v_conn(G, cc);
    check_v_conn_dinic(G, cc);

end for;

//clear;
//ShowActive();
//ShowActive();

///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";

for n in [10..12] do
for i in [1..2] do

    d := 0.1;
    while d le 0.9 do
        
        for i in [1..1] do
            //print "new graph", n, RealField(4)!d;
            //GetSeed();
            G := RandomDigraph(n, d : SparseRep := true);

            cc, SS := VertexConnectivity(G);
            c, S := VertexConnectivity(G : Al := "Dinic");
            assert c eq cc;
            assert #S eq #SS;
	    check_separator(G, SS);
	    check_separator(G, S);
            check_v_conn(G, cc);
            check_v_conn_dinic(G, cc);
        end for;

        d +:= 0.1;

    end while;

end for;
end for;

//clear;
//ShowActive();
//ShowActive();


///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";

for n in [5..8] do

    G := EmptyGraph(n : SparseRep := true);
    cc, SS := EdgeConnectivity(G); 
    c, S := EdgeConnectivity(G : Al := "Dinic");
    assert c eq cc;

    check_e_separator(G, SS);
    check_e_separator(G, S);
    check_e_conn(G, cc);
    check_e_conn_dinic(G, cc);
    
    G := CompleteGraph(n);
    cc, SS := EdgeConnectivity(G); 
    c, S := EdgeConnectivity(G : Al := "Dinic");
    assert c eq cc;

    check_e_separator(G, SS);
    check_e_separator(G, S);
    check_e_conn(G, cc);
    check_e_conn_dinic(G, cc);

end for;

//clear;
//ShowActive();
//ShowActive();


///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetMark(true);


//load "/home/paule/graph/nf/test.m";

for n in [10..12] do
for i in [1..2] do

    d := 0.1;
    while d le 0.9 do
        
        for i in [1..1] do
            //print "new graph", n, RealField(4)!d;
            //GetSeed();
            G := RandomGraph(n, d : SparseRep := true);

            cc, SS := EdgeConnectivity(G); 
            c, S := EdgeConnectivity(G : Al := "Dinic");
            assert c eq cc;
            
	    check_e_separator(G, SS);
	    check_e_separator(G, S);
            check_e_conn(G, cc);
            check_e_conn_dinic(G, cc);

        end for;

        d +:= 0.1;

    end while;

end for;
end for;

//clear;
//ShowActive();
//ShowActive();

///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";

for n in [5..8] do

    G := EmptyDigraph(n : SparseRep := true);
    cc, SS := EdgeConnectivity(G); 
    c, S := EdgeConnectivity(G : Al := "Dinic");
    assert c eq cc;
    check_e_conn(G, cc);
    check_e_conn_dinic(G, cc);
    
    G := CompleteDigraph(n);
    cc, SS := EdgeConnectivity(G); 
    c, S := EdgeConnectivity(G : Al := "Dinic");
    assert c eq cc;
    check_e_separator(G, SS);
    check_e_separator(G, S);
    check_e_conn(G, cc);
    check_e_conn_dinic(G, cc);

end for;

//clear;
//ShowActive();
//ShowActive();


///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";

for n in [10..12] do
for i in [1..2] do

    d := 0.1;
    while d le 0.9 do
        
        for i in [1..1] do
            //print "new graph", n, RealField(4)!d;
            //GetSeed();
            G := RandomDigraph(n, d : SparseRep := true);

            cc, SS := EdgeConnectivity(G); 
            c, S := EdgeConnectivity(G : Al := "Dinic");
            assert c eq cc;
	    check_e_separator(G, SS);
	    check_e_separator(G, S);
            check_e_conn(G, cc);
            check_e_conn_dinic(G, cc);

        end for;

        d +:= 0.1;

    end while;

end for;
end for;



//clear;
//ShowActive();
//ShowActive();

///////////////////////////////////////////////////////
//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";

for i in [1..5] do
    
    //GetSeed();
    n := Random(10, 100);
    m := Random(10, 100);
    //n := Random(100, 1000);
    //m := Random(100, 1000);
    d := m div 3;
    //d := 1;
    //print "", "n ", n, "m ", m, "d ", d;

    G := rand_bip(n, m, d);
    assert HasSparseRepOnly(G);

    assert IsBipartite(G);
    SS := Bipartition(G);
    
    t := Cputime();
    M := MaximumMatching(G);
    tt := RealField()!Cputime(t);
    //print "for 1First0Last  ", tt;
    check_matching(G, M);
    check_matching_dinic(G, M);
        
    t := Cputime();
    MM := MaximumMatching(G : Al := "Dinic");
    tt := RealField()!Cputime(t);
    //print "for Dinic  ", tt;
    assert #M eq #MM;
    check_matching(G, MM);
    check_matching_dinic(G, MM);

    assert HasSparseRepOnly(G);
    
end for;

//clear;
//ShowActive();
//ShowActive();


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//////////  /home/paule/graph/nf/test_dinic.m


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetMark(true);


//load "/home/paule/graph/nf/test.m";

for n:= 100 to 110  by 10 do 

    d := 0.1; j := 1;
    for i in [1..6] do
	
	//print "";
	//GetSeed();
	N := rand_unit_net(n, d, j);
	//print "        network with n", n, "size", \
	Size(N), "d", RealField(4)!d;

	V := VertexSet(N);
	F := 0;
	while F eq 0 do
	    source, sink := get_2_rand_int(n);
	    F := MaximumFlow(V!source, V!sink);
	end while;
	//print "s", source, "t", sink, "F", F;

	t := Cputime();
	F, C := MaximumFlow(V!source, V!sink);
	tt := RealField()!Cputime(t);
	//print "for PRHO", tt;
	    
	t := Cputime();
	FF, CC := MaximumFlow(V!source, V!sink :
	Al := "Dinic");
	tt := RealField()!Cputime(t);
	//print "for Dinic", tt;
	assert FF eq F;
	check_cut(N, source, sink, F, C);
	check_cut(N, source, sink, FF, CC);

	d /:= 10;
    end for;

end for;


//clear;
//ShowActive();
//ShowActive();


// dinic edge connectivity quite good
// on very low density graphs, d <= 0.01
// vertex connectivity is equivalent

n := 100;
while n le 140 do
	d := 0.01;
	for i in [1..4] do

	//GetSeed();
	    G := RandomGraph(n, d : SparseRep := true);
	    //print "";
	    //print "new graph", n, RealField(4)!d, \
	    " size ", Size(G);
	    
	    //print ""; //print "VertexConnectivity";
	    
	    t := Cputime();
	    c, S := VertexConnectivity(G);
	    tt := RealField()!Cputime(t);
	    //print "for PRLO", tt;

            t := Cputime();
	    cc, SS := VertexConnectivity(G :
	    Al := "Dinic");
	    //print "for Dinic", tt;

	    assert cc eq c;
	    assert #SS eq #S;

	    //print ""; //print "EdgeConnectivity";
	    
	    t := Cputime();
	    c, S := EdgeConnectivity(G);
	    tt := RealField()!Cputime(t);
	    //print "for PRLO", tt;
		
            t := Cputime();
	    cc, SS := EdgeConnectivity(G :
	    Al := "Dinic");
	    tt := RealField()!Cputime(t);
	    //print "for Dinic", tt;

            assert cc eq c;
	    assert #SS eq #S;

		//d /:= 10;
	end for;
    n +:= 20;
end while;

//clear;
//ShowActive();
//ShowActive();

//load "/home/paule/graph/nf/test.m";

for n:= 100 to 120  by 10 do 

    d := 0.1; j := 2; c := 3;
    for i in [1..3] do
	
	//print "";
	//GetSeed();
	N := rand_net(n, d,c,  j);
	//print "        network with n", n, "size", \
	Size(N), "d", RealField(4)!d;

	V := VertexSet(N);
	F := 0;
	while F eq 0 do
	    source, sink := get_2_rand_int(n);
	    F := MaximumFlow(V!source, V!sink);
	end while;
	//print "s", source, "t", sink, "F", F;

	t := Cputime();
	F, C := MaximumFlow(V!source, V!sink);
	tt := RealField()!Cputime(t);
	//print "for PRHO", tt;
	    
	t := Cputime();
	FF, CC := MaximumFlow(V!source, V!sink :
	Al := "Dinic");
	tt := RealField()!Cputime(t);
	//print "for Dinic", tt;
	assert FF eq F;
	check_cut(N, source, sink, F, C);
	check_cut(N, source, sink, FF, CC);

	d /:= 10;
    end for;

end for;


//clear;
//ShowActive();
//ShowActive();



////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////  /home/paule/graph/network/coerce.m

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetMark(true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";

//SetSeed(1, 0);

for n in [10..20] do

    d := 0.5;
    c := 10;

    //GetSeed();
    //print "";
    //print "network with n", n, "d", d, "c", c;

    N := rand_net(n, d, c, 3);
    check_sub(N);
    
    E := Edges(N);
    ES := EdgeSet(N);

    for e in E do
	assert e
	eq ES!<[EndVertices(e)[1], EndVertices(e)[2]], Index(e)>;
    end for;

    V := VertexSet(N);
    for u in V do
	for v in V do
	    if not u eq v and u adj v then

		c := Capacity(u, v);
		
		nc := Random(c + 1, c + 10);
		AssignCapacity(~N, u, v, nc);
		assert Capacity(VertexSet(N)!u, 
		VertexSet(N)!v) eq nc;
		
		AssignCapacity(~N, u, v, c);
		assert 
		Capacity(VertexSet(N)!u, VertexSet(N)!v) 
		eq c;

		ES := Edges(u, v);
		d := 0;
		for i in [1..#ES] do
		    e := ES[i];
		    ci := Capacity(e);

		    nci := Random(ci + 1, ci + 10);
		    AssignCapacity(~N, e, nci);
		    assert Capacity(EdgeSet(N)!e) eq nci;

		    d := nci - ci;
		    assert 
			Capacity(VertexSet(N)!u, 
			VertexSet(N)!v) eq c + d;

		    AssignCapacity(~N, e, ci);
		    assert Capacity(EdgeSet(N)!e) eq ci;
		    assert Capacity(VertexSet(N)!u,					VertexSet(N)!v) eq c;
		end for;
		assert Capacity(VertexSet(N)!u, 
			VertexSet(N)!v) eq c;
	    end if;
	end for;
    end for;
    
end for;

//clear;
//ShowActive();
//ShowActive();






////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////////  /home/paule/graph/network/contract.m

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetMark(true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";

//SetSeed(1, 0);
for n in [10..20] do

    d := 0.5;
    c := 10;

    //GetSeed();
    //print "";
    //print "network with n", n, "d", d, "c", c;

    N := rand_net(n, d, c, 3);
    V := VertexSet(N);

    E := { EdgeSet(N) | };
    for nbre in [1..10] do
	e := Random(Edges(N));
	u := EndVertices(e)[1];
	v := EndVertices(e)[2];
	SE := Edges(u, v);
	E := E join SequenceToSet(SE);
    end for;

    H := InsertVertex(E);
    assert not IsSubgraph(H, N);

    SE := [EdgeSet(N) | ];
    /* this stupid thing is needed for proper ordering! */
    for e in E do
	Append(~SE, e);
    end for;
    for nn := #SE to 1 by -1 do
	e := SE[nn]; 
	u := EndVertices(e)[1]; 
	H := Contract(VertexSet(H)!Index(u),
	VertexSet(H)!(n+nn));
    end for;
    assert IsSubgraph(H, N);

    E := { EdgeSet(N) | };
    for nbre in [1..10] do
	e := Random(Edges(N));
	Include(~E, e);
    end for;

    H := InsertVertex(E);

    SE := [EdgeSet(N) | ];
    /* this stupid thing is needed for proper ordering! */
    for e in E do
	Append(~SE, e);
    end for;
    for nn := #SE to 1 by -1 do
	e := SE[nn]; 
	u := EndVertices(e)[1]; 
	H := Contract(VertexSet(H)!Index(u),
	VertexSet(H)!(n+nn));
    end for;
    assert IsSubgraph(H, N);

end for;

//clear;
//ShowActive();
//ShowActive();





////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//////////////  /home/paule/graph/network/flow.m


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetMark(true);
//SetMark(true);


//load "/home/paule/graph/nf/test.m";
    
for n := 50 to 60 by 10 do

    d := 0.5;
    c := 10;

    //GetSeed();
    //print "";
    //print "network with n", n, "d", d, "c", c;

    N := rand_net(n, d, c, 3);
    V := VertexSet(N);
    source := Random(1, n);
    sink := source;
    while sink eq source do
	sink := Random(1, n);
    end while;
    assert not sink eq source;
    
    t := Cputime();
    F, C := MaximumFlow(V!source, V!sink);
    tt := RealField()!Cputime(t);
    //print "for PRLO", tt;


    t := Cputime();
    FF, CC := MaximumFlow(V!source, V!sink :
    Al := "Dinic");
    tt := RealField()!Cputime(t);
    //print "for Dinic", tt;
    assert FF eq F;
    check_cut(N, source, sink, F, C);
    check_cut(N, source, sink, FF, CC);

end for;

//clear;
//ShowActive();
//ShowActive();





////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//////////   /home/paule/graph/network/multi_st.m


//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetMark(true);
//SetMark(true);





for n in [10..20] do

    d := 0.5;
    c := 10;
    for i in [1..5] do
    
	//GetSeed();
	//print "";
	N := rand_net(n, d, c, 3);
        //print "        network with n", n, "size", \
        Size(N), "d", RealField(4)!d;

        V := VertexSet(N);
	F := 0;
	t := Cputime();
        while F eq 0 and Cputime(t) lt 150 do
            source, sink := get_2_rand_int(n);
	    F := MaximumFlow(V!source, V!sink);
        end while;
        //print "s", source, "t", sink, "F", F;
	
	F, C := MaximumFlow([V!source], [V!sink]);
	
	H := N + 1;
	H -:= VertexSet(H)!(Order(H));
	assert H eq N;
	
	FF, CC := MaximumFlow(VertexSet(H)!source,
	VertexSet(H)!sink);
	assert FF eq F;
	assert #C eq #CC;
	for i in [1..#C] do
	    assert Index(C[i]) eq Index(CC[i]);
	end for;
	check_cut(N, source, sink, FF, CC);

	d /:= 10;
    end for;
	
end for;

//clear;
//ShowActive();
//ShowActive();

////////////////////////////////////////////////////////

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetMark(true);
//SetMark(true);

//load "/home/paule/graph/nf/test.m";
   
    
for n := 10 to 30 by 10 do

    d := 0.6;
    c := 10;
    
	//GetSeed();
	//print "";
	N := rand_net(n, d, c, 3);
        //print "        network with n", n, "size", \
        Size(N), "d", RealField(4)!d;

	s := Random(1, n-1);
	t := n - s;
	t := Random(1, t);
	assert t ge 1;
	
	V := VertexSet(N);
	Vs := { Index(v) : v in V };
	S := [];
	for i in [1..s] do
	    while true do
		x := Random(1, n);
		if x in Vs then
		    Exclude(~Vs, x);
		    Append(~S, V!x);
		    break;
		end if;
	    end while;
	end for;
	
	T := [];
	for i in [1..t] do
	    while true do
		x := Random(1, n);
		if x in Vs then
		    Exclude(~Vs, x);
		    Append(~T, V!x);
		    break;
		end if;
	    end while;
	end for;
	
        //print "S ", S, "T ", T;
	
	F, C := MaximumFlow(S, T);
	check_multi_cut(N, S, T, F, C);
	
	d -:= 0.1;
	
end for;

//clear;
//ShowActive();
//ShowActive();







////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
///////////  home/paule/graph/euler/test.m



////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////  /home/paule/graph/cox/cox.m

/////// a few examples from Murray

M1 := SymmetricMatrix( [1, 3,1, 2,3,1] );
M2 := SymmetricMatrix( [1, 3,1, 3,2,1] );
IsCoxeterIsomorphic( M1, M2 );

R1 := RootDatum( "A3" );
R2 := RootDatum( "A3" : Isogeny := "SC" );
R1 eq R2;
IsIsomorphic( R1, R2 );

R := RootSystem( "B4" );  S := RootSystem( "C4" );
IsIsomorphic( R, S );
IsCartanEquivalent( R, S );

IsCoxeterIsomorphic( "A1A1", "D2" );
IsCoxeterIsomorphic( "B5", "C5" );
IsCartanEquivalent( "B5", "C5" );

C1 := Matrix( 2,2, [ 2,-2, -2,2 ] );
C2 := Matrix( 2,2, [ 2,-1, -5,2 ] );
IsCoxeterIsomorphic( C1, C2 );
IsCartanEquivalent( C1, C2 );


W1 := ReflectionGroup( "B3" );
W2 := ReflectionGroup( "C3" );
IsCoxeterIsomorphic( W1, W2 );
IsCartanEquivalent( W1, W2 );







////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
////////////////  /home/paule/graph/weights/test.m

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetTrace(79836,true);
//SetMark(true);


procedure test_consistency(G, FH)

    GetSeed();
    V := VertexSet(G);
    for u in V do
        if HasNegativeWeightCycle(u) then
            print "a negative cycle";
            return;
        end if;
    end for;
    
    GetSeed();
    M := AllPairsShortestPaths(G : UseFibonacciHeap := FH);
    
    n := Order(G);
    V := VertexSet(G);
    for u in V do
        D := Distances(u : UseFibonacciHeap := FH);
        VP := Geodesics(u : UseFibonacciHeap := FH);
        EP := Paths(u : UseFibonacciHeap := FH);
        
        for v in [1..n] do
            b1, d := Reachable(u, V!v
            : UseFibonacciHeap := FH);
            b2, g := GeodesicExists(u, V!v
            : UseFibonacciHeap := FH);
            b3, p := PathExists(u, V!v
            : UseFibonacciHeap := FH);

            assert b1 eq b2 and b2 eq b3;
            if b1 then
                assert d eq D[v] and d eq M[Index(u)][v];
                assert #g eq #p+1;
                w := 0;
                if IsEdgeWeighted(G) then
                    for e in p do
                        w +:= Weight(e);
                    end for;
                else
                    w := #p;
                end if;
                assert d eq w;
            end if;
        end for;
    end for;
    
end procedure;
    


procedure test_w(G)

    n := Order(G);
    
    for e in EdgeSet(G) do
        w := Random(1, n);
        d := Random(1, n);
        AssignWeight(~G, e, w/d);
    end for;

    d := 1.0 * Size(G)/Order(G);
    print "graph density", d;
    
    t := Cputime();
    test_consistency(UnderlyingGraph(G), false);
    test_consistency(G, false);
    tt := RealField()!Cputime(t);
    print "time for PQ", tt;

    t := Cputime();
    test_consistency(UnderlyingGraph(G), true);
    test_consistency(G, true);
    tt := RealField()!Cputime(t);
    print "time for FH", tt;
        
end procedure;
   
procedure test_allw(G, p)

    N := 2^32 - 1;
    P := Round(p * N);
    
    n := Order(G);

    NEG := false;
    for e in EdgeSet(G) do
        if Random(1, N) lt P then
            w := Random(-n, 0);
            d := Random(1, n);
            AssignWeight(~G, e, w/d);
            NEG := true;
        else
            w := Random(0, n);
            d := Random(1, n);
            AssignWeight(~G, e, w/d);
        end if;
    end for;

    if NEG then
        print "negative weights";
    end if;
    test_consistency(UnderlyingGraph(G), false);
    test_consistency(G, false);
    
end procedure;

for i in [1..10] do
    n := 5;
    d := 0.5;

    print "n", n;
    print "Graph"; //GetSeed();
    G := RandomGraph(n, d);
    test_w(G);

    print "n", n;
    print "MultiGraph"; //GetSeed();
    G := MultiGraph< n | G, G >;
    test_w(G);

    print "n", n;
    print "Digraph"; //GetSeed();
    D := RandomDigraph(n, d);
    test_w(D);

    print "n", n;
    print "MultiDigraph"; //GetSeed();
    D := MultiDigraph< n | D, D >;
    test_w(D);

    print "n", n;
    print "Network"; //GetSeed();
    N := Network< n | D >;
    test_w(N);
end for;




for n in [15..15] do

    d := (1.0)/n;

    print "n", n, "d", d;
    print "Graph"; //GetSeed();

    G := RandomGraph(n, d);
    test_w(G);
    
    print "n", n, "d", d;
    print "MultiGraph"; //GetSeed();

    G := MultiGraph< n | G, G >;
    test_w(G);

    print "n", n, "d", d;
    print "Digraph"; //GetSeed();

    D := RandomDigraph(n, d);
    test_w(D);
    
    print "n", n, "d", d;
    print "MultiDigraph"; //GetSeed();

    D := MultiDigraph< n | D, D >;
    test_w(D);

    print "n", n, "d", d;
    print "Network"; //GetSeed();

    N := Network< n | D >;
    test_w(N);
    
end for;



for i in [1..10] do
    n := 5;
    d := 0.5;

    print "n", n;
    print "Graph"; //GetSeed();
    G := RandomGraph(n, d);
    test_allw(G, 0.1);

    print "n", n;
    print "MultiGraph"; //GetSeed();
    G := MultiGraph< n | G, G >;
    test_allw(G, 0.1);

    print "n", n;
    print "Digraph"; //GetSeed();
    D := RandomDigraph(n, d);
    test_allw(D, 0.1);

    print "n", n;
    print "MultiDigraph"; //GetSeed();
    D := MultiDigraph< n | D, D >;
    test_allw(D, 0.1);

    print "n", n;
    print "Network"; //GetSeed();
    N := Network< n | D >;
    test_allw(N, 0.1);
end for;



for n in [15..15] do

    d := 0.5;

    print "n", n;
    print "Graph"; //GetSeed();
    G := RandomGraph(n, d);
    test_allw(G, 0.01);

    print "n", n;
    print "MultiGraph"; //GetSeed();
    G := MultiGraph< n | G, G >;
    test_allw(G, 0.01);

    print "n", n;
    print "Digraph"; //GetSeed();
    D := RandomDigraph(n, d);
    test_allw(D, 0.01);

    print "n", n;
    print "MultiDigraph"; //GetSeed();
    D := MultiDigraph< n | D, D >;
    test_allw(D, 0.01);

    print "n", n;
    print "Network"; //GetSeed();
    N := Network< n | D >;
    test_allw(N, 0.01);
end for;




//clear;
//ShowActive();
//ShowActive();
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////  /home/paule/graph/weights/tree.m


procedure test_tree(G)

    assert IsEdgeWeighted(G);
    V := VertexSet(G);
    E := EdgeSet(G);
    for u in V do
	t :=  Cputime();
	MT := MinimumWeightTree(u);
	tt := RealField()!Cputime(t);
	//print "time for PQ", tt;

	t :=  Cputime();
	MT2 := MinimumWeightTree(u :
	UseFibonacciHeap := true);
	tt := RealField()!Cputime(t);
	//print "time for FH", tt;
	//print "";

	ET := EdgeSet(MT);
	MW := 0;
	for e in ET do
	    MW +:= Weight(e);
	end for;
	ET2 := EdgeSet(MT2);
	MW2 := 0;
	for e in ET2 do
	    MW2 +:= Weight(e);
	end for;
	assert MW eq MW2;
	
	T := DFSTree(u);
	ET := EdgeSet(T);
	W := 0;
	for e in ET do
	    v := InitialVertex(e);
	    w := TerminalVertex(e);
	    if IsSimple(G) then
		W +:= Weight(E!EndVertices(e));
	    else
		W +:= Min([ Weight(edge) :
		edge in Edges(V!v, V!w) ]);
	    end if;
	end for;
	//MW, W;
	assert MW le W;
	
	T := BFSTree(u);
	ET := EdgeSet(T);
	W := 0;
	for e in ET do
	    v := InitialVertex(e);
	    w := TerminalVertex(e);
	    if IsSimple(G) then
		W +:= Weight(E!EndVertices(e));
	    else
		W +:= Min([ Weight(edge) :
		edge in Edges(V!v, V!w) ]);
	    end if;
	end for;
	//MW, W;
	assert MW le W;
    end for;
    
end procedure;

procedure test_tw(G, p)

    N := 2^32 - 1;
    P := Round(p * N);
    
    n := Order(G);

    NEG := false;
    for e in EdgeSet(G) do
        if Random(1, N) lt p then
            w := Random(-n, 0);
            d := Random(1, n);
            AssignWeight(~G, e, w/d);
            NEG := true;
        else
            w := Random(0, n);
            d := Random(1, n);
            AssignWeight(~G, e, w/d);
        end if;
    end for;

    if NEG then
	print "negative weights";
    end if;
    if HasNegativeWeightCycle(G) then
	print "a negative cycle";
	return;
    end if;
    
    test_tree(G);
    
end procedure;

for i in [1..10] do
    n := 5;
    d := 0.5;

    print "n", n;
    print "Graph";//, GetSeed();
    G := RandomGraph(n, d);
    test_tw(G, 0.01);
   
    print "n", n;
    print "MultiGraph";//, GetSeed();
    G := MultiGraph< n | G, G >;
    test_tw(G, 0.01);
end for;

for n in [15..20] do

    d := 0.5;

    print "n", n;
    print "Graph";//, GetSeed();
    G := RandomGraph(n, d);
    test_tw(G, 0.001);

    print "n", n;
    print "MultiGraph";//, GetSeed();
    G := MultiGraph< n | G, G >;
    test_tw(G, 0.001);

end for;

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
/////////  /home/paule/graph/multi/conn.m

//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(12345,true);
//SetMark(true);


//load "/home/paule/graph/nf/test.m";


for n := 50 to 80 by 5 do
    
    d := Random(1, 5);
    d /:= (10 * (n div 10 + 10));
    
    //print "n & d", n, d;

    //GetSeed();
    GG := rand_multi_graph(n, d);
    
    G := UnderlyingGraph(GG);

    assert IsBiconnected(GG) eq IsBiconnected(G);
    assert #Bicomponents(GG) eq #Bicomponents(G);
    assert {* #x : x in Bicomponents(GG) *} eq 
    {* #x : x in Bicomponents(G) *};
    assert { { Index(u) : u in x } :
    x in Bicomponents(GG) }
    eq { { Index(u) : u in x } : x in Bicomponents(G) };
     
    assert IsTriconnected(GG) eq IsTriconnected(G);
    assert #Splitcomponents(GG) eq #Splitcomponents(G);
    assert {* #x : x in Splitcomponents(GG) *} eq 
    {* #x : x in Splitcomponents(G) *};
     
    vv := VertexSet(GG)!1;
    v := VertexSet(G)!1;
    TT, _, _, DDFI := DFSTree(vv);
    T, _, _, DFI := DFSTree(v);
    assert { Index(v) : v in Vertices(TT) } eq
    { Index(v) : v in Vertices(T) };

    BB := BFSTree(vv);
    B := BFSTree(v);
    assert { Index(v) : v in Vertices(BB) } eq
    { Index(v) : v in Vertices(B) };

    if IsConnected(GG) then
	assert IsConnected(G);
	assert #CutVertices(GG) eq #CutVertices(G);
	assert
	(IsConnected(GG) and not IsBiconnected(GG))
	eq IsSeparable(GG);
	assert
	(IsConnected(G) and not IsBiconnected(G))
	eq IsSeparable(G);
 	SPGG := SpanningTree(GG);
	SPG := SpanningTree(G);
	assert Order(SPGG) eq Order(GG)
	and Order(SPG) eq Order(G)
	and Size(SPGG) eq Order(GG) - 1
	and Size(SPG) eq Order(G) - 1;
    end if;
    
    SPFGG := SpanningForest(GG);
    SPFG := SpanningForest(G);
    assert Order(SPFGG) eq Order(GG)
    and Order(SPFG) eq Order(G)
    and #Components(SPFGG) eq #Components(SPFG);

    vk := VertexConnectivity(GG);
    ek := EdgeConnectivity(GG);
    assert VertexConnectivity(GG) eq VertexConnectivity(G);
    assert EdgeConnectivity(GG) eq EdgeConnectivity(G);
    for k in [1..vk] do
	assert IsKVertexConnected(GG, k);
	assert IsKVertexConnected(G, k);
    end for;
    for k in [1..ek] do
	assert IsKEdgeConnected(GG, k);
	assert IsKEdgeConnected(G, k);
    end for;
    
end for;



//clear;
//ShowActive();
//ShowActive();



//SetHistorySize(0);
//SetPreviousSize(0);
//SetDelCheck(true);
//SetTrace(12345,true);
//SetMark(true);


//load "/home/paule/graph/nf/test.m";

for n := 50 to 100 by 5 do
    
    d := Random(1, 5);
    d /:= (10 * (n div 10 + 10));
    
    //print "n & d", n, d;

    //GetSeed();
    GG := rand_multi_digraph(n, d);
    
    G := UnderlyingDigraph(GG);

    assert IsWeaklyConnected(GG) eq IsWeaklyConnected(G);
    assert IsStronglyConnected(GG)
    eq IsStronglyConnected(G);
     
    vv := VertexSet(GG)!1;
    v := VertexSet(G)!1;
    TT, _, _, DDFI := DFSTree(vv);
    T, _, _, DFI := DFSTree(v);
    assert { Index(v) : v in Vertices(TT) } eq
    { Index(v) : v in Vertices(T) };

    BB := BFSTree(vv);
    B := BFSTree(v);
    assert { Index(v) : v in Vertices(BB) } eq
    { Index(v) : v in Vertices(B) };
    
    SPFGG := SpanningForest(GG);
    SPFG := SpanningForest(G);
    assert Order(SPFGG) eq Order(GG)
    and Order(SPFG) eq Order(G)
    and #StronglyConnectedComponents(SPFGG)
    eq #StronglyConnectedComponents(SPFG);

    vk := VertexConnectivity(GG);
    ek := EdgeConnectivity(GG);
    assert VertexConnectivity(GG) eq VertexConnectivity(G);
    assert EdgeConnectivity(GG) eq EdgeConnectivity(G);
    for k in [1..vk] do
	assert IsKVertexConnected(GG, k);
	assert IsKVertexConnected(G, k);
    end for;
    for k in [1..ek] do
	assert IsKEdgeConnected(GG, k);
	assert IsKEdgeConnected(G, k);
    end for;
    
end for;




//clear;
//ShowActive();
//ShowActive();


for i in [1..100] do

    n := Random(10, 20);
    m := Random(10, 20);
    G := BipartiteGraph(n, m);
    GG := MultiGraph< Order(G) | G, G >;
    assert IsBipartite(GG);
    assert { { Index(u) : u in x } :
    x in Bipartition(GG) }
    eq { { Index(u) : u in x } : x in Bipartition(G) };
    
    MMG := MaximumMatching(G);
    MMGG := MaximumMatching(GG);
    assert #MMG eq #MMGG;

end for;

