Number of objects in Logtalk - list

I've got the protocol:
:- protocol(person).
:- public([name/1,
age/1]).
:- end_protocol.
For example, I've made unknown number of objects by using create_object/4, how can I get a number of them? It is not a problem to get their names by current_object/1, but I need an integer!

Assuming only objects (i.e. no categories) implement the person protocol, you can compute their number using e.g.
count(N) :-
findall(1, implements_protocol(_,person), L),
list::length(L, N).
Replace the call to implements_protocol /2 with conforms_to_protocol/2 if you have hierarchies of objects. You can also generalize the count/1 predicate by passing the protocol as an argument.

Related

Properly working with sets in Prolog

In Prolog it seems that sets are represented using lists.
For example, here is the implementation of union/3 from SWI-Prolog:
union([], L, L) :- !.
union([H|T], L, R) :-
memberchk(H, L), !,
union(T, L, R).
union([H|T], L, [H|R]) :-
union(T, L, R).
However this predicate isn't very declarative, for example:
?- union([1,2,3],X,[1,2,3,4]).
X = [1, 2, 3, 4].
which should leave some choice points, or:
?- union(X,[1,2],[1,2,3,4]).
<infinite loop>
which doesn't even work!
That aside, we also find the following problems:
?- union([1,2,3],[4,5],[1,2,3,5,4]).
false.
?- union([1,1,1],[4,5],[1,1,1,4,5]).
true.
which are obviously wrong if we would be really talking about sets.
We can clearly see that using lists to talk about sets isn't straightforward because:
Sets are not ordered whereas lists are;
Sets do not contain duplicate values whereas lists can.
As a consequence we either find predicates working on sets that cut possible solutions (e.g. this implementation of union which only works if the set is ordered) or predicates which provide useless choice points depending on variables' instanciation (e.g. a union predicate which would have as many choice points as the number of permutations of the resulting set).
How should predicates that work on sets be properly implemented in Prolog?
This question is very general and not specific to the example of union/3 used here.
If you want the very general notion, you will have to implement your own data type, with its own unification algorithm. Compared to your previous question, AC-unification is "much" simpler than pure associative unification. You "only" have to solve Diophantine equations and the like. There is much more literature on AC-unification than there is on associative unification.
But that really is more of a research project than a programming task. What can you do in pure Prolog today?
You can approximate sets with lists in a still pure and declarative way, provided you take into account functional dependencies. See this answer for more!
How should predicates that work on sets be properly implemented in
Prolog?
First of all a union predicate in prolog should respect the basic mathematical properties of set union so it which are:
associativity: A ∪ (B ∪ C) = (A ∪ B) ∪ C
commutative: A ∪ B = B ∪ A
(These properties ensure that union is unambiguous which though shouldn't concern a Prolog predicate implementation with to arguments.)
Moreover a union implementation( or other set-predicates) should also have the following properties in Prolog:
Handle duplicates.
If one of the lists have at least an element more than one times then this element should be counted only one time.
Handle cases where at least one argument is not instantiated.
for example Union([X],Union_Set,[Y]). should obviously return Union_set=[X,Y].
Another example : Union([X],[X1,Y1],[Y]). should obviously return X1=X, Y1=Y. through unification.
Be deterministic
Union is a set is the set of all distinct elements in the collection. This definition is well defined (mathematically) which doesn't leave nonuniqueness option (the result must be unique for every well defined mathematical operation(not only for union) ).
Also another desird feature could be logical purity which is provided by the algebraic properties (commutative,associativity).
Handle infinite loop-occasions.
As in your example in union predicate: union(X,[1,2],[1,2,3,4]). should return some instantiation error.
These are some features that I should be included since we are talking about Set operations, but of course these are not all the properties that we could consider. This has to do also with the implementations that we make when defining predicates.
Finally one more comment on: Sets are not ordered whereas lists are;
This is not true. Partial or total ordering applies in both lists and sets and it is has to do whether if we can compare all elements or just some elements, which means that we can put them in order. Any data structure like lists doesn't provide the order (order has to do with semantics) unless we consider it as for example in a heap where it is a tree structure but we consider that is ordered.
First, to add an additional example of what we currently have to cope with:
?- union(A, [], A).
A = [].
Which we can read as:
The empty set is the only set.
Who would have thought?
A very nice library for reasoning about sets is available in ECLiPSe as library(conjunto):
Conjunto is a system to solve set constraints over finite set domain terms. It has been developed using the kernel of ECLiPSe based on metaterms. It contains the finite domain library of ECLiPSe. The library conjunto.pl implements constraints over set domain terms that contain herbrand terms as well as ground sets.
Note also:
As of ECLiPSe release 5.1, the library described in this chapter is being phased out and replaced by the new set solver library lib(ic_sets).
These are great libraries, and I recommend you use them as a starting point if you are interested in set constraints.
A nice example of what can be done with set constraints is available from:
http://csplib.org/Problems/prob010/models/golf.ecl.html

Prolog Beginner: Reverse List only once

Assume I have two arbitrary lists that represent the first two items of a 3-place predicate:
[anna,berta,charlotte],[charles,bob,andy]
I want to match every item in a third list (the third item of the 3-place predicate) as follows:
[[anna,andy],[berta,bob],[charlotte,charles]]
Basically the items get matched in a sequentially reverse fashion. To match the items in a sequential manner, I've devised the following code:
match([],[],[]).
match([A|At],[C|Ct],[[A,C]|Dt]):-match(At,Ct,Dt).
But this would give me the following:
match([anna,berta,charlotte],[charles,bob,andy],X).
X=[[anna,charles],[berta,bob],[charlotte,andy]]
So I need to reverse the second list somehow. So far, I've altered the code as follows:
match([],[],[]).
match([A|At],[C|Ct],[[A,B]|Dt]):-reverse([C|Ct],[B|Bt]),match(At,Bt,Dt).
But this would continually reverse the second list with each pass. The result would look as follows:
match([anna,berta,charlotte],[charles,bob,andy],X).
X=[[anna,andy],[berta,charles],[charlotte,bob]]
Question:
How do I reverse the second list only ONCE, so the actual results match the desired ones? Or is my approach fundamentally flawed? I'm new to prolog and am currently stymied by this. Any help would be appreciated.
Do exactly what you say: Reverse the list once, and then use the reversed list.
lists_pairs(Ps1, Ps2, Pairs) :-
reverse(Ps2, RPs2),
pairs_keys_values(Pairs, Ps1, RPs2).
You can check out the source code of reverse/2 and pairs_keys_values/3 in any decent Prolog library to see how it is defined.
Sample query and answer:
?- lists_pairs([anna,berta,charlotte], [charles,bob,andy], Ps).
Ps = [anna-andy, berta-bob, charlotte-charles].
I leave converting such pairs to the non-sensible "pair as list" representation as an exercise.
The trick to solving problems that require you to apply a rule only once is to build an auxiliary rule which performs extra steps before and/or after invoking the recursive rule:
match(A, B, R) :- reverse(B, RevB), match_impl(A, RevB, R).
match_impl([], [], []).
match_impl([A|At], [C|Ct], [[A,C]|Dt]) :- match_impl(At, Ct, Dt).
match_impl/3 is your match/3 rule renamed to avoid conflicting with the "top" match/3 rule that includes an auxiliary step.
This is a small followup to #mat's answer.
To aid termination in some cases you could add a redundant same_length_as/3 goal like so:
lists_pairs(Ps1, Ps2, Pairs) :-
same_length_as(Ps1, Ps2, Pairs),
reverse(Ps2, RPs2),
pairs_keys_values(Pairs, Ps1, RPs2).
The auxiliary predicate same_length_as/3 can be defined like this:
same_length_as([],[],[]).
same_length_as([_|As],[_|Bs],[_|Cs]) :-
same_length_as(As,Bs,Cs).

Prolog Insert the number in the list by the tail

How can I build a predicate in prolog that receives a number and a list, I must insert the number in the list by the tail
I tried inserting the number in the list by the head: insert(H,[P|Q],[H,P|Q]). and it works, but how can I do it by the tail?
Simply use append/3 like this:
?- append([a,b,c,d],[x],List).
List = [a,b,c,d,x].
Inserting at the tail can be done with a two-part recursive rule:
When the list is empty, unify the result to a single-element list with the item being inserted
When the list is not empty, unify the result to a head followed by the result of inserting into the tail of a tail.
English description is much longer than its Prolog equivalent:
ins_tail([], N, [N]).
ins_tail([H|T], N, [H|R]) :- ins_tail(T, N, R).
Demo.
Nobody talked about difference lists yet.
Difference lists
Difference lists are denoted L-E, which is just a convenient notation for a couple made of a list L whose last cons-cell has E for its tail:
L = [ V1, ..., Vn | E]
The empty difference list is E-E, with E a variable. You unify E whenever you want to refine the list.
For example, if you want to add an element X, you can unify as follows:
E = [X|F]
And then, L-F is the new list. Likewise, you can append lists in constant time. If you unify F with a "normal" list, in particular [], you close your open-ended list. During all operations, you retain a reference to the whole list through L. Of course, you can still add elements in front of L with the ususal [W1, ..., Wm |L]-E notation.
Whether or not you need difference lists is another question. They are intereseting if adding an element at the end is effectively a common operation for you and if you are manipulating large lists.
Definite clause grammars
DCG are a convenient way of writing grammar rules in Prolog. They are typically implemented as reader macros, translating --> forms into actual predicates. Since the purpose of grammars is to build structures during parsing (a.k.a. productions), the translation to actual predicates involves difference lists. So, even though both concepts are theoretically unrelated, difference lists are generally the building material for DCGs.
The example on wikipedia starts with:
sentence --> noun_phrase, verb_phrase.
... which gets translated as:
sentence(S1,S3) :- noun_phrase(S1,S2), verb_phrase(S2,S3).
A lot of "plumbing" is provided by the syntax (a little like monads). The object being "built" by sentence/2 is S1, which is built from different parts joined together by the predicates. S1 is passed down to noun_phrase, which builds/extends it as necessary and "returns" S2, which can be seen as "whatever extends S1". This value is passed to verb_phrase which updates it and gives S3, a.k.a. whatever extends S2. S3 is an argument of sentence, because it is also "whatever extends S1", given the rule we have. But, this is Prolog, so S1, S2 and S3 are not necessarly inputs or outputs, they are unified during the whole process, during which backtracking takes place too (you can parse ambiguous grammars). They are eventually unified with lists.
Difference lists come to play when we encounter lists on the right-hand side of the arrow:
det --> [the].
The above rule is translated as:
det([the|X], X).
That means that det/2 unifies its first argument with an open-ended list which tail is X; other rules will unify X. Generally, you find epsilon rules which are associated with [].
All the above is done with macros, and a typical error is to try to call an auxiliary predicate on your data, which fails because the transformation add two arguments (a call to helper(X) is in fact a call to helper(X,V,W)). You must enclose actual bodies between braces { ... } to avoid treating prediates as rules.
Here is an another option.
insert(N,[],[N]).
insert(N,[H|T],[H|Q]) :- conc([H|T],[N],[H|Q]).
conc([],L,L).
conc([H|T],L,[H|Q]) :- conc(T,L,Q).

How to find the minimum of the list of the terms?

I have a list of terms as below
[t('L', 76), t('I', 73), t('V', 86), t('E', 69)]
I want to write a predicate in prolog so that it will return the term with minimum second value. i.e. from above list it should return t('E', 69)
Below is what I tried. But this is not working.
minChar(L, Min) :-
setof(t(_, A), member(t(_, A), L), Li),
Li = [Min|_].
Here is the output it gives for above input.
?- minChar([t('L', 76), t('I', 73), t('V', 86), t('E', 69)], Min).
Min = t(_G14650, 69) ;
Min = t(_G14672, 73) ;
Min = t(_G14683, 76) ;
Min = t(_G14661, 86).
As lurker says, predicates can't start with a capital letter, so fix that first.
There are two basic problems here: first off all, the two underscores in your second line refers to different variables, so setof/3 doesn't know that you want the same variable both in the template and in the member/2 call.
Second, setof sorts the result (which is why you can extract the minimum like that), but the way you've constructed the template, it will sort it incorrectly. Sorting in swi-prolog uses the standard order of terms definition, and in your case, you're sorting compound terms of the type t(A, B), where A is an atom and B is a number. This will sort it lexicographically first on A and then on B, which is not what you want, you want to sort on B.
The standard trick here when you want to sort things with a key that isn't identical to the term itself is to extract the key you want, bind it with the (-)/2 functor, and then sort it. So, for your example, this should work:
minChar(L, Min) :-
setof(B-t(A, B), member(t(A, B), L), Li),
Li = [_-Min|_].
Remember here that in Prolog, when you say X - Y, you're not actually doing any subtraction, even though it looks you are. You are simply binding X and Y together using the (-)/2 functor. It only does subtraction if you specifically ask it to, but using some operator that forces arithmetic evaluation (such as =:=, <, > or is, for instance). This is why 1+1 = 2 is false in Prolog, because = is a unification operator, and doesn't do any arithmetic evaluation.
To be clear: you don't have to use - for this, you can use whatever functor you like. But it's traditional to use the minus functor for this kind of thing.
Edit: also, setof/3 will backtrack over any free variables not found in the template, and since the two underscores don't refer to the same free variables, it will backtrack over every possible assignment for the second underscore, and then throw that result away and assign a new free variable for the first underscore. That's why you can backtrack over the result and get a bunch of anonymous variables that you don't know where they came from.
Instead of using a setof which runs in O(n log n) (at least), you can also write a minChar predicate yourself:
minChar([X],X) :-
!.
minChar([t(_,V1)|T],t(A2,V2)) :-
minChar(T,t(A2,V2)),
V2 < V1,
!.
minChar([X|_],X).
Or you could further boost performance, by using an accumulator:
minChar([X|T],Min) :-
minChar(T,X,Min).
minChar([],X,X).
minChar([t(A2,V2)|T],t(_,V1),Min) :-
V2 < V1,
!,
minChar(T,t(A2,V2),Min).
minChar([_|T],X,Min) :-
minChar(T,X,Min).
The code works as follows: first you unify the list as [X|T], (evidently there must be at least one items, otherwise there is no minimum). Now you take X as the first minimum. You iterate over the list, and at each time you compare t(A2,V2) (the new head of the list), with t(A1,V1) (the currently found minimum). If the second attribute V2 is less than V1, we know we have found a new minimum, and we continue our search with that term. Otherwise, the quest is continued with the old current minimum. If we reach the end of the list, we simply return the current minimum.
Another performance hack, is placing the empty list case as the last one, and place the the current minimum is the smallest case first:
minChar([t(_,V2)|T],t(A1,V1),Min) :-
V1 <= V2,
!,
minChar(T,t(A1,V1),Min).
minChar([X|T],_,Min) :-
minChar(T,X,Min).
minChar([],X,X).
This because Prolog always first executes the predicates in the order defined. It will occur only once that you reach the empty list case (at the end of the list). And after a will, the odds of finding a smaller value will be reduced significantly.
You are a beginner in Prolog, so try to think Prolog.
What is the minimum of a list ? An element of this list, and no other element of this list is smaller.
So you can write
my_min(L, Min) :-
member(Min, L),
\+((member(X, L), X < Min)).
One will say : "it's not efficient !". Yes, but I think it's a good way to learn Prolog.
You should adapt this code to your case.
EDIT I said adapt :
min_of_list(L, t(X,Y)) :-
member(t(X, Y), L),
\+((member(t(_, Z), L), Z < Y)).

SWI Prolog scalar multiplying with accumulators

so I've been working on the following question:
Write a 3-place predicate scalarMult whose first argument is an
integer, whose second argument is a list of integers, and whose third
argument is the result of scalar multiplying the second argument by
the first. For example, the query
?- scalarMult(3,[2,7,4],Result).
should yield
Result = [6,21,12]
Do this with the help of an accumulator and a wrapper predicate.
This is what I have done:
scalarMult(I, List1, List2):- scalarMult1(I, List1, [], List2).
scalarMult1(I,[], A, A).
scalarMult1(I,[H|T], A, Result):- H1 is H*I, scalarMult1(I,T,[H1|A],Result).
The only trouble with this is that it's putting the new elements at the head of the accumulator so I kind of end up with a reversed list (so for the example above, I would get Result = [12,21,6]). Is there any way I could work around this? I tried using reverse in my code but all my attempts fails.
Thanks
using reverse/2 works, actually:
scalarMult(I, List1, List2):- scalarMult1(I, List1, [], T), reverse(T, List2).
but I think the requirement to use an accumulator (really useless here) could be on purpose to verify your level of lists handling.
Noting Carlo's remark about the use of accumulators being for didactical purposes, no accumulator is required for a straight-forward definition of the scalar_multiplication/3 predicate (renamed from scalarMult/3; camel case is not considered good programming style in Prolog):
% first exchange argument orders to take advantage of the first-argument
% indexing that is provided in most Prolog implementations
scalar_multiplication(Scalar, Numbers, ScaledNumbers) :-
scalar_multiplication_(Numbers, Scalar, ScaledNumbers).
% base case; either input list was empty or we finished traversing the list
scalar_multiplication_([], _, []).
% recursive case
scalar_multiplication_([Number| Numbers], Scalar, [ScaledNumber| ScaledNumbers]) :-
ScaledNumber is Number * Scalar,
scalar_multiplication_(Numbers, Scalar, ScaledNumbers).
This is an instance of a common pattern for processing lists. So common that several Prolog implementations provide a second-order predicate (or meta-predicate), usually named map/3 or maplist/3, to handle it.