🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.prolog
Article #4132

Challenge

#4132
From: fuchs
Date: Thu, 04 Jan 1990 10:26
128 lines
4419 bytes
Some weeks ago John G. Cleary (University of Calgary) wrote

  Recent postings about NU-Prolog and the use of delayed computation have
  reminded me of a problem which I have never quite been able to solve. The
  background is that in NU-Prolog it is possible to permute a list of objects
  with many different programs. For example a straightforward permute can be
  driven backward by instantiating its 'output' and seeing what appears on
  its 'input'. Similarly any sorting program can be driven backward to generate
  permutations. Well almost any sort program. It works fine for simple ones
  like insertion sort or merge sort. However, I tried to reverse quicksort
  and came across a problem. It goes into an infinite loop after giving the
  first solution and I was quite unable to concoct a set of delays which
  prevented this.

  The challenge is to use NU-Prolog (or some other Prolog with delays) to run
  quicksort backward ( and forward).

  ...

The following simple meta-interpreter delays goals that are not 'sufficiently'
instantiated. It will run quicksort forward and backward, will generate all
'unsorted' lists from a sorted one, and will not go into an infinite loop.

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

% prove(Goal) :-
% Goal is true with respect to the Prolog program being interpreted.
% The interpreter will only try to prove a goal if it is ready, i.e. 
% sufficiently instantiated.
% The interpreter transforms conjunctive goals into lists.
% MacProlog 2.5 version

prove(Goal) :-
  proveL([Goal]).

proveL(Goals) :- 
  remove(Ready,Goals,Goals_without_Ready),   %	pick a goal
  ready(Ready),                              %	is it ready ?
  !,                                         %	no backtracking
  prove_one(Ready,Goals_without_Ready).      %	prove the goal
proveL([]).                                  %	all done

prove_one(Goal,Goals) :-
  idef(Goal),                                %  user predicate 
  clause(Goal,Body),
  make_list(Body,Body_as_List),
  append(Body_as_List,Goals,NewGoals),
  proveL(NewGoals).
prove_one(Goal,Goals) :-
  sdef(Goal),                                %	system predicate
  call(Goal),
  proveL(Goals).
													

% make_list(Goals, Goals_as_List) :- Goals_as_List is a list whose  
% elements are the goals of the conjunctive goal Goals
make_list((A,B),[A|B_as_List]) :-
  make_list(B,B_as_List).
make_list(true,[]).
make_list(A,[A]) :-
  A \= (_,_),
  A \= true.


% ready(P) :- P is sufficiently instantiated to be executed
% not/1: no variables 
ready(not(P)) :- 
  !,
  varsin(P,[]).																								
% append/3: first or last argument must be instantiated
ready(append(Xs,Ys,Zs)) :- 
  !, 
  (nonvar(Xs); nonvar(Zs)).		
% partition/4: first and second or second, third and fourth arguments 
% must be instantiated
ready(partition(Xs, X, Littles,Bigs)) :-
  !,
  ((nonvar(Xs), nonvar(X)); (nonvar(X), nonvar(Littles), nonvar(Bigs))). 
% quicksort/2: first or last argument must be instantiated
ready(quicksort(Xs,Ys)) :- 
  !, 
  (nonvar(Xs); nonvar(Ys)).
% catch-all
ready(_).


% quicksort(Xs,Ys) :- the list Ys is an ordered permutation of the list Xs
quicksort([X|Xs],Ys) :-
  partition(Xs,X,Littles,Bigs),
  quicksort(Littles,Ls),
  quicksort(Bigs,Bs), 
  append(Ls,[X|Bs],Ys).
quicksort([],[]).

% partition(Xs,X,Littles,Bigs) :- the list Littles (Bigs) contains all
% elements of the list Xs that are not larger (larger) than X
partition([X|Xs],Y,[X|Ls],Bs) :- 
  X =< Y, 
  partition(Xs,Y,Ls,Bs).
partition([X|Xs],Y,Ls,[X|Bs]) :- 
  X >  Y, 
  partition(Xs,Y,Ls,Bs).
partition([],Y,[],[]).



The meta-interpreter prove/1 will generate all 'unsorted' lists without getting
into an infinite loop.


:-  prove(quicksort(Xs, [1, 2, 3]))

No1  Xs = [1, 2, 3]

No2  Xs = [1, 3, 2]

No3  Xs = [2, 1, 3]

No4  Xs = [2, 3, 1]

No5  Xs = [3, 1, 2]

No6  Xs = [3, 2, 1]

No more solutions


   --- nef (fuchs@ifi.unizh.ch)
Technical Details
Message-ID: <1990Jan4.102648.15154@gorgo.ifi.unizh.ch>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!mcsun!cernvax!chx400!unizh!gorgo!fuchs

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!mcsun!cernvax!chx400!unizh!gorgo!fuchs
From: fuchs@ifi.unizh.ch
Newsgroups: comp.lang.prolog
Subject: Challenge
Message-ID: <1990Jan4.102648.15154@gorgo.ifi.unizh.ch>
Date: 4 Jan 90 10:26:48 GMT
Sender: fuchs@gorgo.ifi.unizh.ch
Organization: University of Zurich, Department of Computer Science
Lines: 128