[comp.lang.prolog] PROLOG Digest V5 #65

PROLOG-REQUEST@SUSHI.STANFORD.EDU.UUCP (09/24/87)

PROLOG Digest            Friday, 25 Sep 1987       Volume 5 : Issue 65

Today's Topics:
                    LP Library - window & stdlist
----------------------------------------------------------------------

Date: Sun, 13 Sep 87 22:44:22 PDT
From: Edouard Lagache <lagache@violet.Berkeley.EDU> 
Subject: window.pro

/* FILE: WINDOW.PRO */
/******************************************************************************/
/*                                                                            */
/*          TIPC window device input/output predicate definition file         */
/*                                                                            */
/*          This file contains predicates to operate the 'WINDOW.SYS' device  */
/*      developed by Greg Haley of Texas Instruments.  These predicates       */
/*      can (and probably should be used) with the 'ansi_io.pro' headers file */
/*      since standard ANSI terminal codes can also be used to manipulate the */
/*      windows.  These predicates only handle the window manipulation that   */
/*      cannot be done with 'ansi_io.pro'                                     */
/*                                                                            */
/*                  E. Lagache,  Version - 1.01,  July  - 1987                */
/*                   Copyright(C) 1987, ALL RIGHTS RESERVED                   */
/*                                                                            */
/*                                                                            */
/*       NOTE: This file has been designed for use with A.D.A. PROLOG.        */
/*                                                                            */
/******************************************************************************/

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'change_window' changes the active window. */
/*  the numerical argument is the number of    */
/*  the window in their order of creation.     */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Mar - 87     */
/* * * * * * * * * * * * * * * * * * * * * * * */
change_window(Number) :- prtstr("[Wa"),write(Number),prtstr("w").

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'close_window' closes last opened window.  */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Mar - 87     */
/*                                             */
/* Note: windows can only be closed in the     */
/*       reverse order of their creation.      */
/* * * * * * * * * * * * * * * * * * * * * * * */
close_window:- prtstr("[Wcw").

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'end_window' returns control to the 'CON:' */
/*  device.  Note that it is best to close all */
/*  all windows before issuing this command.   */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Mar - 87     */
/* * * * * * * * * * * * * * * * * * * * * * * */
end_window :- prtstr("[Wew").

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'make_window' creates a window of desired  */
/*  size.  The parameters are: starting row    */
/*  and column, number of rows and columns in  */
/*  window.                                    */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Mar - 87     */
/* * * * * * * * * * * * * * * * * * * * * * * */
make_window(St_row,St_col,Row_tall,Col_width) :- prtstr("[Wo"), write(St_row),
                                                 put(59),write(St_col),put(59),
                                                 write(Row_tall),put(59),
                                                 write(Col_width),prtstr("w").

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'start_window' sets the standard output    */
/*  device to be '_WINDOWS' instead of 'CON:'  */
/*  this command must be directed to the       */
/*  '_WINDOWS' device.                         */
/*                                             */
/*     E. Lagache,  Vers. - 1.10, Jul - 87     */
/* * * * * * * * * * * * * * * * * * * * * * * */
start_window :- tell('_WINDOWS'), prtstr("[Wbw"), tell(user).

/* End file: WINDOW.PRO */

------------------------------

Date: Sun, 13 Sep 87 22:43:54 PDT
From: Edouard Lagache <lagache@violet.Berkeley.EDU> 
Subject: stdlist.pro

/* file: STDLIST.PRO */
/******************************************************************************/
/*                                                                            */
/*          PROLOG Standard Library of List Manipulation Predicates           */
/*                                                                            */
/*           This library contains a collection of predicates commonly found  */
/*      in languages like LISP to facilitate the use of lists as a data       */
/*      structure.                                                            */
/*                                                                            */
/*               E. Lagache,  Version - 1.10,  July - 1987                    */
/*                   Copyright(C) 1987, ALL RIGHTS RESERVED                   */
/*                                                                            */
/******************************************************************************/

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'assoc' is true if there is sublist in     */
/*  first argument whose 'car' is equal to the */
/*  second argument.  This can be used to      */
/*  implement variable bindings.               */
/*                                             */
/*  Inspired by similar function in Franz LISP */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Feb - 87     */
/*                                             */
/*  Note 1: This predicate will find all such  */
/*          sublists                           */
/*  Note 2: The 'make_assoc_list' predicate    */
/*          in this library is a convenient    */
/*          way to build these sort of lists.  */
/* * * * * * * * * * * * * * * * * * * * * * * */
assoc(_,[],error):- !,fail.  /* Base recursive case, No such element found */
assoc(Item,[Pair|_],Pair):- found_item(Pair,Item).    /* Successful match */
assoc(Item,[_|Rest],Pair):- assoc(Item,Rest,Pair).    /* Continue search */

