#include #include "ifrilc.h" /* * test_emb.c - example showing use of the Fril emebedded foreign language * interface. The main program displays a menu, reads a numerical option and * switches to call the appropriate function(s) from the Fril interface. Note * that little error checking is performed - return values from the Fril * interface functions such as createlist, putatom, etc are ignored, and it * is assumed that options are chosen in the correct order. * Most of this could be achieved more elegantly using the high-level interface */ output_fn(mesg) char* mesg; { printf("%s", mesg); return(1); } main() { int listid; int listid2; int listid3; int listid4; char pred[256]; char arg[256]; int output_fn(); int fril_ans = 1; static char *opts[] = /* create a "menu" of options */ {"initialise_fril", /* 0 */ "initialise_interface", /* 1 */ "run", /* 2 */ "re-run", /* 3 */ "append", /* 4 */ "reverse", /* 5 */ "other query", /* 6 */ "get results", /* 7 */ "share vars ?((sum 1 2 X)(pp X))" /* 8 */ }; int opt; while (fril_ans != FRIL_TERMINATE) { printf("\n"); /* display the options */ for (opt = 0; opt < 9; opt++) printf("option %d : %s\n", opt, opts[opt]); if (scanf("%d", &opt) == EOF) fril_ans = -2; /* read a value and switch to the appropriate * interface functions */ else switch (opt) { case 0: /* this must be called first */ if (initialise_fril() == 1) printf("initialised OK\n"); else printf("test_emb : warning - initialisation failed\n"); break; case 1: /* call this before a new goal */ initialise_interface(); break; case 2: /* call to execute or re-execute a goal */ case 3: for (fril_ans = FRIL_REQUEST_INPUT; fril_ans == FRIL_REQUEST_INPUT;) { // fril_ans = call_fril(arg, output_fn); /* send the query to fril */ fril_ans = call_fril("pp (shut up)", output_fn); /* send the query to fril */ fril_says(fril_ans); /* report the return value */ if (fril_ans == FRIL_REQUEST_INPUT) { if(fgets(arg, 255, stdin) == NULL) fril_ans = -2; } } break; case 4: /* create goal (append X Y (a b c)) */ createlist(&listid, 4); /* main list */ putatom(listid, 1, "append"); createlist(&listid2, 3); /* create list (a b c) */ putatom(listid2, 1, "a"); putatom(listid2, 2, "b"); putatom(listid2, 3, "c"); putlist(listid, 4, listid2);/* install as last argument */ putgoal(listid); /* note that arguments 2 and 3 are * uninstantiated variables */ break; case 5: /* create goal (reverse (a b c) X) */ createlist(&listid, 3); /* main list */ putatom(listid, 1, "reverse"); createlist(&listid2, 3); /* create list (a b c) */ putatom(listid2, 1, "a"); putatom(listid2, 2, "b"); putatom(listid2, 3, "c"); putlist(listid, 2, listid2); putgoal(listid); /* argument 3 is uninstantiated */ break; case 6: /* simple goal of the form */ scanf("%s", pred); /* read in the predicate */ scanf("%s", arg); /* and a single constant argument */ createlist(&listid, 2); putatom(listid, 1, pred); putatom(listid, 2, arg); putgoal(listid); break; case 7: /* print out the goal (with instantiations if * appropriate) */ get_all_elements_in_list(listid, 0); break; case 8: /* test of putarg function */ createlist(&listid, 2); /* main list */ putatom(listid, 1, "?"); createlist(&listid2, 2); /* create list (goal1 goal2) */ createlist(&listid3, 4); /* create goal (sum 1 2 X) */ createlist(&listid4, 2); /* create goal (pp X) */ putatom(listid3, 1, "sum"); putint(listid3, 2, 1); putint(listid3, 3, 2); putatom(listid4, 1, "pp"); putarg(listid3, 4, listid4, 2); putlist(listid2, 1, listid3); putlist(listid2, 2, listid4); putlist(listid, 2, listid2); putgoal(listid); /* argument 4 of list 3 = arg 2 of list 4is uninstantiated */ break; default: printf("input %d ignored - terminating\n", opt); fril_ans = -2; } } printf("main(test_emb): fril has terminated\n"); } /* * get_all_elements_in_list(id, indent) displays all the elements in the list * referenced by "id", indenting each element by "indent" spaces. This can be * used to display a goal to be passed to Fril either before or after * execution. */ get_all_elements_in_list(id, indent) int id; int indent; { int i; /* loop counter */ int len; /* stores the length of the list */ char buff[256]; /* used by "getatom" */ int integ; /* used by "getint" */ float flo; /* used by "getfloat" */ int newid; /* used by "getlist" */ int type; /* used by "getitemtype" */ int ind; /* loop counter for indenting */ if (getlistlen(id, &len)) /* find out how many elements there are */ { for (i = 1; i <= abs(len); i++) /* negative length indicates an * unterminated list (...|X) */ { printf("\n"); /* start on new line and indent appropriately */ for (ind = 0; ind++ < indent; putchar(' ')); printf("item %d is ", i); if (getitemtype(id, i, &type)) /* execute appropriate "get" * function, according to * argument type */ { switch (type) { case 1: /* constant */ if (getatom(id, i, buff)) printf("atom : %s ", buff); break; case 2: /* integer */ if (getint(id, i, &integ)) printf("integer : %d ", integ); break; case 3: /* float */ if (getfloat(id, i, &flo)) printf("float : %g ", flo); break; case 4: /* list - recursively print elements at * indent+2 */ if (getlist(id, i, &newid)) { printf("list"); get_all_elements_in_list(newid, indent + 2); } break; case 5: /* variable */ printf("uninstantiated variable "); break; default: printf("bad return value from getitemtype\n"); } } else printf("couldn't get item type\n"); } if (len < 0) printf("\nlist terminated by | X\n"); } else printf("couldn't get listlen\n"); } fril_says(ans) /* print message appropriate to return value * from call_fril */ int ans; { switch (ans) { case 1: printf("\nfril says yes\n"); break; case 0: printf("\nfril says no\n"); break; case -1: printf("\nfril says system reset\n"); break; case -2: printf("\nfril says goodbye I'm tired\n"); break; case -3: printf("\nfril says Actually I need input\n"); break; default: printf("\nfril returned %d\n", ans); } }