Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

prolog question
i need to write the following program:
%count_type(Term,Type,Number)
i have written the program but it get stuck in T=..L
when i run the following predicate
 count_type(f(g(1,A),A,[1,B,h(C)]),variab
le,Number).
what is the problem with my program.

count_type(T,Y,N):-
Y==numeric,
numeric(T),!,
retract(counter(Y)),
X is Y+1,
asserta(counter(X)).

count_type(T,Y,N):-
Y==atom,
(atomic(T)),!,
retract(counter(Y)),
X is Y+1,
asserta(counter(X)).


count_type(T,Y,N):-
Y==variable,
var(T),!,
retract(counter(Y)),
X is Y+1,
asserta(counter(X)).


count_type([X|Xs],T,N):- !,
count_type(X,T,N),
count_type(Xs,T,N).

count_type(T,Y,N):-
T=..L,
count_type(L,Y,N).


Report this thread to moderator Post Follow-up to this message
Old Post
shoko2004
12-11-04 08:58 PM


Re: prolog question
shoko2004 wrote:
> i need to write the following program:
> %count_type(Term,Type,Number)
> i have written the program but it get stuck in T=..L
> when i run the following predicate
>  count_type(f(g(1,A),A,[1,B,h(C)]),variab
le,Number).
> what is the problem with my program.
>
> count_type(T,Y,N):-
> Y==numeric,
> numeric(T),!,
> retract(counter(Y)),
> X is Y+1,
> asserta(counter(X)).
>
> count_type(T,Y,N):-
> Y==atom,
> (atomic(T)),!,
> retract(counter(Y)),
> X is Y+1,
> asserta(counter(X)).
>
>
> count_type(T,Y,N):-
> Y==variable,
> var(T),!,
> retract(counter(Y)),
> X is Y+1,
> asserta(counter(X)).
>
>
> count_type([X|Xs],T,N):- !,
> count_type(X,T,N),
> count_type(Xs,T,N).
>
> count_type(T,Y,N):-
> 	T=..L,
> 	count_type(L,Y,N).


Hi,
Nice program, a good example of cut usage.
The major problem I see is that clause T=..L is very generic. That is,
near that anything will match it. By example:

a=..L   => L=[a]
[]=..L  => L=[[]]

I do not known your objectives, but probably T=..[F|L] helps a few.

In addition, some very small comments, probably just editorial
subjects:

retract(counter(Y????)), Y is not a number.
what is N in your rules?
addition of ! after T=..L ?
something for the empty list: count_type([],.... ?
nicer count_type(T,numeric,N) :- .... than count_type(T,Y,N) :-
Y==numeric, .... ?

Hope useful,
Kind regards.


Report this thread to moderator Post Follow-up to this message
Old Post
tmp123
12-11-04 08:58 PM


Re: prolog question
tmp123 wrote:
> shoko2004 wrote:
> 
>
>
>
> Hi,
> Nice program, a good example of cut usage.
> The major problem I see is that clause T=..L is very generic. That is,
> near that anything will match it. By example:
>
> a=..L   => L=[a]
> []=..L  => L=[[]]
>
> I do not known your objectives, but probably T=..[F|L] helps a few.
>
> In addition, some very small comments, probably just editorial
> subjects:
>
> retract(counter(Y????)), Y is not a number.
> what is N in your rules?
> addition of ! after T=..L ?
> something for the empty list: count_type([],.... ?
> nicer count_type(T,numeric,N) :- .... than count_type(T,Y,N) :-
> Y==numeric, .... ?
>
> Hope useful,
> Kind regards.
>


Both the original poster and the replying poster have a problem - but
of a different kind. I will address both. First the OP.

Guessing ... the OP wants to count the number of nodes in a Prolog
term "tree", but only the nodes of a particular "type" (variable,
numeric or otherwise atomic) - as a side remark: when asking for help,
please tell us what your program is supposed to do, or which problem
you are trying to solve, because from a piece of code you yourself
describe as "it get stuck" it is impossible to deduce that.

Allow me to first give a general advice regarding the use of Prolog,
actually three advices:

1) don't use dynamic predicates
2) don't use dynamic predicates
3) don't use dynamic predicates

Here are the 3 most important reasons:

if you use dynamic predicates

1) you make more mistakes
2) you abuse them eventually
3) your programs are worse

I do not know how to help you further, except by following my hunch on
what you are trying to achieve and point out the similarity between

if I am counting numbers and the term contained already 13
numbers, and what I see now is a number, then the term
contains 14 numbers up to now

and
count(Term,What,AlReady,UpToNow) :-
What == number,
number(Term),
!,
UpToNow is AlReady + 1.

There are ways to write this (in the context of the whole program)
without a cut (!), but that's for the next lesson if you care.
BTW, number/1 is an ISO Prolog builtin - numeric/1 is not.

Now the reply the OP got from tmp123 - as a side remark: beginner's
questions are ok; they remind us how we also struggled with basic
stuff, and they allow us to show the right path to LP.

But replies as from tmp123 ... please no more !
My advice to tmp123: ask advice, do not offer it.


tmp123 writes:

> Nice program, a good example of cut usage.

How can one judge the niceness of a program without knowing what it is
supposed to solve ?

"a good example of cut usage" please, give us a break ...

> The major problem I see is that clause T=..L is very generic. That is,
> near that anything will match it. By example:
>
> a=..L   => L=[a]
> []=..L  => L=[[]]
>
> I do not known your objectives, but probably T=..[F|L] helps a few.

The only part that makes sense in these sentences is

I do not known your objectives