found_item([Item|_],Item).        /* test if 'car' of list is 'Item' */

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'append' combines two lists into a single  */
/*  list.                                      */
/*                                             */
/*  From Clocksin and Mellish p 63             */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Nov - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
append([],List,List). /* Base recursive case */
/* Transfer elements from list1 to list3 */
append([Item|Tail1],List2,[Item|Tail3]):- append(Tail1,List2,Tail3).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'delete' is a predicate with two forms:    */
/*      1.) delete all occurrences of an item.  */
/*      2.) delete first N occurrences of an    */
/*          item.                              */
/*                                             */
/*  form 1 takes arguments:                    */
/*      delete(Item, List, Result).            */
/*  form 2 takes arguments:                    */
/*      delete(Item, List, N, Result).         */
/*                                             */
/*  Form 1 is from Clocksin and Mellish p 151  */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Dec - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
/*** FORM-1 ***/
delete(_,[],[]).     /* Base case: no list to delete from */
/* found an occurrence, remove item */
delete(Item, [Item|List], Result):- !, delete(Item,List,Result).
/* 'Head' not item, so copy to 'Result' list */
delete(Item, [Head|List], [Head|Result]):- !, delete(Item,List,Result).

/*** FORM-2 ***/
        /* Base case1: deleted correct number of times */
delete(Item,[Item|Result],1,Result):- !.
delete(_,[],_,[]):- !.   /* Base case2: no list to delete from */
/* found an occurrence, remove item and decrement counter */
delete(Item, [Item|List], Number, Result):- !, Next is Number-1,
                                               delete(Item,List,Next,Result).
/* 'Head' not item, so copy to 'Result' list */
delete(Item, [Head|List], N, [Head|Result]):- !, delete(Item,List,N,Result).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'flatten' eliminates any sublists in the   */
/*  first argument, and returns a list with    */
/*  all elements in the top level.             */
/*                                             */
/*  Solution to assignment 3.11 (Bratko).      */
/*                                             */
/*  Note: this function is doubly recursive    */
/*        and uses the recursive 'append';     */
/*        thus it is computationally expensive.*/
/*                                             */
/*     E. Lagache,  Vers. - 1.01, Jul - 87     */
/* * * * * * * * * * * * * * * * * * * * * * * */
flatten([],[]):- !.     /* Base case */
flatten([Head|T],X):- listp(Head),flatten(Head,Y), /* Element a list? flatten */
                   flatten(T,Z),append(Y,Z,X),!.   /* Append list together */
flatten([Head|T],[Head|X]):- flatten(T,X),!.       /* Else 'cdr' down list */

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'get_head' returns the first 'Number' of   */
/*  elements in 'List'.  If the list is        */
/*  smaller than 'Number', then the whole list */
/*  is returned.                               */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Dec - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
get_head(List,0,[]):- !. /* Reached end of index */
get_head([],_,[]):- !.  /* Reached end of list */
/* Transfer current first element of list to list of heads */
get_head([Head|Tail],Index,[Head|Result]):- Next is Index-1,
                                     get_head(Tail,Next,Result).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'get_index' returns the places in the      */
/*  'List' where 'Element' is located (i.e.    */
/*  'get_index(b,[a,b,c],X) returns X=2).      */
/*  If 'Element' is not found predicate fails. */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Dec - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
/* Call internal function */
get_index(Element,List,Index):- int_get_index(Element,List,Index,1).
int_get_index(Element,[],_,_):- !,fail. /* if an empty list is found, fail */
int_get_index(Element,[Element|_],Result,Result).     /* if found return */
/* Else "cdr" down list */
int_get_index(Element,[_|Tail],Result,Index):- Next is Index+1,
                                        int_get_index(Element,Tail,Result,Next).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'get_tail' returns the number of elements  */
/*  counting from the end of the list.  If the */
/*  list is smaller than the number, the whole */
/*  list is returned.                          */
/*                                             */
/*  Note: 'get_tail' uses 'nthcdr' to access   */
/*         the desired elements.               */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Dec - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
/* Return list if requested size is larger than list */
get_tail(List,Index,List):- length(List,Length), Length < Index, !.
get_tail(List,Index,Answer):- length(List,Length), Count is Length-Index,
                              nthcdr(List,Count,Answer).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'nthcdr' returns the remainder of the list */
