1% ------------------------------------------------
    2% Jan 99 
    3% Author: Brian Ross
    4% Dept. of Computer Science, Brock University
    5%
    6% Random generation of CCS expressions.
    7% As in Koza, a ramped half-and-half approach used: 
    8%
    9% If depth = M, then equal spread of trees of approx. depth 2, 3, ..., M.
   10% Tree sizes not precise: list terms (restrict, relabel) can vary as much
   11% as +4 (or more?), because I'm avoiding backtracking for tree depth size.
   12% For each depth category, rougly equal split attempted between full 
   13% and grow trees.
   14% Full tries to get full depth on all branches.
   15% Growth trees are irregularly shaped.
   16% The generation cycles between them and depth size. Cycling done to
   17% reduce duplicates that are common with grow tree generation.
   18%
   19% ramped_population: create a population using ramped approach.
   20% Equal spread of trees using full and growth generation, and of size
   21% 2, 3, ..., MaxDepth.
   22% First, old population in individual/3 retracted.
   23% All expressions asserted into: individual(ID, Val, Expr). 
   24
   25ramped_population(PopSize) :-
   26	retractall(individual(_,_,_)),
   27	max_depth_P(MaxDepth, _),
   28	dctg_root_P(Root),
   29	setof(D, X^Y^Z^(fast:dctg_rule_info(Root,X,Y,D,Z)), L),
   30	max_list(L, MinDepth),
   31	populate(MinDepth, MaxDepth, MinDepth, grow, 0, PopSize),
   32	number_population,
   33	!.
   34
   35% populate(D, MaxDepth, MinDepth, Type, CurrPopn, PopSize) loops until PopSize
   36% individuals created. Depth D goes between 2 and MaxDepth. Type toggles
   37% between grow and full.
   38
   39populate(_, _, _, _, MaxPopn, MaxPopn) :- !.
   40populate(D, MaxD, MinD, Type, Popn, MaxPopn) :- 
   41	D > MaxD,
   42	!,
   43	populate(MinD, MaxD, MinD, Type, Popn, MaxPopn).
   44populate(D, MaxD, MinD, grow, Popn, MaxPopn) :-
   45	prob_grow_P(Pgrow),
   46	maybe(Pgrow),		% new! May/00: only Pgrow% chance of grow tree
   47	make_individual(D, grow, Popn, Popn2),
   48	!,
   49	populate(D, MaxD, MinD, full, Popn2, MaxPopn).
   50/*
   51populate(D, MaxD, MinD, full, Popn, MaxPopn) :-
   52	make_individual(D, full, Popn, Popn2),
   53	D2 is D + 1,
   54	!,
   55	populate(D2, MaxD, MinD, grow, Popn2, MaxPopn).
   56*/
   57populate(D, MaxD, MinD, Type, Popn, MaxPopn) :-
   58	make_individual(D, full, Popn, Popn2),
   59	D2 is D + 1,
   60	!,
   61	toggle_type(Type, Type2),	
   62	populate(D2, MaxD, MinD, Type2, Popn2, MaxPopn).
   63populate(D, MaxD, MinD, Type, Popn, MaxPopn) :- % new: June 11/99
   64	!,
   65	populate(D, MaxD, MinD, Type, Popn, MaxPopn).
   66
   67toggle_type(grow, full).
   68toggle_type(full, grow).
   69
   70% make_individual(Depth, Type, Popn, NewPopn) 
   71% makes an individual of Type tree of Depth size. 
   72% current Popn size updated to NewPopn, but might not change
   73% if expression rejected (not unique?)
   74% Each individual Expr is asserted into: 
   75%      individual(x, _,  Expr, Expr2)
   76% where Expr is main body, Expr2 is adf expression ('0' if unused).
   77% ID and fitness will eventually replace first 2 fields.
   78
   79make_individual(Depth, Type, Popn, NewPopn) :-
   80	dctg_root_P(Root),
   81	user_args_P(UserArgs),
   82	!,
   83	generate_tree(Root, Type, Depth, UserArgs, Expr, _), % last arg is list notn.
   84	((unique_population_P(yes) ; unique_population_P(init)),
   85		individual(_, _, Expr) ->
   86		NewPopn = Popn
   87		;
   88		(Type == full -> writel('f') ; writel('g')), 
   89		assert(individual(x, _, Expr)),
   90		NewPopn is Popn + 1),
   91	!.
   92
   93% consecutively numbers all the population with unique ID numbers
   94
   95number_population :-
   96	assert(popn_cnt(0)),
   97	retract(individual(x, V, E)),
   98	retract(popn_cnt(K)),
   99	K2 is K + 1,
  100	assert(popn_cnt(K2)),
  101	assert(individual(K2, V, E)),
  102	fail.
  103number_population :-
  104	retract(popn_cnt(_)),
  105	!.
  106
  107% consecutively renumbers all the new population with unique ID numbers
  108
  109renumber_population :-
  110	assert(popn_cnt(0)),
  111	retract(newindividual(_, V, E)),
  112	retract(popn_cnt(K)),
  113	K2 is K + 1,
  114	assert(popn_cnt(K2)),
  115	assert(individual(K2, V, E)),
  116	fail.
  117renumber_population :-
  118	retract(popn_cnt(_)),
  119	!