
separate( asud )

-- Key-digit-Ramify
procedure kram( 
	c0: in coords; -- input Cell to search for contradictions
	bad: out s9;
	--0..9: 0=>NoContradictions, 1..9=>digit leads to contradictions

	badsell: out badcelltype; --list of empty cells
	numbad: out integer -- number of empty cells

	;
	forceoutput: in boolean := false

	) is --KeyCell Ramifications




procedure emptyHouse( bno, rno, cno : out s9 ) is
	empty, found: boolean := false;
begin

	bno:=0;
	rno:=0;
	cno:=0;
------------------------------------------------------------

	--check blocks
	for br in 0..2 loop
	for bc in 0..2 loop

	for d in 1..9 loop

		found:=false;
		for r in 0..2 loop
		for c in 0..2 loop
			if candidate(br*3+r+1,bc*3+c+1)(d) then found:=true; end if;
		end loop; --c
		end loop; --r
		if not found then
			empty:=true;
			bno := br*3+bc+1;
		end if;

	end loop; --d

	end loop; --bc
	end loop; --br

------------------------------------------------------------

	--check rows
	for r in 1..9 loop
	for d in 1..9 loop

		found:=false;
		for c in 1..9 loop
			if candidate(r,c)(d) then found:=true; end if;
		end loop; --c
		if not found then
			empty:=true;
			rno:=r;
		end if;

	end loop; --d
	end loop; --r

------------------------------------------------------------

	--check cols
	for c in 1..9 loop
	for d in 1..9 loop

		found:=false;
		for r in 1..9 loop
			if candidate(r,c)(d) then found:=true; end if;
		end loop; --c
		if not found then
			empty:=true;
			cno:=c;
		end if;

	end loop; --d
	end loop; --c

------------------------------------------------------------


end emptyHouse;



--returns list of empty cells found
function blankFound return boolean is
	empty, found: boolean := false;
begin
	for row in 1..9 loop
	for col in 1..9 loop --test each cell

		empty:=true;
		for dig in 1..9 loop --test each digit
		if candidate(row,col)(dig) then
			empty := false;
		end if;
		end loop; --dig
		if empty then 
			found:=true;
			numbad:=numbad+1;
			badsell(numbad)(1):=row;
			badsell(numbad)(2):=col;
		end if;

	end loop; --col
	end loop; --row
	return found;
end blankFound;

--update the candidate array per the initial asserted digit:
procedure ramify( dig: in i9; bad, bn,rn,cn: out s9) is
	changed: boolean;
begin --ramify

	numbad:=0;
	badsell:=(others=>(others=>0));

	loop
		flush; --addendum 30jul23
		findUnique(changed);
		exit when blankfound;
		exit when not changed;
		emptyHouse(bn,rn,cn);
		exit when bn>0 or rn>0 or cn>0;
	end loop;
	if numbad>0 then
		bad:=dig;
	elsif bn>0 or rn>0 or cn>0 then
		bad:=dig;
	else
		bad:=0;
	end if;

end ramify;



	k: integer := 0;
	dig: array(i9) of i9;
	dd: i9;
	--ok: boolean;
	k9: m9type; --copy of current m9 array (before perturbing)

	svm: m9type;
	svc,svn: candidatetype;

	boxnum, rownum, colnum: s9;


begin --kram

	for d in 1..9 loop --count candidates
		if candidate( c0(1), c0(2) )(d) then 
			k:=k+1;
			dig(k):=d; --list the candidates "alive" in this cell
		end if;
	end loop;


	pr:=c0(1);
	pc:=c0(2); --pick cell for highlighting

	svm:=m9;
	svn:=mandidate;
	svc:=candidate;
	--fullsavepuzzle(true); 
	--save to disk the candidate array 
	--which is temporarily overwritten.

	k9:=m9;

	bad:=0;
	for d in 1..k loop --------------------------------------main loop-----------------
	if bad=0 then

		--ok:=fullreadpuzzle(true); --restore candidate array, & m9
		m9:=svm;
		--mandidate:=svn;
		candidate:=svc;

		dd:=dig(d); --current candidate to consider

		--assert digit dd:
		for i in 1..9 loop
			candidate( c0(1), c0(2) )(i):=false;
		end loop;
		candidate( c0(1), c0(2) )(dd) := true;
		m9( c0(1), c0(2) ) := dd;


		set_unbounded_string(consoleBuf, "");

		hiliteKdel:=(others=>(others=>(others=>false))); --track deleted

		append(consoleBuf,crlf&" KeyCell test:"&crlf);
		append(consoleBuf," +");
		append(consoleBuf,i2st(dd));
		append(consoleBuf,"@(");
		append(consoleBuf,i2st(c0(1)));
		append(consoleBuf,",");
		append(consoleBuf,i2st(c0(2)));
		append(consoleBuf,"):");


		-- fully ramify assertion ############################################	
		flushDups( c0(1), c0(2) ); 
		ramify(dd, bad, boxnum,rownum,colnum); --see if contradictory


		if bad=0 then -- no contradiction; no output
			--new_line;
			--put("=========== No Problems Found Above... ===============");
			--new_line;
			--new_line;
			null;
			if forceoutput and d=k then
				put(consoleBuf); --delayed write
			end if;

		else --contradiction

			put(consoleBuf); --delayed write

			if numbad>0 then
			-------------------------------------------------

				new_line;
				put("Found ");
				put( i2st(numbad) );
				put(" Empty Cells @:");
				for i in 1..numbad loop
					put( " (" & i2st( badsell(i)(1) ) );
					put( "," & i2st( badsell(i)(2) ) );
					put( ")" );
				end loop;
				new_line;

				if k9(c0(1),c0(2))=bad then
					put_line(" Contradiction Reached!");
				else
					put( " Digit "& i2st(bad) & " @(" );
						put( i2st( c0(1) ) );
						put( "," & i2st( c0(2) ) );
					put( ") may be removed.");
					new_line;
				end if;

			-------------------------------------------------

			else -- empty house

				new_line;
				put("Found Missing Digit at ");

				if boxnum>0 then
					put(" Box:"); put(i2st(boxnum)); new_line;
				elsif rownum>0 then
					put(" Row:"); put(i2st(rownum)); new_line;
				elsif colnum>0 then
					put(" Col:"); put(i2st(colnum)); new_line;
				end if;

				put( " Digit "& i2st(bad) & " @(" );
					put( i2st( c0(1) ) );
					put( "," & i2st( c0(2) ) );
				put( ") may be removed.");
				new_line;

			end if;

			-------------------------------------------------

		end if;

	end if; --bad=0
	end loop; --d --------------------------------------end main loop--------------


	blu9 := m9; --hold resulting m9 after kram exits

	--ok:=fullreadpuzzle(true); --restore from disk: candiate array + m9
	candidate:=svc;
	mandidate:=svn;
	m9:=svm;


end kram;

