
--subtype coorng is integer range 1..9;
--type coords is array(1..2) of coorng;
--type cellseq is array(1..9) of coords;


separate( asud )

-- This proc finds Hidden-Quads:
procedure hiddenQuads( rcd: cellseq; 
	t1,t2,t3,t4, dt1,dt2,dt3,dt4: out coorng; 
	found: out boolean) is

type tracetype is array(coorng) of coorng;
 

 
-- Count the cells containing digit f
function d1( f: coorng ) return integer is
	kount: integer := 0;
begin
	for c in coorng loop
		if candidate( rcd(c)(1), rcd(c)(2) )(f) then
			kount:=kount+1;
		end if;
	end loop;
	return kount;
end d1;

-- Count the cells containing  f or s
function d2( f,s: coorng ) return integer is
	kount: integer := 0;
begin

	for c in coorng loop

		if 
			candidate( rcd(c)(1), rcd(c)(2) )(f)
			or
			candidate( rcd(c)(1), rcd(c)(2) )(s) 
		then
			kount:=kount+1;
		end if;

	end loop;

	return kount;

end d2;


-- Count the cells containing f or s or t
function d3( f,s,t: coorng ) return integer is
	kount: integer := 0;
begin

	for c in coorng loop

		if 
			candidate( rcd(c)(1), rcd(c)(2) )(f)
			or
			candidate( rcd(c)(1), rcd(c)(2) )(s) 
			or
			candidate( rcd(c)(1), rcd(c)(2) )(t) 
		then
			kount:=kount+1;
		end if;

	end loop;

	return kount;

end d3;





-- Count the cells containing f or s or t or u:
function d4( f,s,t,u: coorng; trace: out tracetype ) return integer is
	kount: integer := 0;
begin

	trace := (others=>1);

	-- temporary sanity check:
	--assert f /= s /= t /= u
	if f=s or f=t or f=u then --fail
		raise program_error;
	elsif s=t or s=u then --fail
		raise program_error;
	elsif t=u then --fail
		raise program_error;
	end if;


	for c in coorng loop

		if 
			candidate( rcd(c)(1), rcd(c)(2) )(f)
			or
			candidate( rcd(c)(1), rcd(c)(2) )(s) 
			or
			candidate( rcd(c)(1), rcd(c)(2) )(t) 
			or
			candidate( rcd(c)(1), rcd(c)(2) )(u) 
		then
			kount:=kount+1;
			trace(kount):=c; -- #cell in sequence
		end if;

	end loop;


	if kount=4 then -- temporary sanity check

		if trace(1)=trace(2) or trace(1)=trace(3) or trace(1)=trace(4) then
			raise program_error;

		elsif trace(2)=trace(3) or trace(2)=trace(4) then
			raise program_error;

		elsif trace(3)=trace(4) then
			raise program_error;

		end if;

	end if; --sanity check


	return kount;

end d4;





-- Count the candidate digits contained in the union
-- of First + Second + Third + 4th cells in "rcd".
function n4( f,s,t,u: coorng ) return integer is
	kount: integer := 0;
begin

	-- temporary sanity check:
	--assert f /= s /= t /= u
	if f=s or f=t or f=u then --fail
		raise program_error;
	elsif s=t or s=u then --fail
		raise program_error;
	elsif t=u then --fail
		raise program_error;
	end if;

	for d in coorng loop

		if 
			candidate( rcd(f)(1), rcd(f)(2) )(d)
			or
			candidate( rcd(s)(1), rcd(s)(2) )(d) 
			or
			candidate( rcd(t)(1), rcd(t)(2) )(d) 
			or
			candidate( rcd(u)(1), rcd(u)(2) )(d) 
		then
			kount:=kount+1;
		end if;

	end loop;

	return kount;

end n4;







	type used is array(coorng) of boolean;
	digUsed: used := (others=>false);

	n, k, i, j: integer;

	trace: tracetype;

begin --hiddenQuads

	found:=false; t1:=1; t2:=1; t3:=1; t4:=1;

	for first in coorng range 1..9 loop
	if not found then --outer

		n:=d1(first);
		if 2<=n and n<=4 then --proceed outer
		for second in coorng range first+1..9 loop
		if not found and d1(second)>1 then --middle


			k:=d2(first,second); -- #cells with f or s

			if k<=4 then --proceed inner

				for third in coorng range second+1..9 loop
				if not found and d1(third)>1 then --core

					i:=d3(first,second,third); -- #cells w/ f or s or t
					if i<=4 then --proceed

						for forth in coorng range third+1..9 loop
						if not found and d1(forth)>1 then

							j:=d4(first,second,third,forth,trace);
							-- j is #cells with {f,s,t,f}

							n:=n4(trace(1),trace(2),trace(3),trace(4));
							-- n is total #digits in Union of cells involved

							--if j=4 then --found a quad (naked+hidden) --6may23
							if j=4 and n>4 then --found a hidden quad

								found:=true;
								t1:=trace(1); t2:=trace(2); --cells involved
								t3:=trace(3); t4:=trace(4);
								dt1:=first; dt2:=second; --digits involved
								dt3:=third; dt4:=forth;

							end if; --j

						end if; --not found
						end loop; --forth

					end if;

				end if; --core
				end loop; --third

			end if; --proceed inner


		end if; --middle
		end loop; --second
		end if; --proceed outer

	end if; --outer
	end loop; --first



end hiddenQuads;

