/*IND-version2.0
 *   IND 2.0 released 9/15/92   contact: ind@kronos.arc.nasa.gov
 *   by Wray Buntine (and others, see IND/README)
 *   NASA Ames Research Center, MS 269-2, Moffett Field, CA 94035
 */

#include <stdio.h>
#include "SYM.h"
#include "sets.h"
#include "TREE.h"
#include "DEFN.h"
extern   int   depth;


/***************************************************************************/
/*
 *	add_counts(t, set) -- add count information to current node
 *               return 1 if out of memory
 */
int
add_counts(t)
ot_ptr	t;
{
	int	i;
	float	tot=0;

 	if ( t->eg_count )
		sfree(t->eg_count); 
	if ( !(t->eg_count = cal_d_vec(t->xtra.gr.egs)))
		return 1;
	for (i=0; i<ndecs; i++)
		tot += t->eg_count[i];
	t->tot_count = tot;
	return 0;
}

bt_ptr make_btree();

/***************************************************************************/
/*
 *	add_option(t, bt) -- add information to make current node into a test
 *               return 1 if out of memory
 *	
 */
int
add_option(t, bt)
ot_ptr	t;
bt_ptr	bt;
{
	register int	i,j;
	register bt_ptr	option;
	register bt_ptr	*optiona;
	if ( !ttest(t) ) {
		/*
		 *	create single option from scratch
		 */
		null_flags(t->tflags);
		set_flag(t->tflags,test);
		if ( !(t->option.o = make_btree(bt) ))
		    return 1;
		t->option.o->parent = t;
		foroutcomes(j, t->option.o->test)
		      t->option.o->branches[j]->xtra.gr.egs=(egset*)0;
	} else if ( toptions(t) ) {
		/*
		 *	already have multiple options so extend by 1
		 */
		optiona = t->option.s.o;
		i = t->option.s.c++;
		if ( !(t->option.s.o = 
			(bt_ptr *) salloc((i+2)*sizeof(bt_ptr)) ))
			return 1;
		option = t->option.s.o[i] = make_btree(bt);
		if ( !option ) return 1;
		option->parent = t;
		foroutcomes(j, option->test)
		      option->branches[j]->xtra.gr.egs=(egset*)0;
		for (i--; i>=0 ; i--)
			t->option.s.o[i] = optiona[i];
		sfree(optiona);  
	} else {
		/*
		 *	have single option so convert to multiple
		 */
		set_flag(t->tflags,optiont);
		option = t->option.o;
		if ( !(t->option.s.o = (bt_ptr *) salloc(2*sizeof(bt_ptr)) ))
			return 1;
		t->option.s.o[0] = option;
		t->option.s.c = 2;
		option = t->option.s.o[1] = make_btree(bt);
		if ( !option ) return 1;
		option->parent = t;
	}
	return 0;
}

/***************************************************************************/
/*
 *	new_node(tp) -- alloc memory for a new tree node
 *    			return 0 if no memory
 */
ot_ptr
new_node(tp)
bt_ptr	tp;		/*  parent node    */
{
	ot_ptr	t;

	t = (ot_ptr) salloc(sizeof(ot_rec));
	if ( !t ) return (ot_ptr)0;
	null_flags(t->tflags);
	t->tot_count = 0;
	t->bestprob = 0.0;
	t->eg_count = (float*)0;
	t->option.o = (bt_ptr)0;
	t->option.s.c = 0;
	if (  !(t->parents = mem_alloc(bt_ptr)) ) return (ot_ptr)0;
        t->num_parents = 1;
#ifdef GRAPH
        t->parent_c = 1;
#endif
	t->parents[0] = tp;
	t->xtra.gr.gain = -FLOATMAX;
	t->xtra.gr.egs = (egset *)0;
        t->testing.unordp = (unordtype *) 0;
	return t;
}

/***************************************************************************/
/*
 *	make_btree(bt) -- create bt_rec, leaves etc. using "bt" as a draft
 *               return 0 if out of memory;   assumes "bt" was created by
 *		 choose()
 *
 */
bt_ptr
make_btree(bt)
bt_ptr	bt;		/*  draft bt_rec to copy   */
{
  int  j;
  bt_ptr   new_bt;
  if ( !(new_bt = mem_alloc(bt_rec) ) )
	return (bt_ptr)0;
  new_bt->tflags = bt->tflags;
  new_bt->parent = bt->parent;
  new_bt->nprob = bt->nprob;
  new_bt->np.nprop = bt->np.nprop;
  new_bt->gain = bt->gain;
  if ( ! (new_bt->test = copy_test(bt->test)) ) {
		sfree(new_bt);
                return (bt_ptr)0;
  }
  if ( !( new_bt->branches = 
	  (ot_ptr *) salloc(outcomes(new_bt->test) * sizeof(ot_ptr)) )) 
    return (bt_ptr)0;
  foroutcomes(j,new_bt->test)
    if ( !(new_bt->branches[j] = new_node(new_bt)) )
	return (bt_ptr)0;
  return new_bt;
}

