Related
Good morning, I'm learning prolog.
But I already searched, but I didn't find a solution, it must be very simple, but I got stuck
I created a database like the following
data base([
movie(["Titanic"], [["Jack", "Dawson"] ,["Rose", "DeWitt", "Bukater"]], ["James","Cameron"] ),
movie(["Hulk"], [["Bruce", "Banner"] ,["Betty", "Ross"]], ["Ang","Lee"] )
]).
This database contains the name of the film, the name of the main characters and then the director.
The goal would be to create a function:
Example
find_movies_by_character("Bruce Banner")
Need return Titanic
I imagine something might be wrong, I'm open to new ideas
data base([ with that space in it, doesn't seem to be valid syntax in SWI Prolog. Wherever did you get that from?
This database contains the name of the film, the name of the main characters and then the director.
More specifically, the database contains a list containing movie terms, each containing a list containing the name of the film and (a list containing lists of parts of names of the main characters) and (a list containing parts of names of directors).
From how complicated it is to write out, it will be at least that complicated to work with. If you can simplify it, it will get easier to work with:
movie('Titanic', ['Jack Dawson', 'Rose DeWitt Bukater'], 'James Cameron').
movie('Hulk', ['Bruce Banner', 'Betty Ross'], 'Ang Lee').
find_movie_by_character(Character, MovieName) :-
movie(MovieName, Characters, _),
member(Character, Characters).
e.g.
?- find_movie_by_character('Bruce Banner', X).
X = 'Hulk'
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'm working on a text based adventure game in prolog. I'm trying to define something that prints out all the adjacent rooms and their descriptions, except when I try to use it it is printing duplicate items and their descriptions.
The definitions for adjacent_rooms is as follows:
adjacent_rooms(Location):-
is_connected(Location, AdjacentLocation),
name(AdjacentLocation, AdjacentName),
short_desc(AdjacentLocation, AdjacentDescription),
write(AdjacentName), write(': '), write(AdjacentDescription),nl,fail.
adjacent_rooms(_).
Below is the output when I call adjacent_rooms(bedroom).
?- adjacent_rooms(bedroom).
Your Bedroom's Closet: A cozy little room used for storing your valuables
Your Bedroom's Closet:
: A cozy little room used for storing your valuables
:
Hallway: Long pathway that has pictures hanging on wall
Hallway:
: Long pathway that has pictures hanging on wall
What is causing duplicate names and descriptions to be printed? Thanks.
Well, I'm a bit new to Prolog, so my question is on Prolog pattern/logic.
I have an relationship called tablet. It has many parameters, such as name, operationSystem, ramCapacity, etc. I have many objects/predicates of this relationship, like
tablet(
name("tablet1"),
operatingSystem("ios"),
ramCapacity(1024),
screen(
type("IPS"),
resolution(1024,2048)
)
).
tablet(
name("tablet2"),
operatingSystem("android"),
ramCapacity(2048),
screen(
type("IPS"),
resolution(1024,2048),
protected(yes)
),
isSupported(yes)
).
And some others similar relationships, BUT with different amounts of parameters. Some of attributes in different objects I do not need OR I have created some tablets, and one day add one more field and started to use it in new tablets.
There are two questions:
I need to use the most flexible structure as possible in prolog. Some of the tablets have attributes/innerPredicates and some do not, but They are all tablets.
I need to access data the easiest way, for example find all tablets that have ramCapacity(1024), not include ones that do not have this attributes.
I do need to change some attributes' values in the easiest way. For example query - change ramCapacity to 2048 for tablet that has name "tablet1".
If it's possible it should be pretty to read in a word editor :)
Is this structure flexible? Should I use another one? Do I need additional rules to manipulate this structure? Is this structure easy to change with query?(I keep this structure in a file).
Since the number of attributes is not fixed and needs to be so flexible, consider to represent these items as in option lists, like this:
tablet([name=tablet1,
operating_system=ios,
ram_capacity=1024,
screen=screen([type="IPS",
resolution = res(1024,2048)])]).
tablet([name=tablet2,
operating_system=android,
ram_capacity=2048,
screen=screen([type="IPS",
resolution = res(1024,2048)]),
is_supported=yes]).
You can easily query and arbitrarily extend such lists. Example:
?- tablet(Ts), member(name=tablet2, Ts).
Ts = [name=tablet2, operating_system=android, ram_capacity=2048, screen=screen([type="IPS", resolution=res(..., ...)]), is_supported=yes] ;
false.
Notice also the common Prolog naming_convention_to_use_underscores_for_readability instead of mixingCasesAndMakingEverythingExtremelyHardToRead.
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.