list


Prolog - Count the Number of Repetitions in a List


I'm writing a program in Prolog that counts the number of uninterrupted occurrences of the first value in a list.
So given, repetitions(A,[a,a,a,a,a,b,c,a]), the program would return A = 5.
This is what my code looks like so far:
repetitions(A,[]).
repetitions(A,[A|T]):- repetitions(A, [_|T]), A is 1+A.
repetitions(A,[_|T]):- repetitions(A,[A|T]).
Here is a relational version:
repetitions(N, [First|Rest]) :-
phrase(repetitions_(First, 1, N), Rest).
repetitions_(_, N, N) --> [].
repetitions_(First, N0, N) --> [First],
{ N1 #= N0 + 1 },
repetitions_(First, N1, N).
repetitions_(First, N, N) --> [Other], { dif(First, Other) }, ... .
... --> [] | [_], ... .
The test case works as required:
?- repetitions(N, [a,a,a,a,a,b,c,a]).
N = 5 ;
false.
And moreover, we can also use this in other directions.
For example, what about a list with 3 element in general:
?- Ls = [A,B,C], repetitions(N, Ls).
Ls = [C, C, C],
A = B, B = C,
N = 3 ;
Ls = [B, B, C],
A = B,
N = 2,
dif(B, C) ;
Ls = [A, B, C],
N = 1,
dif(A, B) ;
false.
And what about all possible answers, fairly enumerated by iterative deepening:
?- length(Ls, _), repetitions(N, Ls).
Ls = [_8248],
N = 1 ;
Ls = [_8248, _8248],
N = 2 ;
Ls = [_8734, _8740],
N = 1,
dif(_8734, _8740) ;
Ls = [_8248, _8248, _8248],
N = 3 ;
Ls = [_8740, _8740, _8752],
N = 2,
dif(_8740, _8752) ;
etc.
It is a major attraction of logic programs that they can often be used in several directions.
See dcg, prolog-dif and clpfd for more information about the mechanisms I used to achieve this generality.
We can also use this to answer the following question
What does a list look like such that there are 3 repetitions of its first element?
Example:
?- repetitions(3, Ls).
Ls = [_2040, _2040, _2040] ;
Ls = [_2514, _2514, _2514, _2532],
dif(_2514, _2532) ;
Ls = [_2526, _2526, _2526, _2544, _2550],
dif(_2526, _2544) ;
Ls = [_2538, _2538, _2538, _2556, _2562, _2568],
dif(_2538, _2556) .
This requires only that a single further constraint be added to the solution above. I leave this as an easy exercise.
Here is a DCG-based solution somewhat a variation to #mat's:
repetitions_II(N, [X|Cs]) :-
phrase( ( reps(X, N), no(X) ), [X|Cs]).
no(X) -->
( [] | [Y], {dif(X,Y)}, ... ).
reps(_X, 0) -->
[].
reps(X, N0) -->
[X],
{ N0 #> 0, N1 #= N0-1 },
reps(X, N1).
Two notable differences:
1mo) There is no use of a difference for maintaining the counter. Thus, constraints on the number can help to improve termination. A perfect clpfd-implementation would (or rather should) implement this with similar efficiency to a difference.
2do) The end no//1 essentially encodes in a pure manner \+[X].
The downside of this solution is that it still produces leftover choicepoints. To get rid of these, some more manual coding is necessary:
:- use_module(library(reif)).
repetitions_III(N, [X|Xs]) :-
reps([X|Xs], X, N).
reps([], _, 0).
reps([X|Xs], C, N0) :-
N0 #>= 0,
if_(X = C, ( N1 #= N0-1, reps(Xs, C, N1) ), N0 = 0 ).
a compact definition, courtesy libraries apply and yall
?- [user].
repetitions(A,[H|T]) :- foldl([E,(C0,H0),(C1,H1)]>>(E==H0 -> succ(C0,C1), H1=H0 ; C0=C1, H1=_), T, (1,H), (A,_)).
|: true.
?- repetitions(A,[a,a,a,a,a,b,c,a]).
A = 5.
Another approach close to what you've done so far, using CLPFD:
:- use_module(library(clpfd)).
repetitions(N,[H|T]):-repetitions(N,[H|T],H).
repetitions(0,[],_).
repetitions(0,[H|_],H1):-dif(H,H1).
repetitions(N,[H|T],H):-repetitions(N1 ,T, H), N #= N1+1.
Examples:
?- repetitions(A,[a,a,a,a,a,b,c,a]).
A = 5 ;
false.
?- repetitions(2,[a,Y]).
Y = a.
?- repetitions(N,[a,a|_]).
N = 2 ;
N = 2 ;
N = 3 ;
N = 3 ;
N = 4 ;
N = 4 ;
N = 5 ;
N = 5 ;
N = 6 ;
N = 6 ....and goes on

Related Links

Formula for coordinates in a linearly increasing interval
SharePoint Field Definition
what are the easiest ways of representing edges for a graph?i mean in terms of a list? in C programming language
Scala - how to get a list element
Haskell range notation to generate list. Unexpected output
Matching elements on 2 lists
Erlang List filter question
Haskell: accessing lists from back
How to read list elements using Mootools
SharePoint 2010 custom list view returning items in the list according to criteria
Setting an ActionScript List border
searching for a value in a list - coldfusion
Only by using cons car cdr
How do you define an operator in prolog to make a list?
Actionscript/Flex: How to maintain the selected item (instead of index) after a Spark list sorts
How to sort a list of objects in to a N-ary tree representing subsets & supersets objects using perl?

Categories

HOME
extjs
memory
eclipse-plugin
kendo-dropdown
systemd
antd
operating-system
dry
ios-simulator
websocket
moodle-api
ontology
responsive-design
roku
gtk
hystrix
watch-os-3
fbloginview
circleci
google-tasks-api
tomcat8
exe
rpmbuild
qa
channel
dragula
jpa-2.1
prompt
network-analysis
php-5.3
bonita
unmarshalling
openbr
wampsharp
john-the-ripper
overwrite
formsauthenticationticket
assert
google-now
best-buy-api
task-parallel-library
stat
sendinput
doctrine-extensions
docker-ucp
ipp-protocol
return-type
xcglogger
karabiner
openstack-glance
mongodb-aggregation
test-data
connect-direct
network-protocols
alertify
adobe-reader
nrf51
xcode6.4
livecycle
wicked-pdf
rails-engines
urbit
verisign
vimperator
myfaces
phpquery
juniper-network-connect
largenumber
android-handler
algebraixlib
android-audiomanager
fasterxml
thoughtworks-go
iplimage
storing-data
coding-efficiency
network-printers
two.js
zend-search-lucene
bittorrent-sync
nodeload
property-injection
iosched
pacman
django-filebrowser
office-app
ip-geolocation
zend-pdf
chronometer
django-apps
net-use
nsrangeexception
space-partitioning
regression-testing
self-tracking-entities
processors
efs
service-factory

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App