Prolog output message understanding - prolog

This is a really quick one, I don't know the correct way to google it!
Say we have an output such it gives:
X = [4|_1218]
what generally has to be changed to get the output just to say 4?
member1(Head, [Head|_]):-!.
member1(Item, [_|Tail]):-
member1(Item, Tail).
findnotin([Head|_], RuledOut, [Head|_]):-
not(member1(Head, RuledOut)).
Edit Completedish program:
find_not_in([], _, _).
find_not_in([Head|Candidates], RuleOut, [Head|Legal]):-
not(member1(Head, RuleOut)),
find_not_in(Candidates, RuleOut, Legal).
find_not_in([_|Candidates], RuleOut, Legal):-
find_not_in(Candidates, RuleOut, Legal).

Related

Prolog Tube Line Task

i have an assignment to make a simplified metro tube map in prolog, one part is asking to make a rule to check if two stations are on the same line, ive got a rule but it doesnt seem to work this is what i have so far:
adjacent(nh,lg,central,4).
adjacent(lg,oc,central,4).
adjacent(oc,tc,central,4).
adjacent(tc,cl,central,4).
adjacent(cl,ls,central,4).
adjacent(ls,bg,central,4).
adjacent(br,vi,victoria,4).
adjacent(vi,oc,victoria,4).
adjacent(oc,ws,victoria,4).
adjacent(ws,kx,victoria,4).
adjacent(kx,fp,victoria,4).
adjacent(ke,em,northern,4).
adjacent(em,tc,northern,4).
adjacent(tc,ws,northern,4).
adjacent(ws,eu,northern,4).
adjacent(al,ls,metropolitan,4).
adjacent(ls,kx,metropolitan,4).
adjacent(kx,bs,metropolitan,4).
adjacent(bs,fr,metropolitan,4).
adjacent(ec,em,bakerloo,4).
adjacent(em,oc,bakerloo,4).
adjacent(oc,pa,bakerloo,4).
adjacent(pa,wa,bakerloo,4).
next(X,Y,L):-adjacent(X,Y,L,_).
next(X,Y,L):-adjacent(Y,X,L,_).
direct_connect(X,Y,L,S,F):-
next(X,Z,L),
not(member(Z,S)),
direct_connect(Z,Y,L,[Z|S],F).
direct_connect(X,Y,L,S,[Y|S]):- next(X,Y,L).
one_change(X,Y,L,F):-
direct_connect(X,Z,L,[X],F1),
direct_connect(Z,Y,L2,[Z|F1],F),
L\=L2.
exist(X):-next(X,_,_).
member(X,[X|_]).
member(X,[_|T]):-member(X,T).
route(X,Y,F):-exist(X),exist(Y),
direct_connect(X,Y,_,[X],F),
write('Direct Connection'),nl,
revwrite(F).
route(X,Y,F):-exist(X),exist(Y),
one_change(X,Y,_,F),
write('One change required'),nl,
revwrite(F).
revwrite([X]):-write(X).
revwrite([H|T]):-revwrite(T), write('->'),write(H).
and the rule;
sameLine(Stat1, Stat2, Line) :-
station(Stat1, Line),
station(Stat2, Line),
Stat1 \= Stat2.
sorry for the unclear and no code propey posted, posting from phone :/

Why does this Prolog code not write my list to a file?

The following rules should write my List to a stream associated with a file, but instead it is a never ending stream of incomprehensible characters. Help.
writeListToFile(List, File) :- open(File, write, Stream),
\+ writeListToStream(Stream, List),
close(Stream).
writeListToStream(Stream, List) :- member(Element, List),
write(Stream, Element),
write(Stream, ' '),
fail.
This occurs even when using a simple list like
List = ['a', 'b'].
Upon executing
writeListToFile(List, 'output.txt').
my SWI-Prolog does not respond and I see the file filling up with endless lines of
"_G889 _G892 _G895 _G898 _G901 _G904 _G907 _G910 _G913 _G916 _G919
_G922 _G925 _G928 _G931 _G934 _G937 _G940 _G943 _G946 _G949 _G952 _G955 _G958 _G961 _G964 _G967 _G970 _G973 _G976 _G979 _G982 _G985 _G988 _G991 _G994 _G997 _G1000 _G1003 _G1006 _G1009 _G1012 _G1015 _G1018"
etc.

