Code Comments
Programming Forum and web based access to our favorite programming groups.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).
Post Follow-up to this messageshoko2004 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.
Post Follow-up to this messagetmp123 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 :-)
Post Follow-up to this messageBart 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.
Post Follow-up to this message"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.
Post Follow-up to this messageOne 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. - ...
Post Follow-up to this messageOn 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
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.