all the rest is gibberish, dangerous noise, because it gives the
impression of knowing the subject matter - believe me, tmp123 doesn't.

> In addition, some very small comments, probably just editorial
> subjects:

and what follows is indeed a comment focussing on "editorial" issues,
not related to understanding; it is commenting on form, not
contents. We can only hope that tmp123 meant it as a sick joke ...

In any case, I beg the OP: ignore the response from tmp123, except for
the part
> Kind regards.
The OP can get better help/response/advice from comp.lang.prolog than
from tmp123 (but make more clear what you want to do).

Cheers

Bart Demoen

ps. yes, I am back :-)

Report this thread to moderator Post Follow-up to this message
Old Post
Bart Demoen
12-13-04 09:07 PM


Re: prolog question
Bart Demoen wrote:

> ps. yes, I am back :-)

Hi Bart,

Nice to read you again.

Your answer is, in my opinion, a few too much.

I think google is not a good place for long non-technical discussions,
so this is my last post to this or any other reply you make to this
subject. I will open a new thread in this post continuing with the
techinical subject. (assumption: if the original author still
interested, then it is not a homework: I can be more exact on my
comments). I think your technical opinion will be an important
contribution. One example, about how to skip cut and its variants.


Report this thread to moderator Post Follow-up to this message
Old Post
tmp123
12-14-04 02:07 PM


Re: prolog question
"tmp123" <tmp123@menta.net> writes:

> I think google is not a good place for long non-technical
> discussions,

I'm sure the people at Google have long non-technical discussions,
but we can't participate. News is however an excellent place for
long non-technical discussions between people from different parts
of the world.

Report this thread to moderator Post Follow-up to this message
Old Post
Torkel Franzen
12-14-04 02:07 PM


Re: prolog question
One example of the application of the previous comments to the rule for
"numbers". It is assumed this rule means "if T is a number, and we are
counting numbers, then number of numbers, N, is 1". With this
definition of N, it is not necessary to use retract/assert.

count_type(T,Y,1):-
Y==numeric,
numeric(T), !.

"numeric" can be changed by standard "number".

Now, the other case for numbers: "if T is a number, but we are looking
for something else, then N is 0". In this way, it is sure that no
numbers will progress to next rules. Using parameter matching instead
of == we will have the following rules:

count_type(T,numeric,1) :- number(T), !.
count_type(T,_Y,0) :- number(T), !.

Same for atoms and variables.

Going for a few more complex rule: the list.
First one "the number of anything in a empty list is 0".
count_type([],_Y,0) :- !.

Next one, the number of something in a list is the number of something
in the head more its number in the rest:
count_type([H|Q],Y,Z) :- !,
count_type(H,Y,Z1),
count_type(Q,Y,Z2),
Z is Z1+Z2.

Finally, the case of terms. At this point, atom, numbers, list, ...
have already analized, so I can suposse only rest terms with functor
and arity >=0. The rules is: the number of anything in a term is the
number of anything in the functor (?) plus the number in the
"parameters".

count_type(T,Y,Z) :-
T=..[F|Q], !,
count_type(F,Y,Z1),
count_type(Q,Y,Z2),
Z is Z1+Z2.

Finally, a completion, for not covered cases:
count_type(_,_,0).

Hope nothing forgot. Time for TECHNICAL comments and improvements (I'm
sure experts can improve it a lot). Some posibilities:
- Make rules tail recursive using 4 parameters.
- Skip cut and -> and similars.
- ...


Report this thread to moderator Post Follow-up to this message
Old Post
tmp123
12-14-04 02:07 PM


Re: prolog question

On Sat, 11 Dec 2004, shoko2004 wrote:

> i need to write the following program:
> %count_type(Term,Type,Number)
> i have written the program but it get stuck in T=..L
> when i run the following predicate
>  count_type(f(g(1,A),A,[1,B,h(C)]),variab
le,Number).
> what is the problem with my program.
>
> count_type(T,Y,N):-
> Y==numeric,
> numeric(T),!,
> retract(counter(Y)),
> X is Y+1,
> asserta(counter(X)).
>
> count_type(T,Y,N):-
> Y==atom,
> (atomic(T)),!,
> retract(counter(Y)),
> X is Y+1,
> asserta(counter(X)).
>
>
> count_type(T,Y,N):-
> Y==variable,
> var(T),!,
> retract(counter(Y)),
> X is Y+1,
> asserta(counter(X)).
>
>
> count_type([X|Xs],T,N):- !,
> count_type(X,T,N),
> count_type(Xs,T,N).
>
> count_type(T,Y,N):-
> 	T=..L,
> 	count_type(L,Y,N).
>
In the first three clauses you seem to be trying to use the variable
Y for two different things, one as a string to indicate the type
you're counting, the other as an integer to hold a count. But the
variable N doesn't get used at all.

As Bart suggests, a good rule is don't use dynamic predicates.
It's often the case that the use of such predicates indicates
a failure to think declaratively. In this case you are using one
just to keep a rewriteable count, but why not just:

count_type([X|Xs],T,N):- !,
count_type(X,T,N1),
count_type(Xs,T,N2),
N is N1+N2.

?

Even when programming in an imperative language, this would be the obvious
way to do it leading to cleaner code, rather than having a global variable
which is updated.

The time when a dynamic predicate to give an updateable count *is*
required in Prolog is when you are keeping a count which is updated over
backtracking. Prolog novices often waste many hours because no-one told
them you can't maintain information over backtracking except through
the use of assert.

Matthew Huntbach

Report this thread to moderator Post Follow-up to this message
Old Post
Matthew Huntbach
12-14-04 02:07 PM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

Prolog archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 04:00 AM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.