🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.prolog
Article #28

Counting lines of code in Prolog (source code)

#28
From: Peter Reintjes
Date: Fri, 30 Oct 1992 22:57
140 lines
4616 bytes
/*
 * After looking at the Prolog-1000 listing, I decided to post
 * my line-counting program to encourage a consistent method of
 * measuring Prolog source-code size.  As everyone knows, a
 * "line of code" is a pretty meaningless measurement. However,
 * in good Prolog style, a line usually corresponds to a single goal.
 *
 * Even a cut should be given a line of its own. It is
 * certainly as *important* as any other line of code in its
 * implications. Just because we get used to seeing something
 * doesn't necessarily mean that we should bury it!
 *
 * As an extreme example, my programs considers the following
 * to be seven lines (goals) of code.
 *
 *  head(X,Y) :- ( X =:= 0 -> p(X,Y) ; q(X,Y) ), !.
 *
 * Calling this 7 lines of code is my way of saying that it
 * should have been written as:
 *
 *  head(X,Y) :-
 *        ( X =:= 0 ->
 *          p(X,Y)
 *        ;
 *          q(X,Y)
 *        ),
 *        !.
 *
 *  This is an extreme example and a little misleading since
 * the -> is counted as a goal even though it doesn't have its
 * own line and the but the final ) is not counted, though it does.
 * So the 7 does not correspond to the actual seven lines of
 * code shown here, but the correspondence remains close.
 * This method of counting still shows me a 10:1 improvement
 * in source-codes size over C programming even though it
 * is *very* conservative when you contrast it with a
 * "line of code" in C which might look like:
 *
 *   for (i=0,j=MACRO(L,i); i < NCOUNT ; i++, j--)
 *
 * Here is the source code for a Goal/Clause/Predicate counter
 * for Prolog programs. Below is a typical usage:
 *
 *  % count count.pl
 *  count.pl       :  81  Lines(goals)   13 Predicates    29 Clauses
 *
 *  Total:   29 Clauses 13 Predicates 81 Lines (goals)
 *
 *  % count count.pl ccount.pl opt.pl
 *  count.pl       :   81 Lines(goals)   13  Predicates     29  Clauses
 *  ccount.pl      :   28 Lines(goals)   8   Predicates     8   Clauses
 *  opt.pl         :   6  Lines(goals)   1   Predicates     1   Clauses
 *  
 *  Total:   38 Clauses 22 Predicates 115 Lines (goals)
 *
 *  Peter Reintjes   pbr@quine.sofla.ingr.com     (407)498-2809
  */


runtime_entry(start) :-   % Equivalent of C main() entry point
    unix(argv(Files)),    % Files = list of the command line arguments
    each(Files),
    total.

total :-
  findall(stat(C,P,L),stat(C,P,L),Stats),
  sum(Stats,stat(0,0,0),stat(C,P,L)),
  format('~nTotal:~+ ~d Clauses~+ ~d Predicates~+ ~d Lines (goals)~n',[C,P,L]).

sum([],X,X).
sum([stat(A,B,C)|Ss],stat(A1,B1,C1),Total) :-
    NA is A+A1, 
    NB is B+B1, 
    NC is C+C1, 
    sum(Ss,stat(NA,NB,NC),Total).

each([]).
each([File|Files]) :-
    see(File),
    format('~a~20|: ',[File]),
    read(T),
    process(T,xxx,0,0,0),
    seen,
    each(Files).

process(end_of_file,_,Clauses,Predicates,Lines) :- !,
    format('~24|~d~29| Lines(goals)   ~d~50| Predicates     ~d~70| Clauses~n',
             [Lines, Predicates, Clauses]),
    assert(stat(Clauses,Predicates,Lines)).

process(Cl,Prev,Clauses,Predicates,Lines) :-
     arg(1,Prev,PHead),
     functor(PHead,F,A),
     arg(1,Cl,Head),
     functor(Head,F,A),
     !,
     add_lines(Cl,Lines,L),
     read(Next),
     C is Clauses + 1,
     process(Next,Cl,C,Predicates,L).
process(Pr,_,Clauses,Predicates,Lines) :-
     add_lines(Pr,Lines,L),
     read(Next),
     P is Predicates + 1,
     C is Clauses + 1,
     process(Next,Pr,C,P,L).

add_lines((:-op(A,B,C)),In,Out) :- !,
      op(A,B,C),
      Out is In + 1.

add_lines(Clause,In,Out) :-
     arg(2,Clause,Body),
     nonvar(Body),
     ( functor(Body,',',2)
     ; functor(Body,';',2)
     ; functor(Body,'->',2)
     ),
     !,
     Next is In + 1, % One for the head
     add_body(Body, Next, Out).

add_lines(_,In,Out) :-
     Out is In + 1.

add_body(iSvAr, In, Out) :-
      !,
      Out is In + 1.

add_body((_,B),In,Out) :-
      !,
      Next is In + 1,
      add_body(B, Next, Out).
add_body((A;B),In,Out) :-
      !,
      add_body(A, In,  Next),
      add_body(B, Next, Out).
add_body(_,In,Out) :-
      Out is In + 1.
Technical Details
Message-ID: <1992Oct30.225748.17312@infonode.ingr.com>
Path: arc1-ca.pugleaf.net!sparky!uunet!infonode!reintjes

Show Full Headers
Complete Article Headers
Newsgroups: comp.lang.prolog
Path: arc1-ca.pugleaf.net!sparky!uunet!infonode!reintjes
From: reintjes@infonode.ingr.com (Peter Reintjes)
Subject: Counting lines of code in Prolog (source code)
Message-ID: <1992Oct30.225748.17312@infonode.ingr.com>
Keywords: predicates clauses goals lines of code
Organization: Intergraph Corporation, Huntsville, AL.
Date: Fri, 30 Oct 1992 22:57:48 GMT
Lines: 141