/* ---------------------------------------------------------- % (C)1992 Institute for New Generation Computer Technology % (Read COPYRIGHT for detailed information.) ----------------------------------------------------------- */ /*===================================================================== * cu-Prolog III (Constraint Unification Prolog) * Copyright: Institute for New Generation Computer Technology,Japan * 1989--91 ==================================================================== */ /*-------------------------------------------------------------------- * << mainsub.c >> * system command etc. * 1993.7.30 freeheap() * 1993.8.3 calc_component(), recalc_component() sppedup * 1994.6.28 component functions. speedup * 1994.9.27 show statistics * 1994.10.25 debug: set_head_component --------------------------------------------------------------------*/ #include "include.h" void putcursor () { if (Is_Notrace) { /* trace off */ tputc ('_'); } else if (Is_Normaltrace) { /* trace on */ tputc ('$'); } else tputc ('>'); /* step trace on */ } void traceswitch () { if (Is_Normaltrace) { Notrace_mode; tprint0 ("\n +++ normal trace off +++\n"); } else { Normaltrace_mode; tprint0 ("\n +++ normal trace on +++\n"); } } void stepswitch () { if (Is_Steptrace) { Notrace_mode; tprint0 ("\n +++ step trace off +++\n"); } else { Steptrace_mode; tprint0 ("\n +++ step trace on +++\n"); } } int decode_pname(fname) /* 'member/2' --> 'member', return 2 */ char *fname; { for (; *fname != '\0'; fname++) if (*fname == '/') { *fname = '\0'; return(atoi(fname + 1)); } return(-1); } void spyswitch (fname) char *fname; { struct func *f; int i,arity; if (strcmp (fname, "*") == 0) { tprint0 ("--- set all spy flag ---"); NL; allspy(1); /* set all spy flag */ return; } if (strcmp (fname, ".") == 0) { tprint0 ("--- reset all spy flag ---"); NL; allspy(0); /* reset all spy flag */ return; } if (strcmp (fname, "?") == 0) {/* list spyed predicates */ tprint0 ("+++ list spyed predicates +++\n"); for (i=0; i < HASH_SIZE; i++) for (f = hash_list[i]; f != NULL; f = f -> f_link) { if isspy(f) tprint2 ("%s(%u) ", f -> f_name, f -> f_arity); } NL; return; } if (strcmp (fname, ">") == 0) /* spy fold/unfold */ { tprint0(" +++ "); if isspy(MODULAR_P) tprint0("no"); tprint0("spy fold/unfold transformation \n"); spychange(MODULAR_P); spychange(INTEG_P); return; } arity = decode_pname(fname); if (!exist_fname(fname)) { tprint1(" '%s' does not exist.\n", fname); return; } if (arity == -1) /* spy switch fname/?? */ { for(f = hash_list[hash(fname)]; f != NULL; f = f->f_link) if (streq(fname,f->f_name)) { tprint0 ("+++ "); if isspy(f) tprint0 ("no"); tprint2("spy %s/%d\n", f->f_name, f->f_arity); spychange(f); } } else { f = funcsearch(fname, arity); if (f != NULL) { tprint0 (" +++"); if isspy(f) tprint0 ("no"); tprint2("spy %s/%d\n", f->f_name,f->f_arity); spychange(f); /* switch spy flag on/off */ } else tprint2(" '%s/%d' does not exist.\n", fname,arity); } } void allspy (n) /* if n == 1: set all spy flag, else resetall flag */ int n; { struct func *f; int i; if (n == 1) { for (i = 0; i < HASH_SIZE; i++) for (f = hash_list[i]; f != NULL; f = f -> f_link) spyfun(f); } else { for (i = 0; i < HASH_SIZE; i++) for (f = hash_list[i]; f != NULL; f = f -> f_link) nospyfun(f); } } void show_pred_roles(f) /* show component */ struct func *f; { int i, arity; struct component *cm; register struct component *c; for (i = 0, arity = f->f_arity; i < arity ; i++) { cm = Component(f,i); if (cm == NULL) { tprint0("_"); } else { for (c = cm; c != NULL; c = c->c_next) { if (c->c_label == NULL) { tprint0("+"); } else { tprint1("%s",c->c_label->f_name); } if (c->c_next == NULL) break; else { tprint0("."); } } } if (i == (arity -1)) return; else { tprint0("|"); } } } /* the number of pred names printed in one line */ #define PRED_IN_LINE 5 void show_syspred_name() { int i, j = 0; register struct func *f; tprint0(" +---------------[ +:recursive, ^:functor ]--\n"); for (i = 0; i < HASH_SIZE; i++) /* print system predicates */ for (f = hash_list[i]; f != NULL; f = f -> f_link) if issystem(f) { tprint2 ("%s/%u", f -> f_name, f -> f_arity); if isrecursive(f) tprint0 ("+"); if (f->def.f_sysfunc == NULL) tprint0("^"); tputc('\t'); if (++j >= PRED_IN_LINE) {j = 0; NL;} }; NL; } void show_userpred_name() { int i, j = 0; register struct func *f; tprint0(" +-------------"); tprint0("--[ *:spy, -:reduced, +:recursive, #:new ]--\n"); for (i = 0; i < HASH_SIZE; i++) /* print user predicates */ for (f = hash_list[i]; f != NULL; f = f -> f_link) { /* if (f->f_arity < 0) continue; */ if (f->def.f_sysfunc == NULL) continue; /* cut constant. */ if issystem(f) continue; tprint2 ("%s/%u", f -> f_name, f -> f_arity); if isspy(f) tprint0 ("*"); if isreduced(f) tprint0 ("-"); if isrecursive(f) tprint0 ("+"); if isnewpred(f) tprint0("#"); tputc('\t'); if (++j >= PRED_IN_LINE) {j = 0; NL;} } NL; } void show_syspred_status(f) struct func *f; { tprint0("-----["); show_pred_roles(f); tprint1("]--<%s>---+\n", ((is_funcsys(f)) ? "functional" : "multi-valued")); } void show_pred_def(f) /* show def of each pred */ struct func *f; { void show_pred_roles(); if (f->def.f_set == NULL) return; /* constant */ tprint2 (" +--------( %s/%u )-----", f->f_name, f->f_arity); if issystem(f) { show_syspred_status(f); return; } if is_nofuncsys(f) { tprint0("------+\n"); return; } if isspy(f) tprint0 ("--"); if isreduced(f) tprint0 ("--"); if isrecursive(f) tprint0("--"); if isnewpred(f) tprint0("--"); tprint0("["); show_pred_roles(f); tprint2("]--%d/%d--+\n",f->f_unitcount,f->f_setcount); if (f -> f_integ != NULL) { tprint0 (" "); P_dclause (f -> f_integ -> it_clause,NULL_ENV); NL; NL; } Showfunc(f); } void showdef (fname) /* list definition (%d command) */ char *fname; { register struct func *f; int i,arity; check_recursion(); if (streq(fname, "/")) { tprint0 (" +-- List all predicates ---+ \n"); for (i = 0; i < HASH_SIZE; i++) for (f = hash_list[i]; f != NULL; f = f -> f_link) Showfunc (f); return; } if (streq(fname, "*")){ tprint0 (" +-- List predicates ---+ \n") for ( i=0; i < HASH_SIZE; i++) for (f = hash_list[i]; f != NULL; f = f -> f_link) { if isnoreduced(f) Showfunc (f); } return; } if (streq(fname, "?")){ show_syspred_name(); show_userpred_name(); return; } if (streq(fname, "-")) { show_userpred_name(); return; } arity = decode_pname(fname); if (exist_fname(fname) == NULL) { tprint1 ("'%s' does not exist.\n", fname); return; } if (arity == -1) /* show fname/?? */ { for (f = hash_list[hash(fname)]; f != NULL; f = f->f_link) if (streq(f->f_name,fname)) show_pred_def(f); } else { f = funcsearch(fname,arity); if (f != NULL) show_pred_def(f); else tprint2("'%s/%d' does not exist.\n",fname,arity); } } void loghandle (fname) /* log file (%l command) */ char *fname; { if (strcmp (fname, "no") == 0) { tprint0 ("=== log stop === \n"); if (lfp != NULL) fclose (lfp); lfp = NULL; strcpy (logfile, "no"); } else if ((fopen (fname, "r")) != NULL) { tprint1 ("'%s' : already exist \n", fname); } else if ((fopen (fname, "w")) == NULL) { tprint1 (" '%s' : can't open \n", fname); } else { if (lfp != NULL) { fclose (lfp); tprint1 (" == %s : close ==\n", logfile); } lfp = fopen (fname, "w"); tprint1 (" log file '%s' \n", fname); strcpy (logfile, fname); } } void helpmenu () { /* on-line help */ tprint0 ("\t%%h\t: help\t\t\t%%Q : quit \n"); tprint0 ("\t# : OS command interpreter \n"); tprint0 ("\t%%d : list definition\n"); tprint0 ("\t\t%%d* %%d/: list all %%d?: list names %%d-: user pred\n"); tprint2 ("\t%c %c: consult file (no echo)\n", '"', '"'); tprint1 ("\t%c ?: consult file (with echo)\n", '"'); tprint1 ("\t%%l : set log file ['%s']\n", logfile); tprint0 ("\t%%w : save program\n"); tprint0 ("\t%%p : spy switch\n"); tprint0 ("\t\t%%p*:spy all\t%%p.:nospy all\t%%p?:list spyed preds.\n"); tprint1 ("\t%%t\t: normal trace switch [%s]\n", ((Is_Normaltrace) ? "on" : "off")); tprint1 ("\t%%s\t: step trace switch [%s]\n", ((Is_Steptrace) ? "on" : "off")); tprint0 ("\t%%a\t: all modular mode "); if (Is_Modular) tprint0(" <=now"); tprint0 ("\n\t%%o\t: M-Solvable mode "); if (Is_Msolvable) tprint0(" <=now\n") else NL; tprint1 ("\t%%c : max number of refutation node [%u]\n", Refcount); tprint0 ("\t%%n \t: new predicate name "); tprint1 ("['%s']\n", genname); tprint0 ("\t%%L\t: list new predicate definitions\n"); tprint0 ("\t%%f\t: show the system heap size\n"); tprint0 ("\t%%C [Feature,type,... ]. : set cat() functor\n"); tprint0 ("\t\t ==> ");show_category();NL; tprint0 ("\t%%G\t: Garbage Collection \n"); tprint1 ("\t%%D : Max Depth of Printing, now is %d\n", Print_Depth); tprint1 ("\t%%u\t: Undefined Predicate Handling Switch [%s]\n", ((Handle_Undefined == TRUE) ? "ERROR" : "FAIL")); tprint1("\t%%M : Max number of Variables in Transformation[%u]\n", MODULARMAX); tprint0 ("\t%%P : Preprocess Constraints\n"); tprint0 ("\t\t%%P*: preprocess all\t%%P?: predicates with nonmodular\n"); tprint0 ("\t%%R\t: system Reset \n"); tprint0 ("\t%%S\t: show statistics of the previous question.\n"); } void freeheap () { /* print shp status */ tprint3 ("\npermanent data area:\n\tSystem_heap : %d%%(%d/%dK) ", (int)(100 * (shp - sheap) *SHEAP_UNIT / SHEAP_SIZE), ((int)(shp-sheap)*SHEAP_UNIT/1000),(int)(SHEAP_SIZE/1000)); tprint3 ("Name_heap : %d%%(%d/%dK)\n", (int)(100 * (nhp - nheap) * NAME_UNIT / NAME_SIZE), (int)((nhp-nheap)*NAME_UNIT/1000),(int)(NAME_SIZE/1000)); show_heap_max(); } void show_heap_max() /* for debug */ { tprint0("temporal data area (max. used)\n\t"); tprint3 ("Cstr. heap : %d%%(%d/%dK) ", (int)((Cheap_Max - cheap) * 100 * CHEAP_UNIT / CHEAP_SIZE), (int)((Cheap_Max - cheap)*CHEAP_UNIT/1000),(int)(CHEAP_SIZE/1000)); tprint3("Heap : %d%%(%d/%dK) ", (int)(((Heap_Max - heap) * 100 * HEAP_UNIT) / HEAP_SIZE), (int)((Heap_Max - heap)*HEAP_UNIT/1000),(int)(HEAP_SIZE/1000)); tprint3 ("\n\tUser stack : %d%%(%d/%dK) ", (int)(((Stack_Max - ustack) * 100 * USTACK_UNIT)/ USTACK_SIZE), (int)((Stack_Max - ustack)*USTACK_UNIT/1000),(int)(USTACK_SIZE/1000)); tprint3 ("Env. stack : %d%%(%d/%dK) \n", (int)(((Esp_Max - eheap) * 100 * ESP_UNIT)/ ESP_SIZE), (int)((Esp_Max - eheap)*ESP_UNIT/1000),(int)(ESP_SIZE/1000)); } void init_heap_max() { Cheap_Max = cheap; Stack_Max = ustack; Heap_Max = heap; } void filewrite (n) /* write program to file */ char *n; { FILE * lfpsave; int i; register struct func *f; if ((wfp = fopen (n, "r")) != NULL) { fclose (wfp); wfp = stdout; tprint1 (" %s : already exist \n", n); return; } if ((wfp = fopen (n, "w")) == NULL) { wfp = stdout; tprint1 (" %s : can't open \n", n); return; } fprintf(wfp,"%%%%%% cu-Prolog predicates %%%%%%%% \n"); lfpsave = lfp; lfp = NULL; writenewfunc(); NL; for (i = 0; i< HASH_SIZE; i++) for (f = hash_list[i]; f != NULL; f = f->f_link) if (isuser(f) && isnoreduced(f)) Showfunc(f); fclose (wfp); wfp = stdout; lfp = lfpsave; tprint1 ("=== write to: %s ===\n", n); return; } void disp_func_def (f_from, f_to)/* show defs of f_from--->f_to */ struct func *f_from, *f_to; { if (f_from == NULL) return; if (f_from == f_to) return; disp_func_def (f_from -> f_link, f_to); if (isuser (f_from) && isnoreduced (f_from)) Showfunc (f_from); } void set_inputfile (n) char *n; /* file name */ { fp = fopen (n, "r"); if (fp == NULL) { /* open error */ fp = stdin; tprint1 ("%s ", n); error ("can't open !"); } else { tprint1 ("=== open '%s'\n", n); } } void readfile () { /* "file name" or "file name?" */ int i; /* if (!KEYIN) error ("file already opened"); */ for (i = 0; ((cbuf != '"') && (cbuf != '?')); advance) nbuf[i++] = cbuf; nbuf[i] = '\0'; /* n[] <- file name */ if (cbuf == '?') ECHO_BACK = TRUE; /* echo back on */ skipline; upush(&fp); utop = usp; set_inputfile (nbuf); /* set file pointer */ if (ECHO_BACK == TRUE) wfp = stdout; /* echo back on */ } void set_eof () { /* file EOF */ clearerr(fp); /* clear eof */ if (tty && KEYIN){ /* from keyboard */ error(" "); /* EOF (^D in UNIX) */ } fclose (fp); if (utop != &ustack[0]) { utop -= 1; undo(utop); } else fp = stdin; if (wfp == NULL) wfp = stdout; /* echo back on */ tprint0 ("\n ****** end of file ******* \n"); } /* ----------- static program analyzer --------------- */ /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * check_recursion() check recursive/finite predicates +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ int REC_to_FINITE = 1; void check_all_unit(),rec_to_finite(),check_unitpred(); int is_body_finite(); void check_recursion() /* check recursive user predicates */ { int i; void reset_component(),calc_component(); if (Def_Modified == 0) return; for (i = 0; i < HASH_SIZE; i++) check_all_unit(hash_list[i]); REC_to_FINITE = 1; while(REC_to_FINITE != 0) { REC_to_FINITE = 0; /* global flag */ rec_to_finite(); /* traverse predicates */ } Def_Modified = 0; /* def modified flag off */ reset_component(); calc_component(); } void check_unitpred(f) struct func *f; { if (issystem(f)) return; if ((f->f_setcount == 0) || (f->f_setcount == f->f_unitcount)) { finitefun(f); return; } recursivefun(f); } void check_all_unit(fl) struct func *fl; { register struct func *f; if (fl == NULL) return; for (f = fl; f != NULL; f = f->f_link) { check_unitpred(f); } } void rec_to_finite() /* recursive pred -> finite pred */ { register int i; register struct func *f; for (i = 0; i < HASH_SIZE; i++) for(f = hash_list[i]; f != NULL; f = f->f_link) { if (issystem(f) || isfinite(f)) continue; else if (is_body_finite(f) != 0) { REC_to_FINITE = 1; finitefun(f); } } } int is_body_finite(f) /* if all the body is finite */ struct func *f; { register struct set *s; register struct clause *c; for (s = f->def.f_set; s != NULL; s = s->s_link) for (c = s->s_clause->c_link; c != NULL; c = c->c_link) if (isvar(c->c_form) || isrecursive(c->c_form->type.t_func)) return(FALSE); return(TRUE); } /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * recalc_component() component of each argument +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ void mark_component_checked_all(), set_all_head_component(), set_head_component(), set_head_component2(), set_all_body_component(),set_body_component(), add_component_pst(), add_component_pst2(), add_label(),calc_all_var(); #define is_globalvar(t) (((struct var *)t)->v_type == VAR_GLOBAL_TYPE) struct component *merge_component(); int COMPONENT_CHANGED; int HAS_BODY; /* changed in set_head_component() */ struct funclist /* temporal funclist structure */ { struct func *func; struct funclist *next; }; #define NULL_fl (struct funclist *)NULL void calc_component() { register int i; register struct func *f; register struct funclist *FL,*fl; int *hsave = hp; FL=fl=NULL_fl; for (i = 0; i < HASH_SIZE; i++) for (f = hash_list[i]; f != (struct func *)NULL; f = f->f_link) if (isuser(f) && f->def.f_set != (struct set *)NULL) { HAS_BODY=0; /* changed in set_head_component() */ set_head_component(f); if (HAS_BODY != 0) /* not unit def predicates */ { MEMORY_ALLOC(fl,funclist,TEMPORAL); fl->func=f; fl->next=FL; FL=fl; } else /* no body clause --> end */ { component_checked(f); calc_all_var(f); } } do { COMPONENT_CHANGED = 0; for (fl=FL; fl != NULL_fl; fl=fl->next) set_body_component(fl->func); for (fl=FL; fl != NULL_fl; fl=fl->next) set_head_component2(fl->func); } while(COMPONENT_CHANGED != 0); for (fl=FL; fl != NULL_fl; fl=fl->next) { component_checked(fl->func); calc_all_var(fl->func); } hp=hsave; } void recalc_component() /* calc component for newly defined preds */ { register int i; register struct func *f; register struct funclist *FL,*fl; int *hsave = hp; FL=fl=NULL_fl; for (i = 0; i < HASH_SIZE; i++) for (f = hash_list[i]; f != (struct func *)NULL; f = f->f_link) if (isuser(f) && is_component_not_checked(f) && f->def.f_set != (struct set *)NULL ) { HAS_BODY=0; /* changed in set_head_component() */ set_head_component(f); if (HAS_BODY != 0) /* if f has a body clause */ { MEMORY_ALLOC(fl,funclist,TEMPORAL); fl->func=f; fl->next=FL; FL=fl; } else /* f has only unit clauses. */ { component_checked(f); calc_all_var(f); } } do { COMPONENT_CHANGED = 0; for (fl=FL; fl != NULL_fl; fl=fl->next) set_body_component(fl->func); for (fl=FL; fl != NULL_fl; fl=fl->next) set_head_component2(fl->func); } while(COMPONENT_CHANGED != 0); for (fl=FL; fl != NULL_fl; fl=fl->next) { component_checked(fl->func); calc_all_var(fl->func); } hp=hsave; } void calc_all_var(f) struct func *f; { register struct set *s; for (s = f->def.f_set; s != NULL; s = s->s_link) recalc_voccurrence(s->s_clause, s->s_vlist); } void reset_component() /* reset all Component() */ { int i; register int j; struct func *f; register struct set *s; register struct term *v; for (i = 0; i < HASH_SIZE; i++) for(f = hash_list[i]; f != NULL; f = f->f_link) if (isuser(f)) { for(j = f->f_arity - 1; j >= 0; j--) Component(f,j) = NULL; for(s = f->def.f_set; s != NULL; s = s->s_link) for (v = s->s_vlist; v != NULL; v = vlink(v)) vcomponent(v) = NULL; } } void set_head_component(f) /* check heads of f */ struct func *f; { register int i; register struct set *s; register struct term *t,*arg; if (f->f_arity == 0) return; for(s = f->def.f_set; s != NULL; s = s->s_link) { t = s->s_clause->c_form; /* head */ if (s->s_clause->c_link != NULL_CL) HAS_BODY=1; for (i = f->f_arity - 1; i >= 0; i--) { arg = Arg(t,i); if (isvar(arg)) { if (is_globalvar(arg)) { Component(f,i) = merge_component(Component(f,i), vcomponent(arg),ETERNAL); } } else if(is_pst(arg)) add_component_pst(f,i,((struct pst *)arg)->p_lists); else add_label(f,i,NOPSTLABEL,ETERNAL); /* normal term ; bug 94.10.25 */ } } } void set_body_component(ff) struct func *ff; { struct set *s; register struct clause *c; register struct term *t,*arg; register struct func *f; int i; if (ff->f_arity == 0) return; for(s=ff->def.f_set; s != NULL; s = s->s_link) for(c=s->s_clause->c_link; c !=NULL; c= c->c_link) { t = c->c_form; if (isvar(t)) continue; /* 94.12.2 call(X):-X. */ f = Pred(t); for (i = f->f_arity - 1; i >= 0; i--) { arg = Arg(t,i); if (is_globalvar(arg)) vcomponent(arg)= merge_component(vcomponent(arg), Component(f,i),TEMPORAL); } } } void set_head_component2(f) /* check heads of f (later than 2nd loop)*/ struct func *f; { register int i; register struct set *s; register struct term *t,*arg; if (f->f_arity == 0) return; for(s = f->def.f_set; s != NULL; s = s->s_link) { if (s->s_clause->c_link == NULL_CL) continue; /* omit unit clause */ t = s->s_clause->c_form; /* head */ for (i = f->f_arity - 1; i >= 0; i--) { arg = Arg(t,i); /* check only var and pst */ if (is_globalvar(arg)) Component(f,i) = merge_component(Component(f,i), vcomponent(arg),ETERNAL); else if(is_pst(arg)) add_component_pst2(f,i,((struct pst *)arg)->p_lists); } } } void add_component_pst(f,a,ec) /* add pst ec to f/a */ struct func *f; int a; struct eclause *ec; { register struct eclause *e; register struct term *value; register struct func *label; for (e = ec; e != NULL_ECL; e = e->c_link) { label = Pred(Arg1(e->c_form)); value = Arg2(e->c_form); if (isvar(value) && vcomponent(value) == NULL) continue; else add_label(f,a,label,ETERNAL); } } void add_component_pst2(f,a,ec) /* add pst ec to f/a (later than 2nd loop) */ struct func *f; int a; struct eclause *ec; { register struct eclause *e; register struct term *value; register struct func *label; for (e = ec; e != NULL_ECL; e = e->c_link) { label = Pred(Arg1(e->c_form)); value = Arg2(e->c_form); if is_globalvar(value) /* check var values only */ if (vcomponent(value) == NULL) continue; else add_label(f,a,label,ETERNAL); } } int cmp_label(l1,l2) /* 0:equal -1:l1l2 */ struct func *l1,*l2; { register int dif; if (l1 == l2) return(0); else if (l1 == NULL) return(-1); else if (l2 == NULL) return(1); else return(l1->f_number - l2->f_number); } /* component : ascending order */ void add_label(f,a,l,flag) /* add label l to f/a */ struct func *f,*l; int a,flag; /* flag = ETERNAL or TEMPORAL */ { register struct component *c,*cprev,*nc; register int cmp; for (cprev=NULL,c=Component(f,a); c != NULL; cprev= c, c = c->c_next) { cmp = cmp_label(l,c->c_label); if (cmp == 0) return; else if (cmp < 0) break; /* l < c_label */ } MEMORY_ALLOC(nc,component,flag); nc->c_next = c; nc->c_label = l; if (cprev == NULL) Component(f,a) = nc; else cprev->c_next = nc; COMPONENT_CHANGED++; } struct component *copy_component(cb,flag) /* make a copy of cb */ struct component *cb; int flag; /* ETERNAL or TEMPORAL */ { register struct component *nc; if (cb == (struct component *)NULL) return(cb); MEMORY_ALLOC(nc,component,flag); nc->c_label = cb->c_label; nc->c_next = copy_component(cb->c_next,flag); return(nc); } struct component *merge_component(ca,cb,flag) /* merge cb in ca */ struct component *ca, /* ca will be changed */ *cb; int flag; /* ETERNAL or TEMPORAL */ { int a; register struct component *nc; if (cb == (struct component *)NULL) return(ca); else if (ca == (struct component *)NULL) { COMPONENT_CHANGED++; return(copy_component(cb,flag)); } else if (ca != (struct component *)NULL) { a = cmp_label(ca->c_label,cb->c_label); if (a == 0) { ca->c_next = merge_component(ca->c_next,cb->c_next,flag); return(ca); } else if (a < 0) /* ca < cb */ { ca->c_next = merge_component(ca->c_next,cb,flag); return(ca); } else /* ca > cb */ { COMPONENT_CHANGED++; /* global var */ MEMORY_ALLOC(nc,component,flag); nc->c_label = cb->c_label; nc->c_next = merge_component(ca,cb->c_next,flag); return(nc); } } } int has_common_label(ec,cm) /* TRUE/FALSE */ struct eclause *ec; struct component *cm; { register int cmp; if (ec == NULL || cm == NULL) return(FALSE); if (cm->c_label == NOPSTLABEL) return(TRUE); /* cm is not vacuous */ cmp = cmp_label(Pred(Arg1(ec->c_form)), cm->c_label); if (cmp == 0) return(TRUE); else if (cmp < 0) return(has_common_label(ec->c_link,cm)); else return(has_common_label(ec,cm->c_next)); } /* -------------- end of component part --------------- */ void oscommand () { /* os command interpreter */ int i; for (i = 0; (cbuf != '\n'); next ()) nbuf[i++] = cbuf; nbuf[i] = '\0'; if (system (nbuf) != 0) tprint0 ("== OS command error == \n"); } void delete_tmp () { /* delete temp file */ FILE *fptmp; if ((fptmp = fopen("TEMPF.###","r")) != NULL) { fclose(fptmp); #if MSDOS == 0 /* for UNIX */ system ("rm -f TEMPF.###"); #else /* for MS-DOS */ system ("del TEMPF.###"); #endif } } void quit_prolog () { /* system quit */ tprint0("\n---- Quit cu-Prolog ? (y/n) ----"); skipline; if (keyread('y')) { if (lfp != NULL) fclose (lfp); /* close log file */ delete_tmp (); /* delete temp file */ exit (1); /* end */ } tprint0("\n.... Return to Prolog ....\n");/* cansel */ return; } void preprocess_constraints(fn) char *fn; { struct func *f; int arity; void preprocess_constr_sub(), preprocess_unit(); if (strcmp(fn,"*") == 0) { tprint0("--- preprocess all predicates ---\n"); preprocess_constr_sub(TRUE); tprint0("Done\n"); return; } if (strcmp(fn,"?") == 0) { tprint0("--- showing predicates with nonmodular constraints ---\n"); preprocess_constr_sub(FALSE); NL; return; } arity = decode_pname(fn); if (! exist_fname(fn)) { tprint1("'%s' does not exist\n",fn); return; } if (arity == -1) { /* any arity */ for (f = hash_list[hash(fn)]; f != NULL; f = f->f_link) if (streq(f->f_name,fn)) preprocess_unit(f,TRUE); } else { f = funcsearch(fn,arity); if (f == NULL) { tprint2("'%s/%d' does not exist.\n",fn,arity); return; } preprocess_unit(f,TRUE); } tprint0("Done\n"); } void preprocess_constr_sub(flag) int flag; /* preproces control flag */ { register int i; void preprocess_all_unit(); for (i = 0; i < HASH_SIZE; i++) preprocess_all_unit(hash_list[i],flag); } void preprocess_all_unit(fl,flag) struct func *fl; int flag; { register struct func *f; void preprocess_unit(); if (fl == NULL) return; for (f = fl; f != NULL; f = f->f_link) preprocess_unit(f,flag); } void preprocess_unit(f,flag) struct func *f; int flag; { register struct set *s; struct clause *c, *sol, *reduce_cstr(); struct pair *env; int check_modularity(); /* cf. is_modular_clause() */ if (issystem(f)) return; for (s = f->def.f_set; s != (struct set *)NULL; s = s->s_link) { c = s->s_constraint; if (c == NULL_CL) continue; if (check_modularity(c) == TRUE) continue; if (flag == FALSE) { Showhorn(s->s_clause,s->s_constraint, NULL_ENV); NL; continue; } tprint2("%s/%d\t", f->f_name,f->f_arity); env = Nenv(s->s_anumber); sol = reduce_cstr(c,s->s_vlist,s->s_anumber,env); if (sol == MFAIL) { /* failing transformation */ wfp = stderr; tprint1("Warning: Failing transformation in %s\n", f->f_name); c->c_form = FAIL; c->c_link = NULL_CL; Showhorn(s->s_clause,s->s_constraint, NULL_ENV);NL; wfp = stdout; continue; } up_init(); s->s_constraint = (struct clause *)termset(sol,env,ETERNAL); s->s_clause = (struct clause *) termset(s->s_clause,env,ETERNAL); up_restore(); if (p_number != 0) { renum_pvars((struct pstvar *)pv_list,v_number); } s->s_anumber = (unsigned short int)(v_number+p_number); s->s_vlist = v_list; } } int check_modularity(cst) /* cf. is_modular_clause */ struct clause *cst; { register struct clause *c; register struct term *t; for (c= cst; c != NULL; c = c->c_link) { t = c->c_form; if (Pred(t) == EQ2_P || (! is_modular_literal(t))) return(FALSE); } return(TRUE); } #define NOREDUCED_CLAUSE (struct clause *)11 struct clause *reduce_cstr(cst,vlist,anum,env) struct clause *cst; struct term *vlist; int anum; struct pair *env; { struct clause *nc,*reduce_substitute(); int reduced = 0; nc = reduce_substitute(cst,env); /* reduce x=y */ if (nc == MFAIL) return(MFAIL); else if (nc == NOREDUCED_CLAUSE) /* no reduction */ return(startmodular(cst,vlist,anum)); else if (nc == NULL) return(NULL); else { up_init(); nc = (struct clause *)termset(nc,env,MEDIUM); up_restore(); if (p_number != 0) { renum_pvars((struct pstvar *)pv_list,v_number); } return(startmodular(nc,v_list,v_number + p_number)); } } struct clause *reduce_substitute(cst,e)/* preprocess constraint */ struct clause *cst; struct pair *e; { register struct clause *c; struct clause *compress_clause(); int reduced = 0; struct term *t; for (c = cst; c != NULL_CL; c = c->c_link) { t = c->c_form; if (Pred(t) == EQ2_P) /* '=' */ { reduced = 1; c->c_form = NULL; if (tunify(Arg(t,0),e,Arg(t,1),e,0) == FALSE) return(MFAIL); } } if (reduced == 0) return(NOREDUCED_CLAUSE); else return(compress_clause(cst)); } struct clause *compress_clause(cst) /* cut c (c->c_form == NULL) */ struct clause *cst; { if (cst == NULL_CL) return(NULL); if (cst->c_form == NULL) return(compress_clause(cst->c_link)); else { cst->c_link = compress_clause(cst->c_link); return(cst); } } /************* print CPU time ******************************/ #if SUN4 == 1 /* print CPU time */ #include long TIMESAVE; /* system time saver (time_t = long) */ void printtime () { /* print CPU time from the previous settime()*/ long clock(); tprint2 ("CPU time = %.3lf sec (Constraints Handling = %.3lf sec)\n", ((double)(clock() - TIMESAVE))/ 1000000.0, ((double)CONSTRAINT_HANDLING_TIME/1000000.0)); } void settimer () { /* set clock */ long clock(); TIMESAVE = clock(); CONSTRAINT_HANDLING_TIME = 0L; } #else #if CPUTIME == 0 /* do not print CPU-time */ void printtime () { } void settimer () { } #else /* BSD */ #include #include time_t TIMESAVE; /* system time saver (time_t = long) */ struct tms TIMES; /* cf. times() */ /* * Structure returned by old times() interface * struct tms { * time_t tms_utime; user time * time_t tms_stime; system time * time_t tms_cutime; user time, children * time_t tms_cstime; system time, children * }; */ void printtime () { /* print CPU time from the previous settime()*/ time_t ttemp; times(&TIMES); /* get time */ ttemp = TIMES.tms_stime + TIMES.tms_utime; tprint2 ("CPU time = %.3lf sec (Constraints Handling = %.3lf sec)\n", (ttemp - TIMESAVE) / (float)CPUTIME, (CONSTRAINT_HANDLING_TIME / (float)CPUTIME)); } void settimer() { /* set clock */ times(&TIMES); TIMESAVE = TIMES.tms_stime + TIMES.tms_utime; CONSTRAINT_HANDLING_TIME = 0L; } #endif #endif