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
********************