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