/*

File BroadeningSearch.m

This type of search is depth first with iterative broadening.

*/

#import <appkit/appkit.h>

#import "BroadeningSearch.h"


/* 行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行  */


#define variable(i)		([variables  objectAt: i])


/* 行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行  */


@implementation BroadeningSearch


- free
{
	free(branches);
	return [super  free];
}


- (BOOL) startSearch: (id) theVariables
{
	branches = (int *) malloc(sizeof(int) * [theVariables  count]);
	bound = 1;
	missedSome = NO;
	
	return [super  startSearch: theVariables];
}


- (BOOL) step
{
	if (ok)
	{
		[self  findBest];
		branches[next] = 0;
	}
	
	ok = ((branches[next] != bound) && [self  fill: variable(next)]);
	if (!ok)
	{
		if ([self  backup] == NO) return [self  done];
	}
	
	else
	{
		branches[next]++;
		if (++next == count) return [self  done];
	}
	
	return YES;
}


- (BOOL) backup
{
	if (branches[next] == bound)
	{
		[self  erase: variable(next)];
		missedSome = YES;
	}
	
	if ((next == 0) && !missedSome) return NO;
	else if (next == 0)
	{
		ok = YES;
		bound++;
		missedSome = NO;
		[variables  makeObjectsPerform: @selector(startOver)];
	}
	
	else next--;
	
	return YES;
}


- erase: (id) variable
{
	[last  unhilight];
	[variable  hilight];
	[last = variable  erase];
	
	return self;
}


@end