"strptime" in SWI-Prolog

How to convert atom '2015-12-15T05 PST' to timestamp or datetime?
I've tried parse_time/3
?- parse_time('2015-12-15T05 PST', '%Y-%m-%dT%H %Z', Stamp)
false.
and format_time/3
?- format_time('2015-12-15T05 PST', '%Y-%m-%dT%H %Z', date(Y,M,D,H,M,S,O,TZ,DST)).
ERROR: format_time/3: Arguments are not sufficiently instantiated
According to the documentation, the mode of format_time/3 can't really help you, because it's expecting everything to be passed in:
format_time(+Out, +Format, +StampOrDateTime)
This means you supply each of the arguments. You want to see something with a - prefix which means it's handing something back, which seems like it would mean parse_time/3, but there the documentation says:
Supported formats for Text are in the table below.
and it then proceeds to list exactly two options, rfc_1123 and iso_8601, neither of which really match your format. There does not seem to be a way to supply a format code here, which I find really puzzling, because there are underlying Unix libraries here that can certainly do this.
However, the problem can be solved with everyone's favorite tool: definite clause grammars! Here's my solution:
:- use_module(library(dcg/basics)).
myformat(date(Y,M,D,H,_,_,_,TZ,_)) -->
integer(Y), "-", integer(M), "-", integer(D),
"T", integer(H), " ", timezone(TZ).
timezone('UTC') --> "UTC".
timezone('UTC') --> "GMT".
timezone(-18000) --> "PST".
timezone(Secs) -->
[Sign], digit(H0), digit(H1), digit(M0), digit(M1),
{
(Sign = 0'+ ; Sign = 0'-),
number_codes(Hour, [H0,H1]),
number_codes(Minutes, [M0, M1]),
(Sign = 0'+
-> Secs is Hour * 3600 + Minutes * 60
; Secs is -(Hour * 3600 + Minutes * 60))
}.
my_time_parse(Atom, Date) :-
atom_codes(Atom, Codes),
phrase(myformat(Date), Codes).
I'm sure the learned will see ways to improve this code but it did the trick for me with your sample data. You will unfortunately need to either enumerate timezones or find a better source of data on them (perhaps parsing the system timezone definitions?) but if you know a-priori that you only need to handle PST, you can try it. Here's an example:
?- my_time_parse('2015-12-15T05 PST', Date).
Date = date(2015, 12, 15, 5, _G3204, _G3205, _G3206, -18000, _G3208) ;
false.
Hope this helps!
Coming late to this question: the desired format is close to iso_8601, which would take the format "2015-12-15T05-08". To replace the time zone " PST" with "-08", we can use append. For code:
:- set_prolog_flag(double_quotes, chars).
timezone(" PST", "-08").
timezone(" PDT", "-07").
%% etc
convert_time(Date, Stamp) :-
timezone(Zone, Delta),
append(Front, Zone, Date),
append(Front, Delta, Date2),
string_chars(Date3, Date2),
parse_time(Date3, iso_8601, Stamp).
test :-
convert_time("2015-12-15T05 PST", Stamp),
writeln('Stamp'=Stamp),
fail.
with output
?- test.
Stamp=1450184400.0
false.

Prolog Query Exercise - Beginner

