Comparison between C\C++\Lisp\Prolog Written by Ahmed Hesham Mostafa, secon 1, FCIH, Level 3, CS, 18/11/2009 ا ه م
Abstract: this article introduces the difference between Imperative , functional ,OOP and logic programming languages by using example language for each type. Imperative a programming paradigm that describes computation in terms of statements that change a program state also called structured programming language. the program is built from one or more procedures (also known as subroutines or functions) .I will use C programming language as an example for it functional programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. I will use Lisp programming language as an example for it OOP "Object Oriented language" a programming paradigm that uses "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as information hiding, data abstraction, encapsulation, modularity, polymorphism, and inheritance. I will use C++ programming language as an example for it logic programming Logic programming is, in its broadest sense, the use of mathematical logic for computer programming. I will use Prolog programming language as an example for it
١
Data types between C, C++, Lisp, Prolog
C A C language programmer has to tell the system before-hand, the type of numbers or characters he is using in his program. These are data types. There are many data types in C language. A C programmer has to use appropriate data type as per his requirement. C language data types can be broadly classified as Primary data type Derived data type User-defined data type
Primary data type TYPE Char or Signed Char Unsigned Char Int or Signed int Unsigned int Short int or Signed short int Unsigned short int Long int or signed long int Unsigned long int Float Double Long Double
SIZE (Byres)
Range -128 to 127
1 1 2 2 1 1 4 4 4 8 10
0 to 255 -32768 to 32767 0 to 65535 -128 to 127
0 to 255 -2147483648 to 2147483647 0 to 4294967295 3.4 e-38 to 3.4 e+38 1.7e-308 to 1.7e+308 3.4 e-4932 to 3.4 e+4932
User defined type declaration In C language a user can define an identifier that represents an existing data type. The user defined datatype identifier can later be used to declare variables. The general syntax is typedef type identifier; here type represents existing data type and ‘identifier’ refers to the ‘row’ name given to the data type. Example: typedef int salary; typedef float average;
Declaration of Storage Class Variables in C have not only the data type but also storage class that provides information about their location and visibility. The storage class divides the portion of ٢
the program within which the variables are recognized. Auto: It is a local variable known only to the function in which it is declared. Auto is the default storage class. Static: Local variable which exists and retains its value even after the control is transferred to the calling function. Extern: Global variable known to all functions in the file register: Social variables which are stored in the register.
C++ TYPE
SIZE (Byres)
Range
Char
1
short int
2
Int
4
long int
4
Bool Float Double long double wchar_t
1 4 8 8 2 or 4
signed: -128 to 127 unsigned: 0 to 255 signed: -32768 to 32767 unsigned: 0 to 65535 signed: -2147483648 to 2147483647 unsigned: 0 to 4294967295 signed: -2147483648 to 2147483647 unsigned: 0 to 4294967295 true or false +/- 3.4e +/- 38 (~7 digits) +/- 1.7e +/- 308 (~15 digits +/- 1.7e +/- 308 (~15 digits) 1 wide character
Lisp •
Printed Representation and Read Syntax
The printed representation of an object is the format of the output generated by the Lisp printer (the function prin1) for that object. The read syntax of an object is the format of the input accepted by the Lisp reader (the function read) for that object. •
Comments A comment is text that is written in a program only for the sake of humans that read the program, and that has no effect on the meaning of the program. ٣
•
Programming Types TYPE
SIZE (Bits)
Range
-134217728 to 134217727 Integer 28 Floating 0 to 524287 Character 19 Also contain these types :-Symbol Type , Sequence Types , Cons Cell and List Types , Array Type , String Type , Vector Type , Char-Table Type , Bool-Vector Type , Function Type , Macro Type , Primitive Function Type , Byte-Code Function TypeAutoload Type . •
Editing Types Type, Marker, Window, Frame, Window, Frame, Process, Stream.
Prolog Prolog's single data type is the term. Terms are either: atoms, numbers, and
variables Or compound terms (structures). The figure below presents a classification of the data types in Prolog:
Atoms: An atom is a general-purpose name with no inherent meaning. It is Composed of a sequence of characters that is parsed by the Prolog reader as single unit. Numbers: Numbers can be integers or real numbers (not used very much in typical Prolog programming. Variables: Variables are denoted by a string consisting of letters, numbers and Underscore characters, and beginning with an upper-case letter or underscore.
٤
Program structure in C\C++\Lisp\Prolog
C #include int main() { /* My first program */ printf("Hello, World! \n"); return 0; }
C++ // my first program in C++ #include using namespace std; int main () { cout << "Hello World!"; return 0; }
Lisp (+ 2 2) (defvar *x*)
; adds 2 and 2, yielding 4. ; Ensures that a variable *x* exists, ; without giving it a value. The asterisks are
part of ; the name. The symbol *x* is also hereby endowed with ; the property that subsequent bindings of it are dynamic, (setf *x* 42.1) value 42.1
; rather than lexical. ; sets the variable *x* to the floating-point
;; Define a function that squares a number: (defun square (x) (* x x)) ;; Execute the function: (square 3) ; Returns 9 ;; the 'let' construct creates a scope for local variables. Here ;; the variable 'a' is bound to 6 and the variable 'b' is bound ;; to 4. Inside the 'let' is a 'body', where the last computed value is returned. ;; Here the result of adding a and b is returned from the 'let' expression.
٥
;; The variables a and b have lexical scope, unless the symbols have been ;; marked as special variables (for instance by a prior DEFVAR). (let ((a 6) (b 4)) (+ a b)) ; returns 10
Prolog A Prolog program consists of a database of facts, rules, and queries. This program is, in essence, a knowledge base. •
• •
Fact: head but no body man(socrates). man(plato). Rules: head and body mortal(X) :- man(X). Questions: body but no head mortal(X). Use ``;'' to get next possible answer, Return to end. Yes means true with no variables, no means not consistent with database.
Data structure in C\C++\Lisp\Prolog
C 1-Arrays Declaration of arrays: type variable-name[50]; for example: float height[50]; Initialization of arrays: type array_name[size]={list of values}; int number[3]={0,0,0}; Multi dimensional Arrays: two dimension arrays data_type array_name[row_size][column_size]; int m[10][20]; a 3 dimensional array date_type array_name[s1][s2][s3]…..[sn]; int survey[3][5][12]; float table[5][4][5][3];
٦
2-Struct struct lib_books { char title[20]; char author[15]; int pages; float price; }; struct lib_books, book1, book2, book3; 3-Union: union item { int m; float p; char c; } code;
C++ 1-Arrays Similar to C array 2-Struct struct structure_name { member_type1 member_name1; member_type2 member_name2; member_type3 member_name3; . . } object_names; EX: struct product { int weight; float price; } ; product apple; product banana, melon; NOTE:C++ is a OOP language so it has additional data structure types.
٧
3-Object oriebted in C++:
(a) Classes A class is an expanded concept of a data structure: instead of holding only data, it can hold both data and functions. An object is an instantiation of a class. In terms of variables, a class would be the type, and an object would be the variable. Classes are generally declared using the keyword class, with the following format: class class_name { access_specifier_1: member1; access_specifier_2: member2; ... } object_names;
• • •
members of a class are accessible only from within other members of the same class or from their friends. protected members are accessible from members of their same class and from their friends, but also from members of their derived classes. public members are accessible from anywhere where the object is visible. private
EX // classes example #include using namespace std; class CRectangle { int x, y; public: void set_values (int,int); int area () {return (x*y);} }; void CRectangle::set_values (int a, int b) { x = a; y = b; } int main () { CRectangle rect; rect.set_values (3,4); cout << "area: " << rect.area(); return 0; }
٨
Lisp 1-array Declaration of arrays: (typep (make-array ... :element-type 'A ...) '(array A)))
Initialization of arrays: (make-array '(4 2 3) :initial-contents '(((a b c) (1 2 3)) ((d e f) (3 1 2)) ((g h i) (2 3 1)) ((j k l) (0 0 0))))
2-Struct different structures may print out in different ways; the definition of a structure type may specify a print procedure to use for objects of that type (see the :printfunction option to defstruct). The default notation for structures is #S(structure-name slot-name-1 slot-value-1 slot-name-2 slot-value-2 ...)
where #S indicates structure syntax, structure-name is the name (a symbol) of the structure type, each slot-name is the name (also a symbol) of a component, and each corresponding slot-value is the representation of the Lisp object in that slot.
Prolog Lists in Prolog A list of terms can be represented betweenbrackets:[a, b, c, d] Its head is a and its tail is [b, c, d]. The tail of [a] is [ ], the empty list. Lists may contain lists: [3.3, [a, 8, [ ]], [x], [p,q]] is a list of four items. Special form to direct pattern matching: • The term [X|Y] matches any list with at least one element: X matches the head of the list, and Y matches the tail. The term [X,Y,77|T] matches any list with at least three elements whose third element is the number 77:X matches the first element,Y matches the second element, and T matches rest of the list after the third item. Using these pattern matching facilities, values can be specified as the intersection of constraints on terms instead of by direct assignment. Use variable names that are suggestive: [ Head | Tail ] or [ H | T ]
٩
Branching in C\C++\Lisp\Prolog
if Statement: if (condition) statement; EX: if (i=1) printf("%d",i);
The If else construct: if (num < 0) printf ("The number is negative") else printf ("The number is positive") Compound Relational tests: a> if (condition1 && condition2 && condition3) b> if (condition1 // condition2 // condition3)
The syntax in the statement ‘a’ represents a complex if statement which combines different conditions using the and operator in this case if all the conditions are true only then the whole statement is considered to be true. Even if one condition is false the whole if statement is considered to be false. The statement ‘b’ uses the logical operator or (//) to group different expression to be checked. In this case if any one of the expression if found to be true the whole expression considered to be true, we can also uses the mixed expressions using logical operators and and or together. Nested if Statement if (condition1) if (condition2) statement-1; else statement-2; else statement-3;
The ELSE If Ladder if (condition1) statement – 1; else if (condition2) statement2; else if (condition3) statement3; else if (condition)
١٠
statement n; else default statement; statement-x;
The Switch Statement: Switch (expression) { Case case-label-1; Case case-label-2; Case case-label-n; ……………… Case default }
The GOTO statement: a> goto label; ………… ………… ………… Label; Statement; b> label; ………… ………… ………… goto label; EX: #include //include stdio.h header file to your program main () //start of main { int n, sum = 0, i = 0 // variable declaration printf ("Enter a number") // message to the user scanf ("%d", &n) //Read and store the number loop: i++ //Label of goto statement sum += i //the sum value in stored and I is added to sum if (i < n) goto loop //If value of I is less than n pass control to loop printf ("\n sum of %d natural numbers = %d", n, sum) //print the sum of the numbers & value of n }
C++ Similar to C but do not contain GOTO statement.
١١
LISP cond By using the convention that a zero value is false and a non-zero value is true, LISP allows conditional branching and boolean logic. The cond function takes a series of condition-result pairs. This construct is similar to a Switch-Case block in C. e.g. ( defun abs-val(x) (cond ( (< x 0) (-x) ) ( (>= x 0) x ) ) ) if The if function takes an expression to be examined as true or false, and returns one of its two other parameters, depending upon the result. e.g. (if (< x 0) (-x) x) Boolean operators The and and or functions act as boolean operators. Their left to right checking gives rise to a side-effect which is often used as a conditional branching technique. and stops checking when it encounters one item which is false, while or stops checking when it encounters one true item.
Prolog if(Condition, TrueClause, FalseClause) :Condition, !, TrueClause; !, FalseClause)
Prolog already has an "if_then_" operator: Condition -> TrueClause; !, FalseClause EX: if(X, Y) :\+ var(X), var(Y), X is 1, % if this fails, prolog tries the next clause of if/2
١٢
Y is 0. if(X, Y) :\+ var(X), var(Y), Y is 0. ?- if(0, A). A = 1. ?- if(1, A). A = 0.
Looping in C\c++\Lisp\Prolog in looping process in general would include the following four steps 1. Setting and initialization of a counter 2. Exertion of the statements in the loop 3. Test for a specified conditions for the execution of the loop 4. Incrementing the counter
C The While Statement: while (test condition) { body of the loop }
The Do while statement: Do { statement; } while(expression);
The Break Statement: EX: while(1) // While loop starts { scanf(“%d”,&I); // read and store the input number if(I==-1) // check whether input number is -1 break; //if number –1 is input skip the loop sum+=I; //else add the value of I to sum num++ // increment num value by 1 }}
Continue statement: Continue;
١٣
For Loop: The for loop provides a more concise loop control structure. The general form of the for loop is: for (initialization; test condition; increment) { body of the loop } EX: for(I=0;I < = 30; I+=2) //for loop { sum+=I; //add the value of I and store it to sum sum_of_squares+=I*I; //find the square value and add it to sum_of_squares } //end of for loop printf(“Sum of first 15 positive even numbers=%d\n”,sum); //Print sum printf(“Sum of their squares=%d\n”,sum_of_squares); //print sum_of_square }
C++ Similar to C
Lisp LISP has no loop constructs, so recursion is the only way to process data. A recursive function is a function which calls itself. This technique recognizes that an operation on some data may be best expressed as the aggregate of the same operation performed on each item of data of which it is comprised. Obviously this technique is best used with data structures which have the same form at both higher and lower levels, differing only in scale. This focus on recursion is the reason for LISP's popularity with AI researchers, who often attempt to model large-scale behavior in terms of smaller-scale decisions. For instance, recursion is often used in LISP to search state spaces. Many of the lists used in LISP programs would be better referred to as trees. Lists are simply the mechanism used to represent those trees. The car and cdr functions are generally used to recourse (or 'walk') through the elements in a tree, while cons is often used to gradually build tree structures to form the result of a recursive operation. By also using the null function to test for an empty
١٤
list, we can walk through the tree structure, dealing with successively smaller pieces of the tree. car returns the first element of a list. e.g. ( car '(a b c) ) evaluates to a. cdr returns the list with the first element removed. e.g. ( cdr '(a b c) ) evaluates to (b c). cons are an associated function which is used to build tree structures, often to form the result of a recursive operation. Note that it does not simply concatenate lists, but undoes the effects of a hypothetical use of car and cdr. e.g. ( cons '(a b) '(c d e) ) evaluates to ( (a b) (c d e)) rather than (a b c d e). Note that the use of these functions can lead to a great deal of inefficient copying.
Prolog 1-looping using command
repeate
command_loop:repeat, write('Enter command (end to exit): '), read(X), write(X), nl, X = end.
The last goal will fail unless end is entered. The repeat/0 always succeeds on backtracking and causes the intermediate goals to be re-executed. We can execute it by entering this query. ?- command_loop.
We will write a new predicate called do/1, which executes only the commands we allow. Many other languages have 'do case' control structures that perform this kind of function. Multiple clauses in a Prolog predicate behave similarly to a 'do case.' Here is do/1. Notice that it allows us to define synonyms for commands, that is, the player can enter either goto(X) or go(X) to cause the goto/1 predicate to be executed. do(goto(X)):-goto(X),!. do(go(X)):-goto(X),!. do(inventory):-inventory,!. do(look):-look,!.
NOTE: The cut serves two purposes. First, it says once we have found a 'do' clause to execute, don't bother looking for anymore. Second, it prevents the backtracking initiated at the end of command_loop from entering the other command predicates.
١٥
Here are some more do/1's. If do(end) did not always succeed, we would never get to the' X = end' test and would fail forever. The last do/1 allows us to tell the user there was something wrong with the command. do(take(X)) :- take(X), !. do(end). do(_) :write('Invalid command').
We can now rewrite command_loop/0 to use the new do/1 and incorporate puzzle/1 in the command loop. We will also replace the old simple test for end with a new predicate, end_condition/1, that will determine if the game is over. command_loop:write('Welcome to Nani Search'), nl, repeat, write('>nani> '), read(X), puzzle(X), do(X), nl, end_condition(X).
Two conditions might end the game. The first is if the player types 'end.' The second is if the player has successfully taken the Nani. end_condition(end). end_condition(_) :have(nani), write('Congratulations').
The game can now be played from the top. ?- command_loop.
2-looping using recursion Most interesting algorithms involve repeatingsome group of actions. Prolog implements repetition using recursion. Recursion is closely related to mathematical induction, requiring two cases: Basis: Solve some initial or small version ofthe problem directly. Recursion: Assuming the algorithm works onsmaller or simpler versions of the problem, solve an arbitrary instance of the problem. Example sublist(S,L) succeeds if and only if the list S is asublist of the list L. sublist([a,b,c], [a,b,c,d,e]) succeeds. sublist([c,d], [a,b,c,d,e]) succeeds. sublist([b,d], [a,b,c,d,e]) fails. For list algorithms, the basis usually deals withan empty list, certainly the smallest list. (Some algorithms for lists do not handle theempty list; so begin with a singleton list, [H]). For the recursion step, we define the algorithmfor the arbitrary list, [H|T], assuming that it works correctly for its tail T, a smaller list.
١٦
Sublist basis The empty list is a sublist of any list. sublist([ ], L). % 1 Sublist recursion List [H|T] is a sublist of the list [H|U] if list T is a sublist of list U starting at the first position. sublist([H|T], [H|U]) :- initialsublist(T,U). % 2 initialsublist([ ], L). % 3 initialsublist([H|T],[H|U]) :- initialsublist(T,U). % 4 Or the list S is a sublist of the list [H|T] if it is a sublist of T. sublist(S, [H|T]) :- sublist(S,T). % 5 These two cases correspond to the situation where the sublist begins at the start of the list or the sublist begins later in the list, the only two possibilities. Sample Executions sublist([b,c,d], [a,b,c,d,e,f]) % 5 because sublist([b,c,d], [b,c,d,e,f]) % 2 because initialsublist([c,d], [c,d,e,f]) % 4 because initialsublist ([d], [d,e,f]) % 4 because initialsublist ([ ], [e,f]) % 3 sublist([b,d], [b,c,d]) fails % 2 because initialsublist([d], [c,d]) fails and % 5 because sublist([b,d], [c,d]) fails % 5 because sublist([b,d], [d]) fails % 5 because sublist([b,d], [ ]) fails
Resources 1-http://en.wikipedia.org/wiki/Logic_programming 2-http://www.exforsys.com/tutorials/c-language/decision-makinglooping-in-c.html 3-http://www.amzi.com/AdventureInProlog/a14cntrl.htm 4-http://www.murrayc.com/learning/AI/lisp.shtml 5-http://www.cplusplus.com/doc/tutorial/variables/ 6-http://www.zvon.org/other/elisp/Output/SEC20.html 7-http://www.experiencefestival.com/a/prolog%20%20data%20types/id/1866789 8-http://www.csupomona.edu/~jrfisher/www/prolog_tutorial/2_7.html
١٧
١٨