/*  after removing the first 'N' elements.     */
/*  If there are less elements than 'N', the   */
/*  empty list is returned.                    */
/*                                             */
/*  Inspired by the analog function of Franz   */
/*  LISP.                                      */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Dec - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
nthcdr(Tail,0,Tail).   /* Finished index base case */
nthcdr([],_,[]):- !,fail.   /* Empty list base case, fail*/
/* Remove elements */
nthcdr([_|Tail],Index,Result):- Next is Index-1, nthcdr(Tail,Next,Result).


/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'last' returns the last element of the     */
/*  list.                                      */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Nov - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
last([Element],Element):- !.
last([_|Rest],Element):- last(Rest,Element).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'length' returns the number of elements    */
/*  in the top level of the list.              */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Nov - 86     */
/*                                             */
/*  Note: Length is already supplied by most   */
/*  PROLOGs (including A.D.A. PROLOG)          */
/* * * * * * * * * * * * * * * * * * * * * * * */
/* length([],0).  */
/* length([_|Tail], NewLength):- length(Tail,OldLength), */
/*                              NewLength is OldLength+1. */

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  Definition of a list 'listp'.              */
/*                                             */
/*     E. Lagache,  Vers. - 1.01, Dec - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
listp([]).
listp([_|_]).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'make_assoc_list' combines two lists with  */
/*  the same number of elements so that the    */
/*  elements of the two lists are paired by    */
/*  order.  Predicate fails in lists are not   */
/*  of the same length.  This predicate is     */
/*  identical to the 'merge' predicate except  */
/*  that it stores each pair in a sublist.     */
/*                                             */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Jul - 87     */
/* * * * * * * * * * * * * * * * * * * * * * * */
make_assoc_list([],[],[]).
make_assoc_list([],List2,List2):- !, fail. /* Cases where list length is not */
make_assoc_list(List1,[],List1):- !, fail. /* equal - fail. */
/* Merge by taking heads from both lists and placing on merged list */
make_assoc_list([Head1|Tail1],[Head2|Tail2],[[Head1,Head2]|R]):-
                                        make_assoc_list(Tail1,Tail2,R), !.


/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'member' determines if 'Element' is a      */
/*  member of 'List'.                          */
/*                                             */
/*  From Clocksin and Mellish p 55             */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Nov - 86     */
/*                                             */
/* Note: 'member' is supplied by A.D.A. PROLOG */
/* * * * * * * * * * * * * * * * * * * * * * * */
/* member(Element,[Element|_]). */
/* member(Element,[_|Tail]):- member(Element,Tail). */

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'merge' combines two lists with the same   */
/*  same number of elements so that the        */
/*  elements of the two lists are paired by    */
/*  order.  Predicate fails in lists are not   */
/*  of the same length.                        */
/*                                             */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Nov - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
merge([],[],[]).
merge([],List2,List2):- !, fail.      /* Cases where list length is not equal */
merge(List1,[],List1):- !, fail.
/* Merge by taking heads from both lists and placing on merged list */
merge([Head1|Tail1],[Head2|Tail2],[Head1,Head2|R]):- merge(Tail1,Tail2,R), !.

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'nthelem' returns the element in the       */
/*  'Index' place of the list.                 */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Dec - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
nthelem([],_,error):- !, fail.  /* fail if list is smaller than index */
nthelem([Item|_],1,Item):- !.   /* return item */
nthelem([X|Rest],NewIndex,Item):- Index is NewIndex-1,nthelem(Rest,Index,Item).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'quicksort' uses the quicksort algorithm   */
/*  to order a list of items.  Two forms are   */
/*  provided:                                  */
/*  1.) Sort based on numerical ranking.       */
/*  2.) Sort based on some comparison          */
/*      predicate 'Pred'.                      */
/*                                             */
/*  Form 1 is from Clocksin and Mellish p 157  */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Nov - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
/*** FORM-1 ***/
/* Call internal function */
quicksort(Unsort,Result):- quisort1(Unsort,Result,[]).
/* Break problem up, and solve recursively */
quisort1([Item|Tail],Sort,Partial1):- split1(Item,Tail,Part1,Part2),
                                     quisort1(Part2,Partial2,Partial1),
                                     quisort1(Part1,Sort,[Item|Partial2]).
quisort1([],Sort,Result):- !,Sort=Result.

