Related
trying to print a loop over x for values of q, but keep getting this syntax error. Can anyone help with this?
Because it's a vector/array, not a single value. You may try the following:
np.set_printoptions(precision=2)
print(f'x = {x} -> q = {q}')
You could also take a look at numpy.array2string function.
So I have database which looks something like:
DB = [
data([table, keyboard,cup, box,watch]),
data([green,red, yellow,white,blue]),
data([alex, john,sasha, sabrina, ben]),
data([coffee, tea, syrup, vodka, beer]),
data([bookA, bookB, bookC, bookD, bookE])
]
I would like to save DB as a fact. Then we should create a relation db_to_facts which finds all the facts.
Example:
data([true, false]).
data([dog,cat]).
Output:
db_to_facts(DB).
DB = [data([true, false]), data([dog, cat])].
What would be the cleanest way possible to achieve it?
Edit:
I think I got it:
db_to_facts(L) :- findall(data(X),data(X),L).
But if the database is empty, it will fail. How to make it return empty list?
In the beginning of your Prolog program, use the directive, dynamic(data/1).. This tells Prolog you have a dynamic database that can change over time and will still recognize the data(X) query even if there is no data.
Without the directive:
1 ?- data(X).
ERROR: Undefined procedure: data/1 (DWIM could not correct goal)
2 ?-
With the directive:
2 ?- dynamic(data/1).
true.
3 ?- data(X).
false.
And then your findall/3 call will yield [] if there is no data.
For sure, the usage of dynamic(data/1) is the best way. Just to let you know, there is another way to check if data/1 exists. You can use current_predicate/2 in this way:
db_to_facts(L):-
( current_predicate(data,_) -> findall(data(X),data(X),L) ; L = []).
If you compile it (you cannot use swish online, it gives No permission to call sandboxed ...) you get a warning saying that you should define data/1 but if you run the query anyway you get the empty list:
?- db_to_facts(L).
L = [].
It's not the cleanest way but it works :)
I don't know why this isn't working... here's the code.
cameToTheParty(date(15,9,2011), flor).
cameToTheParty(date(22,9,2011), marina).
cameToTheParty(date(15,9,2011), pablo).
cameToTheParty(date(22,9,2011), pablo).
cameToTheParty(date(15,9,2011), leo).
cameToTheParty(date(22,9,2011), flor).
cameToTheParty(date(15,9,2011), fer).
cameToTheParty(date(22,9,2011), mati).
cameToThePartyThatDay(Peoples, Date):-
bagof(X,cameToTheParty(Date,X),Peoples).
When I try
?- cameToThePartyThatDay(People,Day).
it says
People = [flor, pablo, leo, fer],
Day = date(15, 9, 2011) ;
People = [marina, pablo, flor, mati],
Day = date(22, 9, 2011).
But, when I try the following with a variable date's field, or an actual date, like...
member(X,cameToThePartyThatDay(People,date(15,9,2011))).
it just says
false.
The issue is that member is trying to find an element from the list cameToThePartyThatDay(People,date(15,9,2011)), which is not, in fact, a list.
What you want to do is:
cameToThePartyThatDay(People,date(15,9,2011)),
member(X,People).
... so that People is unified with the list of people who came to the party that day, and then member can pull elements from the list of People.
member(X,cameToThePartyThatDay(People,date(15,9,2011)))
is a wrong way to use member/2 because
cameToThePartyThatDay(People,date(15,9,2011))
isn't a list.
A right way could be
cameToThePartyThatDay(People, date(15, 9, 2011)),
member(X, People)
For Prolog, the boldface part in the following expression:
member(X,cameToThePartyThatDay(People,date(15,9,2011))).
Is not a call. In fact predicates are not functions: they do not return anything. According to Prolog the boldface part is a functor.
In order to let it work, you first call cameToThePartyThatDay and then you use People in the member/2 predicate, like:
cameToThePartyThatDay(People,date(15,9,2011)),
member(X,People).
I'm trying to to get a list of three items with their relevant information based on a collection of information:
product(I):-
I = [_,_,_,_], %Type,Brand,Category,Value
cheaper(item(apple,_,_),item(_,kay,_,_),I),
cheaper(item(bar,_,_,_),item(_,_,fruit,_),I),
member(item(_,kay,_,2),I),
member(item(apple,granny,_,_),I),
member(item(bar,_,chocolate,_),I),
/* Below not given */
member(item(cracker,_,_,_),I),
member(item(_,_,biscuit,_),I),
member(item(_,_,_,4),I),
member(item(_,_,_,5),I).
cheaper(X,Y,H) :- %Used to determine the item values
item(X,_,_,A),
item(Y,_,_,B),
A<B.
When I try running it I encounter an error:
?- product(I).
ERROR: cheaper/3: Undefined procedure: item/4
Exception: (8) item(item(apple, _G3604, _G3605), _G3651, _G3652, _G3653) ?
I understand that item isn't a procedure, however what can I used for checking the value for apple against the value for bar?
First, the obvious note, you're calling cheaper wrong once:
cheaper(item(apple,_,_),item(_,kay,_,_),I),
↑
Only three values, not four.
If item isn't a procedure, you mustn't call it, but use destructuring.
Also you want those items you're checking with cheaper to be part of the list, right? If so, you'll have to check that. And you can use unification to extract the values that you need:
cheaper(X,Y,I) :-
member(X,I),
member(Y,I),
[item(_,_,_,A),item(_,_,_,B)] = [X,Y],
A<B.
Now you'll get some errors regarding not instantiated argument. That's because you are checking not (yet) set variables if they are greater than each other. To avoid this, move the cheaper/3 calls to the end of your clause body:
product(I):-
I = [_,_,_,_], %Type,Brand,Category,Value
member(item(_,kay,_,2),I),
member(item(_,_,_,4),I),
member(item(_,_,_,5),I),
member(item(apple,granny,_,_),I),
member(item(bar,_,chocolate,_),I),
/* Below not given */
member(item(cracker,_,_,_),I),
member(item(_,_,biscuit,_),I),
cheaper(item(apple,_,_,_),item(_,kay,_,_),I), % note the 4th argument
cheaper(item(bar,_,_,_),item(_,_,fruit,_),I).
With this, you'll get one solution and then it fails with an error. This is, because you only give three values for the price slot and you have four items and prolog will check A > 2.
Sorry, in my other answer I didn't look for what the poster was trying to achieve and I think that this is better than a complete reedit. (glorious SO mods let me know if I'm wrong)
I'd like to know how to make a predicate that puts all results obtained from some query (so I get a result and press semicolon until I get False) in a list.
For example if I write foo(X,[1,2,3]). in some Prolog listener, let's say the result is
X=[11];
X=[22];
False.
I would like to get all those results in a list, so something like the following would happen.
?-another_foo(X,[1,2,3]).
X=[[11],[22]].
another_foo would somehow use foo to create a list with all the results from foo.
I just don't know how.
Use the built-in predicate findall/3:
?-findall(X0, foo(X0, [1,2,3]), X).
X = [[11], [22]].
You can define your another_foo/2:
another_foo(X, Input) :-
findall(X0, foo(X0, Input), X).