I'm a begginer at Prolog and I need some help with this exercise, this is the knowledge base provided:
album(‘R. Stevie Moore’, ‘Manuscription’).
album(‘Lane Steinberg’, ‘Manuscription’).
album(‘R. Stevie Moore’, ‘The Yung & Moore Show’).
album(‘Yukio Yung’, ‘The Yung & Moore Show’).
album(‘Jessie Evans’, ‘Autonervous’).
album(‘Bettina Koster’, ‘Autonervous’).
album(‘Lucia Pamela’, ‘Walkin on the moon’).
album(‘Shooby Taylor’, ‘The Human Horn’).
album(‘Tiny Tim’, ‘God Bless Tiny Tim’).
album(‘The Legendary Stardust Cowboy’, ‘Rock-It to Stardom’).
vinil(‘Rock-It to Stardom’).
vinil(‘Walking on the Moon’).
cd( ‘God Bless Tiny Tim’).
cd(‘Walking on the Moon’).
cd(‘Autonervous’).
cd(‘Manuscription’).
cassette(‘The Human Horn’).
cassette(‘The Yung & Moore Show’).
mp3(‘Walkin on the Moon’).
I need to make a query that will return to me all the albums that were made by only one musician.
Thanks for your help :)
In the comments you have provided your code album(X,B),album(Y,C), B \= C. Actually, this is not too far away from a correct solution.
A correct solution could be:
one_musician_album(X) :-
album(A, X),
\+ (album(B, X), A \= B).
The meaning of the predicate is: an album X is a "one-musician album" if this album is authored by some musician A and it's not possible to find a different musician B authored the album X.
Test run:
?- one_musician_album(X).
X = 'Walkin on the moon' ;
X = 'The Human Horn' ;
X = 'God Bless Tiny Tim' ;
X = 'Rock-It to Stardom'.
To get all answers you have to type ';' after each answer.
Maybe this is not needed for you, but it's possible to get all answers in a list with findall:
?- findall(X, one_musician_album(X), Albums).
Albums = ['Walkin on the moon', 'The Human Horn', 'God Bless Tiny Tim', 'Rock-It to Stardom'].
Here is a generalization, based on 'all solutions' builtin bagof/3.
Note that
?- bagof(A, album(A,T), As).
T = 'Autonervous',
As = ['Jessie Evans', 'Bettina Koster'] ;
T = 'God Bless Tiny Tim',
As = ['Tiny Tim']
....
then, restricting the authors (As) to be a list of a single element, we get albums with a single author
?- bagof(A, album(A,T), [A]).
A = 'Tiny Tim',
T = 'God Bless Tiny Tim' ;
...
then, we could use findall/3, as in the good answer by Sergey, or, again, bagof/3, with explicit quantification:
?- bagof(T, A^bagof(A, album(A, T), [A]), Ts).
Ts = ['God Bless Tiny Tim', 'Rock-It to Stardom', 'The Human Horn', 'Walkin on the moon'].

DCG output single variable instead of whole clause in a list

I have a problem, while creating a question answer Prolog file. I have a database with locations and I can already get the question and write the answer out. But there are different types of objects, that require different prefixes. So I defined DCG for prefixes.
answer(P,A) :- location(P, Str, Nr),A = [there, is, article(G,K,N,P), noun(G,K,N,P), pre(P),Str,Nr].
question(A) --> questionsentence(P),{answer(P,A)}.
pre(P) --> [in, P], {member(P, [road66])}.
pre(P) --> [at, P], {member(P, [trafalgarsquare])}.
but what i get is something like this:
?-question(A, [where,is,a,kentuckys],[]).
A = [there, is, article(_G2791, _G2792, _G2793, kentuckys), noun(_G2791, _G2792, _G2793, kentuckys), prep(kentuckys), road66, 123]
This works for verifying the input properly, but it seems to be useless for the output. How can I take just the variable and not the clause?
OK, I tried to translate the whole program to a more or less usefull and working example.
location(kentuckys, road66, 121).
location(soliver, trafalgarsquare, 15).
location(marcopolo, trafalgarsquare, 15).
location(internist, jumpstreet, 21).
questionsentence(P,G) --> [where],[is], article(G), noun(G,P).
answer(P,A,G) :- location(P, Str, Nr), prep(W,Str), article(G,Art,[]), flatten([there, is, Art, P, W, Str,Nr], A).
question(A) --> questionsentence(P,G),{answer(P,A,G)}.
article(m) --> [a].
article(f) --> [an].
noun(m, P) --> [P], {member(P, [kentuckys, soliver, marcopolo])}.
noun(f, P) --> [P], {member(P, [internist])}.
prep([at],Str) :- member(Str, [trafalgarsquare, road66]).
prep([in],Str) :- member(Str, [jumpstreet]).
Result:
?- question(A, [where,is,a,kentuckys],[]).
A = [there, is, a, kentuckys, at, road66, 121] .
I think, what I looked for was a construction like: article(G,Art,[]) to determine the depending DCG variable... actually I do not fathom yet how the two last arguments are working...

Resources