/* Partition list */
split1(Item,[Head|List],[Head|Small],Big):- Head =< Item,
                                            split1(Item,List,Small,Big).
split1(Item,[Head|List],Small,[Head|Big]):- Head > Item,
                                            split1(Item,List,Small,Big).
split1(_,[],[],[]).

/*** FORM-2 ***/
quicksort(Unsort,Pred,Result):- quisort2(Unsort,Pred,Result,[]).
/* Break problem up, and solve recursively */
quisort2([Item|Tail],Pred,Sort,Partial1):- split2(Item,Tail,Pred,Part1,Part2),
                                    quisort2(Part2,Pred,Partial2,Partial1),
                                    quisort2(Part1,Pred,Sort,[Item|Partial2]).
quisort2([],_,Sort,Result):- !,Sort=Result.

/* Partition list */
split2(Item,[Head|List],Pred,Small,[Head|Big]):- Test =.. [Pred,Head,Item],
                                                 call(Test),
                                            split2(Item,List,Pred,Small,Big).
split2(Item,[Head|List],Pred,[Head|Small],Big):- Test =.. [Pred,Head,Item],
                                                 not(call(Test)),
                                            split2(Item,List,Pred,Small,Big).
split2(_,[],_,[],[]).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'reverse' reverses the order of elements   */
/*  in a list.                                 */
/*                                             */
/*  From Clocksin and Mellish p 150            */
/*                                             */
/*     E. Lagache,  Vers. - 1.01, Dec - 86     */
/*                                             */
/*  Note: 'List' must be instantiated for      */
/*  predicate to operate.                      */
/* * * * * * * * * * * * * * * * * * * * * * * */

reverse(List, Result):- int_rev(List,[],Result), !. /* Call to int. function */
/* move items one at a time */
int_rev([Item|Tail1],Partial,Result):- int_rev(Tail1,[Item|Partial],Result).
int_rev([],Result,Result).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'shift_l' cyclically moves the list        */
/*  elements to the left by putting the head   */
/*  of the list at the tail.                   */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Dec - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
shift_l([Head|Tail],Result):- append(Tail,[Head],Result).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'shift_r' cyclically moves the list        */
/*  to the right by putting the last element   */
/*  on the head of the list.                   */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Dec - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
shift_r(List,[End|Tail]):- last(List,End),delete(End,List,Tail).

/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'subst' is a predicate with two forms:     */
/*      1.) substitute for all occurrences of  */
/*          an item.                           */
/*      2.) substitute for the first N         */
/*          occurrences on an item.            */
/*                                             */
/*  form 1 takes arguments:                    */
/*   subst(Item, replacement, List, Result).   */
/*  form 2 takes arguments:                    */
/*   subst(Item, replacement, List, N, Result).*/
/*                                             */
/*  Form 1 is from Clocksin and Mellish p 151  */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Dec - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
/*** FORM-1 ***/
subst(_,_,[],[]).     /* Base case: no list to substitute in */
/* found an occurrence, remove item */
subst(Item, Repl, [Item|List], [Repl|Result]):- !, subst(Item,Repl,List,Result).
/* 'Head' not item, so copy to 'Result' list */
subst(Item, Repl, [Head|List], [Head|Result]):- !, subst(Item,Repl,List,Result).

/*** FORM-2 ***/
subst(_,_,Result,0,Result):- !./* Base case 1: subst correct number of times */
subst(_,_,[],_,[]):- !.   /* Base case 2: no list to subst from */
/* found an occurrence, remove item and decrement counter */
subst(Item,Repl,[Item|List],N,[Repl|Result]):- !, Next is N-1,
                                              subst(Item,Repl,List,Next,Result).
/* 'Head' not item, so copy to 'Result' list */
subst(Item,Repl,[Head|List],N,[Head|Result]):- !,subst(Item,Repl,List,N,Result).


/* * * * * * * * * * * * * * * * * * * * * * * */
/*  'sumlist' returns the summation of all     */
/*  numbers on list 'list'.  Predicate returns */
/*  false if list contains atoms that are not  */
/*  numbers.                                   */
/*                                             */
/*     E. Lagache,  Vers. - 1.00, Dec - 86     */
/* * * * * * * * * * * * * * * * * * * * * * * */
sumlist([],0).      /* Base case */
sumlist([Number|Tail],Result):- sumlist(Tail,OldResult),
                                Result is Number + OldResult.

/* End file: STDLIST.PRO */

------------------------------

End of PROLOG Digest
********************