Related
I have a predicate check(Data,Res) that checksDats according to some rules and returns Res (a function result on Data, assuming Data answers to several criteria).
I have another function generate(N,Data) which generates a N-size Data.
My main program begins with generating many 1-size Data, then if none answered the criteria, we go on to 2-size Data and so on until we reach a certain M upper limit.
main(M):- next_number(N,M), generate(N,Data), check(Data,Res).
However, the program runs for very long time. I wanted to make sure it does not get stuck. For this, I wanted to print the generated Data each time before its being checked. But adding display did not assist, because it only actually displayed if the entire statement was true.
That's not what I want.
I want to keep track of the progran using display, similarly to System.out.println in Java.
Is there any other function that displays anyway? Or an idea how to use display in a way that will always display, regardless if the Data answered the criteria or not?
I thought to do:
(check(Data,Res) -> display(Data);display(Data)).
But I am not sure. Any ideas?
Your long process is likely to be within check - or more precisely, that check fails for most data, causing the system to backtrack repeatedly.
If you display a result in check, you'll have line upon line of tracing. Instead, you could add a write statement to generate, or even to your number generation:
main(M):-
next_number_and_tick(N,M),
generate(N,Data),
check(Data,Res).
next_number_and_tick(N,M) :-
next_number(N,M),
write('Tick - now doing '),
writeln(N).
Upon backtracking, the program will signal the data size it is now working on, giving you an idea of the volume of work it is doing.
The problem in the way you use display is that the entire statement must be true for it to display. Your idea of using "if-then" is good but not accurate. If you want to use it, you should "trick" prolog the following way:
new_check(Data,Res) :- (check(Data,Res) -> display('Victory!'),!; display('Failed Data: '), display(Data), nl, fail).
This way, if the check fails, you will get a report on which Data failed, and if it succeeded everything stops (assuming you want only 1 solution. If you want more, remoce the ! predicate).
Good day! I would like to ask for help in understanding Prolog code as well as learning how to extend its functionality. Based on my limited yet newbie knowledge of programming, the function of the first given code (is quite like a main file), everything originates from it and thus it is the first file that is run before calling any other function.
main.pl
printSequences([]).
printSequences([Sequence|Sequences]):-
writeln(Sequence),
printSequences(Sequences).
loadHelpers:-
['helpers'],
['part01'],
['part02'],
['part03'],
['part04'].
part01:-
readExtremePegSolitaireFile('test04.eps',_,Game),
printGame(Game),
columnsAndRows(Game).
part02:-
readExtremePegSolitaireFile('part01test01.eps',_,Game),
printGame(Game),
openSpaces(Game).
part03:-
readExtremePegSolitaireFile('test04.single.eps',_,Game),
printGame(Game),
setof(Moves,fewestMoves(Game,Moves),AllMoves),
writeln(moves),
printSequences(AllMoves).
part04:-
readExtremePegSolitaireFile('test04.eps',_,Game),
printGame(Game),
noIslands(Game).
I don't think I have any problems understanding the first given code above, but my problem is mostly with this second given code and how to go about manipulating other files. I can't seem to understand the prefix part (is this the definition of a list of lists?) Also am I correct that most of the other functions are declared in this helper file to make the code more organized?
helpers.pl
:- module( helpers,
[ readExtremePegSolitaireFile/3
, printGame/1
]
).
prefix([H],[]).
prefix([H|T],[H|PreT]):-
prefix(T,PreT).
readExtremePegSolitaireFile(File,Moves,Game):-
open(File,read,Input),
read(Input,Moves),
readGame(Input,Temp),
prefix(Temp,Game),
close(Input).
readGame(Input,[]):-
at_end_of_stream(Input),
!.
readGame(Input,[Row|Rows]):-
\+ at_end_of_stream(Input),
read(Input,Row),
readGame(Input,Rows).
printGame(Game):-
writeln(game),
printRows(Game).
printRows([]).
printRows([Row|Rows]):-
writeln(Row),
printRows(Rows).
Last is a peg solitaire board that is given with the first line being the list of moves performed and the following lines are the board declarations (1,2,3,4 - players, x - peg, and '-' as empty spaces)
test04.eps
[r,d,u,r,l,l,l,d,l,u,r,r].
[2,-,x,x,x,x,x].
[x,x,-,x,-,x,x].
[x,3,x,-,x,-,x].
[x,-,4,x,x,x,x].
[x,x,-,x,x,-,x].
[x,x,x,1,-,x,x].
[x,x,x,x,x,x,x].
I would like to know how one would be able to calculate the number of columns and rows via a query columnsAndRows(Game). My first plan of action was to use something like this: (Which would be able to calculate the length of the rows by counting each element in the list however, it seems to have calculated all the elements in the list. 2 things that I noticed was:
It didn't stop at the end of the row
Apparently it didn't print the entire board, it was missing the last line of the board!
columnsAndRows(Game) :-
flatten(Game, FlatList),
length(FlatList,FlatListSize),
writeln(FlatListSize).
?- [a04tests].
?- loadHelpers.
?- part01.
game
[2,-,x,x,x,x,x]
[x,x,-,x,-,x,x]
[x,3,x,-,x,-,x]
[x,-,4,x,x,x,x]
[x,x,-,x,x,-,x]
[x,x,x,1,-,x,x]
42
true
I'm honestly really lost and I'd appreciate any guidance as to where to begin, or even a process flow for this program. Many thanks!
I saw the below threads and they are very useful and related to my problem
Writing in file | Swi-Prolog | Windows\
Prolog insert, modify and delete facts on a separated database text file
I tried to use tell, told see , seen to read write from text files but I have the same result nothing is written on the file when (I open it and see that) , and on the read either the system read end_of_file or have an error displayed in a message or on the console
Below is some samples of my work :
start1:-
open('output.txt',write,OS),
X = 'Hi all',
write(OS,X),
close(OS),
open('output.txt',read,OS2),
read(OS2,Input).
start1:-
absolute_file_name('X.data',Abs),
open(Abs,write,Out),
tell(Abs),
write('HiAll'),
told,
close(Out),
open(Abs,read,In),
see('X.data'),
read(X),
seen,
write(X).
Thank you very much #CapelliC the below code , which I wrote it , works fine
the read built-in predicate used to read terms and when reach to end of file it shows an error , instead I used read_line_to_codes
readfacts:-
open('output.txt',read,In),
repeat,
read_line_to_codes(In,X),writef(" "),
writef(X),nl,
X=end_of_file,!,
nl,
close(In).
writefacts:-
open('output.txt',write,Out),
write(Out,'Age(Peter,30)'),
write(Out,'Skin(Smith,Black).'),
close(Out).
I'm using SWI-Prolog interactively. When I run my query, I get a prefix of the output and the rest is taken off (marked using the string ...|...). Is this normal or should I go back and fix my program?
The number of items shown is controlled by a prolog flag.
You can remove it by issuing
remove_max_depth:-
current_prolog_flag(toplevel_print_options,Options),
select(max_depth(_), Options, NOptions)->
set_prolog_flag(toplevel_print_options, NOptions); true.
Nothing to worry about. It's just abbreviating it visually... just press 'w' (write) to display the complete internal representation of the list.
this is my code currently, I am trying to solve the zebra puzzle.
exists(A,(A,_,_,_,_)).
exists(A,(_,A,_,_,_)).
exists(A,(_,_,A,_,_)).
exists(A,(_,_,_,A,_)).
exists(A,(_,_,_,_,A)).
rightOf(A,B,(B,A,_,_,_)).
rightOf(A,B,(_,B,A,_,_)).
rightOf(A,B,(_,_,B,A,_)).
rightOf(A,B,(_,_,_,B,A)).
middleHouse(A,(_,_,A,_,_)).
firstHouse(A,(A,_,_,_,_)).
nextTo(A,B,(B,A,_,_,_)).
nextTo(A,B,(_,B,A,_,_)).
nextTo(A,B,(_,_,B,A,_)).
nextTo(A,B,(_,_,_,B,A)).
nextTo(A,B,(A,B,_,_,_)).
nextTo(A,B,(_,A,B,_,_)).
nextTo(A,B,(_,_,A,B,_)).
nextTo(A,B,(_,_,_,A,B)).
:- Houses = (house(N1,P1,S1,D1,C1),house(N2,P2,S2,D2,C2),house(N3,P3,S3,D3,C3),house(N4,P4,S4,D4,C4),house(N5,P5,S5,D5,C5)),
exists(house(english,_,_,_,red),Houses),
exists(house(spainish,dog,_,_,_),Houses),
exists(house(_,_,_,coffee,green),Houses),
exists(house(ukrainian,_,_,tea,_),Houses),
rightOf(house(_,_,_,_,green),house(_,_,_,_,ivory),Houses),
exists(house(_,dog,oldgold,_,_),Houses),
exists(house(_,_,kools,_,yellow),Houses),
middleHouse(house(_,_,_,milk,_),Houses),
firstHouse(house(norwegian,_,_,_,_),Houses),
nextTo(house(_,_,chesterfields,_,_),house(_,fox,_,_,_),Houses),
nextTo(house(_,_,kools,_,_),house(_,horse,_,_,_),Houses),
exists(house(_,_,luckystike,orangejuice,_),Houses),
exists(house(japanise,_,parliments,_,_),Houses),
nextTo(house(norwegian,_,_,_,_),house(_,_,_,_,blue),Houses),
exists(house(WaterDrinker,_,_,water,_),Houses),
exists(house(ZebraOwner,zebra,_,_,_),Houses).
I have typed this up and saved it as zebra.pl, this I open it and enter [zebra] into SWI-prolog, it returns a warning message about the singleton use of N1,P1,C1 etc.. and returns true, then i ask it to print water drinker using print(WaterDrinker) and it returns _G317 and true,
why is it doing this and not returning the answer which could be norwegian, it does the same if i ask it return any variable like C3 or ZebraOwner
The main problem is that you cannot write a goal like :- Houses = ... in the middle of your program. Rather, you should write something like
solution(WaterDrinker, ZebraOwner) :-
Houses = ...
and then after the program has been loaded type
solution(W, Z).
at the -? prompt to compute the solution.
You also don't specify that all the values should be distinct. If you do that you will use the variables a second time and the warning will go away.
If you really need a variable only once you can prepend it with an underscore to make the warning go away. Or you can just use an underscore, like you already did many times.