#include "structures.h" #include "direct.c" #define MAXJUST 100 void process_clause(struct clause *cl, struct proposition *prop); struct literal_list *body_dereference(module_ptr agent, struct term **body, int body_size, var_array *vars); void forward_chain(struct proposition *prop, struct clause *parent); void forward_clause(struct proposition *prop, int position, struct clause *cl); void spawn_forward(module_ptr agent, struct clause *clause, int entry, var_array *vars); extern struct proposition *get_prop_deref(module_ptr agent,struct term *t, var_array *vars, int type, int action_flag); extern void return_list(struct literal_list *list); void forward_direct_clause(module_ptr agent, struct term *atom, int position, struct clause *cl); void forward_direct_chain(module_ptr agent, struct term *atom); struct list *forward_evaluate(module_ptr agent, struct term **conj, int count, var_array *input_vars, int original_entry, struct term *original_atom, garbage_lists *g); term_pointer eval_deref(term_pointer var_term, var_array *vars); struct literal_list *just_array[MAXJUST]; int just_high; extern int justify_trace; void back_chain(struct proposition *prop, struct clause *parent) { struct list *clause_list; char c; if (!is_processed(prop)) { set_processed(prop); time_consider(prop->agent,prop->term,NULL,prop); forward_chain(prop,parent); if (!prop->is_incomplete) { clause_list= prop->agent->clause_head_table[prop->term->functor]; while (clause_list) { process_clause(clause_list->object,prop); clause_list=clause_list->next; } } } } extern struct list *direct_process(module_ptr agent, struct term **dir, int count, int entry, struct list *vars_list, garbage_lists *g); void process_clause(struct clause *cl, struct proposition *prop) { struct literal_list *body; struct literal_list *temp; struct literal_list *tms_clause; garbage_lists g; var_array *vars=create_vars(cl->var_counter); garbage_init(&g); if (match(prop->term,cl->head,vars)==SUCCESS) { struct list *direct_results; /*direct_results returns a list of variable bindings corresponding to the solutions of the direct predicates */ direct_results=direct_process(prop->agent, cl->body, cl->body_size, 0, g_cons(vars,NULL,&g), &g); while (direct_results) { int i; body=body_dereference(prop->agent, cl->body, cl->body_size, direct_results->object); tms_clause=cons_literal(1,prop,body); add_horn_tms_clause(tms_clause); if(justify_trace&&just_highprop,cl); temp=temp->next; } if(!(justify_trace&&just_highnext; } collect(g); } free(vars->array); free(vars); } struct literal_list *body_dereference(module_ptr agent, struct term **body, int body_size, var_array *vars) { struct literal_list *temp=NULL; struct term *current_atom; int i; for(i=0;iclause_direct_table[current_atom->functor]==NULL &&sym_table[current_atom->functor]->type!='S') temp=cons_literal(0, get_prop_deref(agent, current_atom, vars, sym_table[current_atom->functor]->type, sym_table[current_atom->functor] ->action_type), temp); } return temp; } void forward_chain(struct proposition *prop, struct clause *parent) { struct indexed_clause *f; struct list *temp; #if MYDEBUG printf("%s : forward_chain ",prop->agent->name); print_prop(prop); #endif temp=prop->agent->clause_body_table[prop->term->functor]; while (temp) { f=temp->object; if (f->cl!=parent) forward_clause(prop,f->position,f->cl); temp=temp->next; } } /* ============================================================ | forward_direct_chain() | |----------------------------------------------------------| | Params : 1) pointer to an agent structure | | 2) a term | | Desc : chains forward from the term with respect to the given agent, using only direct_forward rules | | |==========================================================| */ void forward_direct_chain(module_ptr agent, struct term *atom) { struct indexed_clause *f; struct list *temp=agent->direct_forward_table[atom->functor]; while (temp) { f=temp->object; forward_direct_clause(agent,atom,f->position,f->cl); temp=temp->next; } } void push_non_prop_action(module_ptr agent, struct term *term); void forward_direct_clause(module_ptr agent, struct term *atom, int position, struct clause *cl) { struct term *nth_atom, *head_atom; garbage_lists g; struct list *instantiations; var_array *vars=create_vars(cl->var_counter); var_array *this_var; garbage_init(&g); nth_atom=cl->body[position]; if (match(atom,nth_atom,vars)==SUCCESS) { instantiations=forward_evaluate(agent, cl->body, cl->body_size, vars, position, atom, &g); while (instantiations) { this_var=instantiations->object; instantiations=instantiations->next; head_atom=eval_deref(cl->head,this_var); if (sym_table[head_atom->functor]->action_type==ACTION) { push_non_prop_action(agent,copy_term(head_atom)); }; forward_direct_chain(agent,head_atom); /* free_term(head_atom);*/ } } collect(g); } extern int justify_trace; void forward_clause(struct proposition *prop, int position, struct clause *cl) { struct term *nth_atom; var_array *vars=create_vars(cl->var_counter); nth_atom=cl->body[position]; if (match(prop->term,nth_atom,vars)==SUCCESS) { spawn_forward(prop->agent,cl,0,vars); } free(vars->array); free(vars); } extern void update_forward_table(module_ptr mod, struct clause *cl); extern struct clause *expand(module_ptr agent, struct term *atom, var_array *vars); void recursive_consider(module_ptr agent, struct term *entry_atom, var_array *vars) { struct list *encountered=agent->encountered[entry_atom->functor]; if (sym_table[entry_atom->functor]->type=='R' && !term_on_list(entry_atom,vars,encountered)) { struct clause *exp_clause; var_array *new_vars; agent->encountered[entry_atom->functor]= cons(dereference(entry_atom,vars),encountered); exp_clause=expand(agent,entry_atom,vars); if (exp_clause==NULL) printf("Error: bad recursive clause \n"); else { update_forward_table(agent,exp_clause); } if (justify_trace) { printf("recursive clause expanded \n"); print_clause(exp_clause,sym_table); } new_vars=create_vars(exp_clause->var_counter); spawn_forward(agent,exp_clause,0,new_vars); free(new_vars->array); free(new_vars); } } var_array *find_all_solutions(module_ptr agent, struct term *atom_tuple, var_array *input_vars, int exist_var, int result_var, garbage_lists *g); void spawn_forward(module_ptr agent, struct clause *clause, int entry, var_array *vars) { if (entry==clause->body_size) { struct proposition *head; struct literal_list *tms_clause; tms_clause=body_dereference(agent,clause->body, clause->body_size, vars); if(clause->head->functor!=FALSE) { head=get_prop_deref(agent, clause->head, vars, sym_table[clause->head->functor]->type, sym_table[clause->head->functor]->action_type); tms_clause=cons_literal(1,head,tms_clause); } add_horn_tms_clause(tms_clause); if(justify_trace&&just_highhead->functor!=FALSE && !is_processed(head)) { set_processed(head); time_consider(head->agent,head,NULL,head); forward_chain(head,NULL); } } else { struct term *entry_atom=clause->body[entry]; if (sym_table[entry_atom->functor]->type=='D'|| sym_table[entry_atom->functor]->type=='S') { struct list *direct_results; garbage_lists g; garbage_init(&g); if (entry_atom->functor!=FIND_ALL) { direct_results=direct_one(agent,entry_atom,vars,&g); for(;direct_results;direct_results=direct_results->next) { spawn_forward(agent,clause,entry+1,direct_results->object); } } else if (entry_atom->arity==3) { spawn_forward(agent, clause, entry+1, find_all_solutions( agent, entry_atom->argument_array[1], vars, entry_atom->argument_array[0]->functor, entry_atom->argument_array[2]->functor, &g)); } collect(g); } else { struct list *possible_props= agent->prop_table[entry_atom->functor]; time_consider(agent,entry_atom,vars,NULL); while (possible_props) { match_and_spawn(possible_props->object, entry_atom, entry+1,vars,clause); possible_props=possible_props->next; } recursive_consider(agent,entry_atom,vars); } } } struct list *matching_props(module_ptr agent, struct term *t, var_array *vars); void free_list(struct list *l); match_and_spawn(struct proposition *prop, struct term *entry_atom, int entry, var_array *vars, struct clause *clause) { int i; var_array *local_vars=create_vars(vars->length); copy_vars(vars,local_vars); if (eval_match(prop->term,entry_atom,local_vars)==SUCCESS) { spawn_forward(prop->agent,clause,entry,local_vars); } free(local_vars->array); free(local_vars); } var_array *find_all_solutions(module_ptr agent, struct term *atom_tuple, var_array *vars, int exist_var, int result_var, garbage_lists *g); struct list *forward_evaluate(module_ptr agent, struct term **conj, int count, var_array *input_vars, int original_entry, struct term *original_atom, garbage_lists *g) { struct list *vars_list=g_cons(input_vars,NULL,g); struct list *so_far=NULL; int entry; for (entry=0;entryobject; if (sym_table[entry_atom->functor]->type=='S'|| sym_table[entry_atom->functor]->type=='D') switch(entry_atom->functor) { case NOT: { struct list *p_list= matching_props(agent, entry_atom->argument_array[0], vars); int is_true=FALSE; while (p_list&&!is_true) { is_true=((struct proposition *)(p_list->object)) ->state; p_list=p_list->next; } if(!is_true) so_far=g_cons(vars,so_far,g); free_list(p_list); } break; case FIND_ALL: so_far=g_cons(find_all_solutions( agent, entry_atom->argument_array[1], vars, entry_atom->argument_array[0]->functor, entry_atom->argument_array[2]->functor, g), so_far, g); break; default: so_far=append(direct_one(agent,entry_atom, vars_list->object,g),so_far); break; } else if (original_entry==entry) { so_far=g_cons(vars,so_far,g); } else { struct list *potentials=agent->prop_table[entry_atom->functor]; recursive_consider(agent,entry_atom,vars); while (potentials) { struct proposition *p=potentials->object; var_array *local_vars=create_vars(vars->length); copy_vars(vars,local_vars); g->garbage_vars=cons(local_vars,g->garbage_vars); if (p->state==TRUE&& eval_match(p->term,entry_atom,local_vars)==SUCCESS) so_far=g_cons(local_vars,so_far,g); potentials=potentials->next; } } vars_list=vars_list->next; } vars_list=so_far; so_far=NULL; } return vars_list; } struct term *t_cons(struct term *t, struct term *list); struct term *t_null(); var_array *find_all_solutions(module_ptr agent, struct term *atom_tuple, var_array *vars, int exist_var, int result_var, garbage_lists *g) { struct list *results; var_array *local_vars=create_vars(vars->length); int result_count,i; struct term *r_list=t_null(); copy_vars(vars,local_vars); g->garbage_vars=cons(local_vars,g->garbage_vars); results=forward_evaluate(agent, atom_tuple->argument_array, atom_tuple->arity, vars, -1, NULL, g); result_count=list_length(results); for(i=0;iobject))->array[exist_var], r_list); results=results->next; } local_vars->array[result_var]=r_list; return local_vars; } void dump_justifications(void) { int i; void *print_justification(struct literal_list *c); struct literal_list *just; for (i=0;iprop->state==TRUE) just=just->next; if (just==NULL) print_justification(just_array[i]); return_list(just_array[i]); } }