cBase := func<P | Order(Stabilizer(P, Base(P))) ne 1>;

dEltBim := func<P, x | Base(P) eq [] or x ne Permutation(P, BaseImage(x))>;
eEltBim := func<P, x | Base(P)^x ne BaseImage(x)>;

cBlSys := function(P)
/*
Test block images.
*/
    b := MinimalPartitions(P);
    for i := 1 to #b do
	for x in Generators(P) do
	    mark_sweep;
	    r := #(Rep(b[i])^x meet Rep(b[i]));
	    if (r ne 0) and (r ne #(Rep(b[i]))) then
		return true;
	    end if;
	end for;
    end for;
    return false;
end function;

cConHom := func<P, i | OrbitKernel(P, i) ne Stabilizer(P, [x : x in Orbit(P,i)])
		    or OrbitKernel(P,i) ne Kernel(OrbitAction(P, Orbit(P, i)))>;

eBlHom := function(P)
/*
Calculate and compare blocks kernel.
WARNING: assumes orbit of each block system covers {x:1<=x<=degree}.
*/
    bs := MinimalPartitions(P);
    for i := 1 to #bs do
	bq := Rep(bs[i])^P;
	f, Im, K := BlocksAction(P, bs[i]);
	M := P;
	for bqj in bq do
	    mark_sweep;
	    M := M meet Stabilizer(P, bqj);
	end for;
	if K ne M or K ne BlocksKernel(P, bs[i]) or Im ne Image(f) or
	      K ne Kernel(f) or Im ne f(P) or Im ne BlocksImage(P, bs[i]) then
	    return true;
	end if;
    end for;
    return false;
end function;

bCycStr := function(x)
/*
Test order correct.
*/
    c := CycleStructure(x);
    ord := 1;
    for i := 1 to #c do
	mark_sweep;
	ord := LCM(ord, c[i][1]);
    end for;
    return ord ne Order(x);
end function;

cCycStr := func<x, y | CycleStructure(x) ne CycleStructure(x^y)>;

eEven := function(x)
/*
Calculate and compare for evenness.
*/
    c := CycleStructure(x);
    evn := 0;
    for i := 1 to #c do
	mark_sweep;
	if c[i][1] mod 2 eq 0 then
	    evn := (evn + c[i][2]) mod 2;
	end if;
    end for;
    return (evn eq 0) ne IsEven(x);
end function;

// PANIC: don't use when fix(x) eq NULL!!
bFix := func<x | Fix(x)^x ne Fix(x)>;

cFix := function(G, x)
/*
Check all points (fairly small degree).
*/
    for i := 1 to Degree(G) do
	mark_sweep;
	if (i^x eq i) ne (i in Fix(x)) then
	    return true;
	end if;
    end for;
    return false;
end function;

eFrob := function(P)
/*
Is P a frobenius group? For small degree only.
*/
    if not IsTransitive(P) or IsRegular(P) then
	return IsFrobenius(P);
    end if;
    for i := 1 to Degree(P) do
	for j := i+1 to Degree(P) do
	    mark_sweep;
	    if Order(Stabilizer(P, [i,j])) ne 1 then
		return IsFrobenius(P);
	    end if;
	end for;
    end for;
    return not IsFrobenius(P);
end function;

cStGen := function(P)
/*
Check strong generators.  For groups of small base.
*/
    S := StrongGenerators(P);
    b := Base(P);
    while #b gt 1 do
	mark_sweep;
	Prune(~b);
	G := Stabilizer(P, b);
	if sub<P | {s : s in S | s in G}> ne G then
	    return true;
	end if;
    end while;
    return sub<P | {s : s in S | s in P}> ne P;
end function;

eSemireg := function(P, S_orig)
/*
Determine semiregularity P. Fairly small degree.
*/
    S := OrbitClosure(P, S_orig);
    orb := Orbits(P);
    for i := 1 to #orb do
	mark_sweep;
	if Rep(orb[i]) in S then
	    if Setseq(S)^Stabilizer(P, Rep(orb[i])) ne {Setseq(S)} then
		return IsSemiregular(P, S);
	    end if;
	end if;
    end for;
    return not IsSemiregular(P, S);
end function;

cRegular := func<P | IsRegular(P) ne
		    (IsTransitive(P) and Order(Stabilizer(P, 1)) eq 1)>;

cPrimitive := func<P | IsPrimitive(P) ne (#MinimalPartitions(P) eq 0)>;

cNSGen := func<P | Nsgens(P) ne #StrongGenerators(P)>;

cTnstv := func<P | (#(1^P) eq Degree(P)) ne IsTransitive(P)>;

bPtStab := func<P, x | x^Stabilizer(P, x) ne {x}>;

bSeStab := func<P, S | S^Stabilizer(P, S) ne {S}>;

bPtOrb := func<P, x | Orbit(P, x) ne x^P>;

cPtOrb := function(P, x)
/*
Calculate and compare orbit.
*/
    Y := Support(P);
    a := {Y | x};
    b := {Y | };
    while #a ne 0 do
	mark_sweep;
	b join:= a;
	new := {Y | };
	for z in a do
	    for y in Generators(P) do
		if not z^y in b then
		    Include(~new, z^y);
		end if;
	    end for;
	end for;
	a := new;
    end while;
    return b ne Orbit(P, x);
end function;

bSeOrb := func<P, S | Orbit(P, S) ne S^P>;

bOrbs := function(P)
/*
Ensure orbits partition.  Small degree only.
*/
    o := Orbits(P);
    A := {};
    B := 0;
    for i := 1 to #o do
	mark_sweep;
	if Orbit(P, Rep(o[i])) ne o[i] then
	    return true;
	end if;
	if Orbit(P, Rep(o[i])) ne Rep(o[i])^P then
	    return true;
	end if;
	A join:= {x : x in Orbit(P, Rep(o[i]))};
	B +:= #o[i];
    end for;
    return #A ne Degree(P) or B ne Degree(P);
end function;
