You are on page 1of 24

St.

Peter’s Engineering College (Autonomous)


Dullapally (P), Medchal, Hyderabad – 500100.
III B.Tech I Semester Regular Examinations – December 2023
Subject Name: Principles of Programming Languages Branch: CSE
Regulation: SR-20 Subject Code: AS20-05PE13
Time: 3 Hrs Max. Marks: 70

Note: Answer all Questions. Each Question carries equal marks.

BLOOMS LEVEL
Remember L1 Understand L2 Apply L3
Analyze L4 Evaluate L5 Create L6

PART - A
Q.N Answer All the Questions (10 x 2 = 20M) Marks BL
o
1 Write short note on BNF? 2M L1
Ans:-BNF, or Backus-Naur Form, is a notation used in computer
science and Principles of Programming Languages (PPL) to describe
the syntax of programming languages, context-free grammars, and
formal languages. It was introduced by John Backus and Peter Naur in
the 1960s. BNF is widely used in the specification of programming
languages and serves as the foundation for compiler and parser design.
2 Define Lexeme, Pattern and Token 2M L1
Ans:- Token:- Token is a sequence of characters that are treated as a unit
as it cannot be further broken down.
Lexeme:-it is a sequence of characters in the source code that are
matched by given predefined language rules for every lexeme to
be specified as a valid token.
Pattern:-it specifies a set of rules that a scanner follows to create a token
3 Explain in detail various design issues of character string 2M L2
types.
Ans:- Character string types are essential components in programming
languages, providing a way to represent and manipulate sequences of
characters.
The design issues related to character string types:-

1.Representation:-
Characters are represented in memory is a fundamental design
issue. Common representations include ASCII, Unicode, and UTF-8.

2.Length Representation:-
How the length of a string is stored is a crucial decision. Some
languages use a null-terminated approach, where a special character
(like \0) marks the end of the string. Others use a length prefix,
indicating the number of characters in the string.

3.Immutable vs. Mutable Strings:-


Whether strings are mutable (modifiable) or immutable
(unchangeable) influences how operations like concatenation and
substring creation are implemented. Immutable strings are safer in
concurrent programming but may be less efficient for certain
operations.

4 What are the design issues for names? 2M L3


Ans:- The design of names, including identifiers, variables, functions,
and other named entities, is a crucial aspect of programming languages.
The design issues are:-
1.Syntax Rules for Identifiers:-
Establishing clear syntax rules for identifiers, such as variable names
and function names, ensures consistency and readability. Common rules
include starting with a letter, allowing alphanumeric characters and
underscores, and avoiding reserved words.

2.Case Sensitivity:-
Deciding whether identifiers are case-sensitive or case-insensitive
affects naming conventions. Languages like C and C++ are case-
sensitive, while languages like Python are case-insensitive.

3.Reserved Words:-
Identifying and defining a set of reserved words (keywords) is
critical. These words have predefined meanings in the language and
cannot be used as identifiers.
5 What are the design issues for sub programs 2M L1
Ans:- Subprograms,also known as subroutines, functions, methods, or
procedures, play a vital role in programming languages by allowing
code to be organized into reusable units.
1.Interface Design:
Defining the interface of a subprogram includes specifying the
name, parameters, return type, and visibility. A well-designed interface
promotes clarity and ease of use.

2.Parameter Passing:-
Deciding how parameters are passed to subprograms is a crucial
design decision. Common methods include pass by value, pass by
reference, pass by result, and pass by name. The choice impacts
memory usage, side effects, and efficiency.
6 Write about Generic Subprograms 2M L2
Generic subprograms, also known as generic functions or polymorphic
functions, allow developers to write code that can operate on different
types of data without sacrificing type safety. This feature is particularly
useful in situations where a certain algorithm or operation is
conceptually the same but can be applied to a variety of data types.
Generic subprograms are designed to provide flexibility and reusability
across different data types.
7 Explain how information hiding is provided in an ADA 2M L2
package.
In Ada, information hiding is a key concept supported by the
package construct. Ada's package mechanism allows developers to
encapsulate data and procedures, controlling the visibility and
accessibility of these elements.
Here's how information hiding is provided in an Ada package:

1.Package Specification:The package specification defines the interface


to the outside world. It includes declarations of types, subprograms
(procedures and functions), and constants that are meant to be visible to
other parts of the program.

2.Private Types:Ada allows the declaration of private types within a


package. The private keyword is used to indicate that the type is private
to the package and its details are not visible outside.
8 What is the difference between a C++ class and an Ada 2M L2
package?
While both provide encapsulation, C++ classes are more flexible in member
access, whereas Ada packages offer explicit visibility control and promote a
clearer modular design with separate compilation
C++ Class:
Defined using the class keyword.
Includes data members and member functions.
Ada Package:
Used for encapsulation in a modular way.
Has a clear separation between specification and body.

9 Explain the features of functional programming 2M L2


languages
Functional programming languages exhibit several distinctive features
that set them apart from imperative or object-oriented languages. Here
are key features of functional programming languages:
Immutable Data:Data, once created, cannot be changed (immutable).
Instead of modifying existing data, functional programming encourages
the creation of new data structures.
Recursion: is often preferred over traditional iterative constructs. It
aligns well with the functional paradigm and eliminates the need for
mutable state in many cases.

10 What are the applications of logic programming. 2M L2


Logic programming is a programming paradigm that is based on formal
logic. In logic programming languages, programs are expressed as
logical statements, and computation is performed by making logical
inferences.
Applications are:
1.Artificial Intelligence (AI)
2.Expert Systems
3.Natural Language Processing (NLP)
4.Knowledge Representation
5.Database Querying
6.Semantic Web
7.Constraint Logic Programmin

PART - B
Mark
Q.No Question Description (10 x 5 = 50M) BL
s
a)Describe the important factors influencing the
writability of a language
The writability of a programming language refers to how easily and
effectively developers can write code in that language. Several factors
influence the writability of a programming language.
1.Syntax Clarity: The writability of a programming language refers to
how easily and effectively developers can write code in that language.
Several factors influence the writability of a programming language.
2.Abstraction Level:Higher-level abstractions simplify code, making it
more concise and easier to write.
1 3.Error Handling Mechanisms:Effective error handling mechanisms, 5M L2
such as informative error messages and exception handling, can
significantly improve writability by aiding developers in identifying and
fixing issues.
4. Flexibility:A language that offers flexibility in coding styles and
paradigms allows developers to choose approaches that best suit their
problem domain
5. Readability:Readable code is writable code. A language that
encourages clear and readable code, with consistent formatting and
naming conventions, enhances writability by making it easier for
developers to understand and write code.
b) What are the formal methods of describing syntax 5M L2
Formal methods of describing syntax are techniques used to precisely define
the structure of a programming language or any formal language. These
methods aim to provide a clear and unambiguous specification of the syntax,
ensuring that the language's grammar is well-defined. Here are some common
formal methods for describing syntax:
1. Backus-Naur Form (BNF):BNF is one of the earliest and widely
used formal methods for describing the syntax of programming
languages. It uses production rules to define the structure of a language.
BNF is particularly popular for specifying the syntax of context-free
grammars.
Example BNF rule: <expression> ::= <term> "+" <expression> | <term>
2. Extended Backus-Naur Form (EBNF):EBNF is an extension of
BNF that includes additional symbols and constructs for expressing
more complex syntactic structures. It often includes features like
optional elements, repetition, and grouping.
Example EBNF rule: expression = term, { "+", term } ;
3. Abstract Syntax Notation One (ASN.1):ASN.1 is a standard
interface description language used for defining data structures that can
be serialized and deserialized in a cross-platform way. It is often used in
telecommunication protocols.
Example ASN.1 definition: MyType ::= SEQUENCE {
Field1 INTEGER, field2 OCTET STRING }
4. W3C XML Schema Definition (XSD):XSD is a formal specification
language for XML documents. It defines the structure, data types, and
constraints of XML documents. XSD documents are written in XML.
Example XSD definition: <xs:element name="book" type="xs:string"/>
5. Railway Oriented Programming (ROP):ROP is a more recent
approach that uses diagrams resembling railway tracks to describe the
syntax of programming languages. It provides a visual representation of
the language's grammar.
Example ROP diagram: Start -> "if" -> Condition -> "then" ->
Expression -> "else" -> Expression

6. Parsing Expression Grammar (PEG):PEG is a formalism for


describing the syntax of programming languages. PEGs are used for
defining recursive-descent parsers, and they are capable of expressing
both lexing and parsing in a single grammar.
Example PEG rule: statement = if-statement / while-statement /
assignment
2 What are the three general methods of implementing a 10 L2
programming language? M
The implementation of a programming language involves transforming
its source code into executable code that can be run on a computer.
There are three general methods of implementing a programming
language:

1.Interpretation:In an interpreted language implementation, the source


code is directly executed by an interpreter without the need for a separate
compilation step. The interpreter reads the source code line by line and
executes the corresponding operations.

Advantages:
Easier debugging and development cycle.
Platform independence, as the interpreter can be designed to run on
different systems.
Disadvantages:
Generally slower execution compared to compiled languages.
Interpretation overhead may impact performance.
Examples: Python, JavaScript (in certain environments), Ruby.
2.Compilation:Compilation involves translating the entire source code
of a program into machine code or an intermediate code before
execution. This process is performed by a compiler, which generates an
executable file that can be run independently of the source code.
Advantages:
Generally results in faster execution as the entire program is optimized
during compilation.
Code is not exposed, providing a level of security.
Disadvantages:
Longer development cycles due to the separate compilation step.
Platform-dependent executables unless additional tools (like virtual
machines) are used.
Examples: C, C++, Java (with Java Virtual Machine), C# (with Common
Intermediate Language).
3.Just-In-Time Compilation (JIT):JIT compilation is a hybrid
approach that combines elements of interpretation and compilation. The
source code is initially translated into an intermediate representation, and
this intermediate code is then compiled into machine code at runtime,
just before execution.
Advantages:
Combines the advantages of interpretation (quick development cycle)
and compilation (optimized machine code).
Platform independence for the intermediate code.
Disadvantages:
Initial interpretation step may introduce some overhead.
require additional runtime support.
Examples: Java (with HotSpot JVM), C# (with .NET's Common
Language Runtime).
3 a)What are the design issues for character string types? 5M L2
Discuss.
Ans:- Character string types are essential components in programming
languages, providing a way to represent and manipulate sequences of
characters. The design of character string types involves addressing
various issues to ensure efficiency, flexibility, and compatibility with the
language's overall design.

1.Representation:-
Characters are represented in memory is a fundamental design issue.
Common representations include ASCII, Unicode, and UTF-8. The
choice affects the range of characters that can be supported and the
memory required for each character.

2.Length Representation:-
How the length of a string is stored is a crucial decision. Some
languages use a null-terminated approach, where a special character (like
\0) marks the end of the string. Others use a length prefix, indicating the
number of characters in the string.

3.Immutable vs. Mutable Strings:-


Whether strings are mutable (modifiable) or immutable
(unchangeable) influences how operations like concatenation and
substring creation are implemented. Immutable strings are safer in
concurrent programming but may be less efficient for certain operations.

4.Character Set Support:-


The set of supported characters, including special characters,
whitespace, and non-printable characters, should be clearly defined. This
affects the language's ability to handle various writing systems and
character encodings.

5.String Operations:-
The set of operations that can be performed on strings, such as
concatenation, substring extraction, and searching, needs to be well-
defined. The efficiency of these operations can impact the overall
performance of string manipulation.

6.Literal Representation:-
How string literals are represented in source code affects readability
and ease of use. Common approaches include using double or single
quotes, and some languages support multi-line string literals.

7.Escape Sequences:-
The design must specify how escape sequences are handled within
strings. Escape sequences allow the representation of special characters
(e.g., newline, tab) and Unicode characters.

8.Comparison and Equality:-


Defining how string comparison and equality are performed is
crucial. It involves considerations such as case sensitivity, locale-
awareness, and the use of special comparison operators.

9.Subscripting and Slicing:-


If the language supports subscripting (accessing individual characters
by index) and slicing (extracting substrings), the rules for these
operations must be clearly defined, including the handling of out-of-
bounds indices.
10.Concatenation:-
The design must specify how string concatenation is handled,
including the efficiency of the operation and whether it involves creating
new string objects.

b) Explain the differences between subtypes and derived 5M L2


types
Subtypes:
1.Definition:
In Programming Languages:
In the context of programming languages, a subtype is a data type that is
related to another (called the supertype or base type) and represents a
more specialized version of it. Subtypes inherit properties from their
supertypes.
In Database Systems:
In the context of databases, subtypes are used in entity-relationship
modeling. They represent specialized entities related to a more general
entity (the supertype). Subtypes share some common attributes with the
supertype but may also have additional attributes.
2,Inheritance:
In Programming Languages:
Subtypes in programming languages often involve inheritance. A
subtype inherits the properties (fields and methods) of its supertype and
may extend or override them.
In Database Systems:
Subtypes in databases represent an "is-a" relationship, indicating that the
subtype is a specialized version of the supertype. This relationship
allows for more precise modeling of the real-world entities.
3.Usage:
In Programming Languages:
Subtypes are used for polymorphism and code reuse. They allow for the
creation of more specific types based on existing ones, promoting
modularity and extensibility.
In Database Systems:
Subtypes help model hierarchical relationships between entities,
allowing for more accurate representation of the underlying data.

Derived Types:
• Definition:
In Programming Languages:
Derived types refer to new types that are created based on existing types.
This can include types that are derived through operations like arrays,
pointers, or user-defined operations.
In Database Systems:
Derived types can refer to types that are generated based on the data in
the database. For example, a query result or a view can be considered a
derived type.
• Creation:
In Programming Languages:
Derived types in programming languages can be created through
operations like array declarations, pointer declarations, or through user-
defined operations.
Database Systems:
Derived types in databases can be created through queries that combine
or transform existing data.
• Relationship with Base Types:
In Programming Languages:
Derived types in programming languages may have a more direct
relationship with base types. For example, an array is a derived type of
the element type.
In Database Systems:
Derived types in databases may represent transformations or
combinations of existing types.

4 What is type checking? Differentiate between static and


dynamic type checking and give their relative advantages. 10 M L3
Type checking:-is a process in which a programming language's
compiler or interpreter verifies that the program's usage of variables and
expressions is consistent with the types specified in the program. The
goal is to catch type-related errors before the program runs, improving
reliability and preventing unintended behaviors.

Static Type Checking:


• Definition:
Static type checking occurs at compile-time. The types of variables and
expressions are checked during the compilation process, and any type-
related errors are flagged before the program is executed.
• Advantages:
• Early Detection of Errors:
Static type checking catches errors before the program is run, providing
early detection and reducing the likelihood of type-related runtime
errors.
• Performance Optimization:
Since types are known at compile-time, optimizations can be applied to
the generated machine code, leading to potentially more efficient
execution.
• Improved Code Quality:
Static typing often leads to more readable and self-documenting code.
Type annotations can serve as a form of documentation, making it easier
for developers to understand the code.
• Refactoring Support:
Tools and IDEs can leverage type information to provide better code
refactoring support, helping developers make changes to their code with
confidence.

Dynamic Type Checking:


• Definition:
Dynamic type checking occurs at runtime. The types of variables and
expressions are checked as the program runs, and errors are detected
when inappropriate type operations are performed.
• Advantages:
• Flexibility:
Dynamic typing allows for more flexible and concise code, as variables
can change their type during runtime. This can be advantageous in
certain situations where the program's structure is more dynamic.
• Rapid Development:
Dynamic typing can speed up the development process, especially in the
early stages of a project, as developers don't need to explicitly declare
types.
• Ease of Prototyping
Dynamic typing is often preferred in prototyping and scripting
languages, where the emphasis is on quick development and
experimentation.
• Late Binding:
Late binding allows for dynamic dispatch and polymorphism, facilitating
the creation of more abstract and extensible code.

Relative Advantages:

• Static Type Checking:


• Safety:
Static type checking provides an additional layer of safety by catching
potential type-related errors before runtime, reducing the likelihood of
runtime crashes.
• Performance Optimization
The knowledge of types at compile-time allows for performance
optimizations, leading to potentially more efficient code execution.
• Code Quality
Static typing can contribute to better code quality by making the code
more self-documenting and by enforcing type-related constraints.
• Dynamic Type Checking
• Flexibility:
Dynamic typing allows for more flexible and concise code,
accommodating a variety of data types without explicit type
declarations.
• Rapid Development:
Dynamic typing can speed up the development process, especially
during the prototyping phase, by allowing developers to write and
modify code more quickly.
• Ease of Refactoring:
Dynamic typing can simplify certain code refactoring tasks, as the same
variable can take on different types during the program's execution.

5 a)Explain how subprogram is overloaded? Give 5M


L1
examples.
Subprogram overloading refers to the ability to define multiple subprograms
(functions or procedures) within the same scope that share the same name but
differ in terms of their parameters.
There are two types of overloading: static (compile-time) and dynamic (run-
time).

Static Overloading (Compile-Time):


Static overloading is resolved at compile-time based on the number and
types of parameters in the subprogram's signature.

Example in Java:
public class OverloadedExample {
// Method with two integer parameters
public static int add(int a, int b) {
return a + b;
}
// Method with three double parameters
public static double add(double a, double b, double c) {
return a + b + c;
}

public static void main(String[] args) {


System.out.println(add(5, 7)); // Calls the first version
System.out.println(add(2.5, 3.5, 1.5)); // Calls the second
version
}
}
In this Java example, the add method is overloaded with two versions: one that
takes two integers and another that takes three doubles s. The correct version is
determined at compile-time based on the method call.

Dynamic Overloading (Run-Time):


Dynamic overloading is resolved at run-time and is typically associated
with languages that support polymorphism through features like function
overloading or generic programming.

Example in Python:

class OverloadedExample:
# Method with two parameters of any type
def add(self, a, b):
return a + b

# Creating an instance of the class


obj = OverloadedExample()

# Calls the method with two integer parameters


result1 = obj.add(5, 7)
print(result1)

# Calls the method with two string parameters


result2 = obj.add("Hello", "World")
print(result2)
In this Python example, the add method of the OverloadedExample class can
accept parameters of any type. Python supports dynamic typing and
polymorphism, allowing the method to handle different types of parameters
during runtime.

b) Demonstrate the need of Co-Routines with an example. 5M L2


Coroutines are useful in scenarios where you have concurrent tasks that
need to cooperate and communicate with each other. Unlike traditional
functions, coroutines allow for non-blocking execution, making them
valuable in situations where asynchronous programming is required.
Ex:-Consider a scenario where you need to download data from multiple
URLs concurrently. Using coroutines, you can efficiently perform
asynchronous downloads without blocking the entire program. Below is
an example using Python's asyncio module:

import asyncio
import aiohttp

async def fetch_data(url):


async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()

async def download_data(urls):


tasks = [fetch_data(url) for url in urls]
results = await asyncio.gather(*tasks)
return results

async def main():


urls = [
'https://example.com/api/data1',
'https://example.com/api/data2',
'https://example.com/api/data3',
]

results = await download_data(urls)


for url, data in zip(urls, results):
print(f'Data downloaded from {url}: {len(data)} characters')

if __name__ == "__main__":
asyncio.run(main())

In this example:

• The fetch_data coroutine is responsible for asynchronously


fetching data from a given URL using the aiohttp library.
• The download_data coroutine creates a list of tasks, each
corresponding to downloading data from a specific URL.
• The asyncio.gather function is used to concurrently execute all the
tasks and wait for their completion.
• The main coroutine sets up a list of URLs and asynchronously
downloads data from them using download_data.

6 Explain the generic subprograms in Ada with an example. L2


In Ada, generic subprograms are a powerful feature that allows you to 10 M
define subprograms (functions or procedures) in a generic and reusable
way. Generic subprograms enable you to write algorithms or operations
that can be used with different data types without duplicating code.
Here's an explanation of generic subprograms in Ada with an example:

Generic Subprogram Syntax:


type Generic_Type is private; -- Declare a generic type
-- Additional generic parameters can be specified here
procedure or function Generic_Subprogram(Parameter_1 : in
Generic_Type; ...; Parameter_n : out Generic_Type);

Example of a Generic Subprogram in Ada:


Let's create a generic subprogram that swaps the values of two variables
of any data type:

with Ada.Text_IO; use Ada.Text_IO;

procedure Generic_Swap is
generic
type Element_Type is private;
procedure Swap(A, B : in out Element_Type);

procedure Swap(A, B : in out Element_Type) is


Temp : Element_Type;
begin
Temp := A;
A := B;
B := Temp;
end Swap;

-- Example usage
A, B : Integer := 5;
C, D : Float := 3.14;
begin
Put_Line("Before swapping:");
Put_Line("A = " & Integer'Image(A) & ", B = " & Integer'Image(B));
Swap(A, B);
Put_Line("After swapping:");
Put_Line("A = " & Integer'Image(A) & ", B = " & Integer'Image(B));

Put_Line("Before swapping:");
Put_Line("C = " & Float'Image(C) & ", D = " & Float'Image(D));
Swap(C, D);
Put_Line("After swapping:");
Put_Line("C = " & Float'Image(C) & ", D = " & Float'Image(D));
end Generic_Swap;

In this example:

• The Generic_Swap procedure is a generic subprogram that takes


two parameters of type Element_Type and swaps their values. It is
generic in the sense that it can work with variables of any type.
• The Swap procedure within the generic subprogram performs the
actual swapping of values. It uses a temporary variable of type
Element_Type for the swap.
• The Swap procedure is then instantiated with two specific data
types, Integer and Float, to demonstrate the generic subprogram's
usage.

a)Briefly Explain the Sub-program level concurrency. 5M


Sub-program level concurrency refers to a concurrency model in
programming languages where concurrency is achieved at the level of
subprograms, which are essentially functions or procedures. In this
model, different subprograms can be executed concurrently, allowing for
parallel execution of independent tasks within a program
1. Concurrency at the Function/Procedure Level:In sub-program
level concurrency, concurrency is introduced at the level of functions or
procedures. These functions or procedures can be executed
independently and concurrently.
2.Parallel Execution:The primary goal of sub-program level
concurrency is to enable parallel execution of independent tasks.
Different subprograms can be executed simultaneously, taking
advantage of multiple processor cores or parallel processing capabilities.
7 3.Isolation of Tasks:Each subprogram typically represents a distinct L3
task or computation. The tasks are designed to be independent of each
other to avoid conflicts and ensure that parallel execution does not lead
to data races or other concurrency-related issues.
4. Task Creation and Synchronization:Sub-program level concurrency
may involve mechanisms for creating and synchronizing tasks. Tasks
can be created to represent independent units of work, and
synchronization mechanisms are used to coordinate their execution
5. Task Communication:Communication between concurrently
executing subprograms may be facilitated through shared variables,
message passing, or other inter-task communication mechanisms. Proper
synchronization mechanisms are employed to avoid race conditions.
6. Concurrency Control:Concurrency control mechanisms are
implemented to manage access to shared resources, ensuring that
multiple tasks can access shared data without causing conflicts.
b)Explain about the concurrency in Ada 95. 5M
In Ada, concurrency is a fundamental feature that allows developers to
design and implement concurrent and parallel programs. Ada 95
introduced a tasking model, providing a powerful mechanism for
managing concurrent activities. Here are the key features of concurrency
in Ada 95:

1.Tasking Model:Ada 95 introduced a tasking model, allowing


developers to create and manage concurrent tasks. A task is a unit of
execution that runs concurrently with other tasks. Tasks can be created,
terminated, and synchronized to achieve parallelism.

2.Task Declaration:Tasks are declared explicitly using the task


keyword.

3. Task Bodies:Tasks in Ada have bodies, which contain the actual code
to be executed concurrently. The body of a task is defined separately
from the task declaration.
4. Task Activation:Tasks can be activated by creating task objects. Task
objects are created using the new keyword. Once a task is created, it
begins executing its body concurrently with other tasks.

5. Task Synchronization:Ada provides various mechanisms for task L1


synchronization, including entry calls, select statements, and rendezvous.
These mechanisms allow tasks to communicate and synchronize their
execution.

6. Protected Types:Ada supports protected types, which are used to


encapsulate shared data and synchronize access to that data among
concurrent tasks. Protected types provide a mechanism for mutual
exclusion and data encapsulation.

7. Asynchronous Transfer of Control (ATC): Ada supports


asynchronous transfer of control using the abort statement. This allows a
task to terminate another task or cancel a rendezvous.
8.Task Termination:Tasks can be explicitly terminated using the
terminate statement or by reaching the end of the task body. When a task
terminates, any outstanding rendezvous are canceled.
9.Task Priority:Ada allows developers to specify task priorities,
influencing the order in which tasks are scheduled for execution. Higher-
priority tasks are given preference in scheduling.
10.Task Packages:Ada provides predefined task-related packages, such
as Ada.Task_Identification and Ada.Real_Time, to facilitate task
management and real-time programming.
8 What is a semaphore? What are the operations on
semaphores? 10 M L2
A semaphore is a synchronization mechanism used in concurrent
programming to control access to shared resources by multiple processes
or threads. It is a variable or abstract data type that serves as a signaling
mechanism to enforce mutual exclusion and coordinate the execution of
concurrent processes.

The semaphore concept was introduced by Edsger Dijkstra in the 1960s.

Operations on Semaphores:
Semaphores support two fundamental operations: P (Wait) and V
(Signal). These operations are also sometimes referred to as down and
up, or acquire and release. The semaphore maintains a non-negative
integer value, often referred to as the semaphore's count or value.

1.P (Wait) Operation:The P operation decrements the semaphore count.


If the semaphore count is non-negative, the process continues its
execution. If the count is zero or negative, the process is blocked until
the semaphore count becomes positive.The P operation is often denoted
as P(S) or Wait(S).ex:-

P(S):
if S > 0:
S=S-1
else:
block the process
2. V (Signal) Operation:
The V operation increments the semaphore count. If there are processes
blocked on the semaphore, one of them is unblocked. If the semaphore
count becomes positive, a blocked process is allowed to continue.The V
operation is often denoted as V(S) or Signal(S).ex:-
V(S):
S=S+1
if there are blocked processes:
unblock one of them
Binary Semaphores and Counting Semaphores:
1.Binary Semaphore:
A binary semaphore, also known as a mutex (mutual exclusion), has a
count that can only be 0 or 1. It is used to control access to a critical
section, allowing only one process to enter at a time.
2.Counting Semaphore:
A counting semaphore can have a count greater than 1. It is used to
control access to a resource with multiple instances, and the count
represents the number of available instances.
Example Usage:
Consider a scenario where two processes need to access a shared
resource protected by a semaphore: from threading import Thread,
Semaphore

import time

shared_resource = 0

semaphore = Semaphore(1) # Binary semaphore with an initial count of


1

def process_one():

global shared_resource

semaphore.acquire()

shared_resource += 1

print(f"Process One: Shared Resource = {shared_resource}")

semaphore.release()

def process_two():

global shared_resource

semaphore.acquire()

shared_resource -= 1

print(f"Process Two: Shared Resource = {shared_resource}")

semaphore.release()

# Create two threads representing two processes

thread_one = Thread(target=process_one)

thread_two = Thread(target=process_two)
# Start the threads

thread_one.start()

thread_two.start()

# Wait for the threads to finish

thread_one.join()

thread_two.join()

In this Python example, a binary semaphore ( Semaphore(1)) is used to


protect access to the shared resource (shared_resource). The acquire and
release operations on the semaphore ensure that only one process can
access the critical section at a time, preventing race conditions.

Semaphores play a crucial role in coordinating and synchronizing


concurrent processes, helping to avoid conflicts over shared resources
and promoting orderly execution in a multi-process or multi-threaded
environment.

9 a)Describe about the basic elements of prolog 5M L1


Prolog (Programming in Logic) is a declarative programming language
designed for expressing and querying relations and rules in the form of
logical predicates. Here are the basic elements of Prolog: Here are the
basic elements of Prolog:
1.Facts: Syntax::-
predicate(term1, term2, ..., termN).
Explanation:Facts are the basic building blocks in Prolog. They
represent assertions about relationships or properties in the form of
predicates. Each fact is a statement indicating that a particular
relationship or property holds true.
2.Rules: Syntax:
head :- body.
Explanation:Rules define relationships or properties based on existing
facts or other rules. The head specifies the predicate being defined, and
the body contains conditions that must be satisfied for the rule to be true.
3.Queries: Syntax:
?- goal.
Explanation:Queries are used to pose questions or make queries about
the relationships defined in the facts and rules. The interpreter responds
with solutions or explanations for the given query..
4.Variables:Syntax:
Variable
Explanation:Variables are placeholders for values in Prolog queries.
They allow you to find all possible values that satisfy a given query
5.Lists:Syntax:
[element1, element2, ..., elementN]
Explanation:Lists are a fundamental data structure in Prolog, allowing
you to represent sequences of elements. Lists can be used to store
multiple terms and can be manipulated using various built-in predicates.
6. Cut Operator (!):Syntax:

Explanation:The cut operator is used to control the backtracking


behavior of Prolog. It commits to the choices made before the cut,
preventing further backtracking beyond that point. In the example, once
a parent relationship is found, the cut operator prevents backtracking to
explore other alternatives.
b) Explain the differences between Imperative and 5M
L2
functional languages.

1. Programming Paradigm:

Imperative:
Focuses on describing how a program operates, step by step.Emphasizes
changing program state through statements that modify variables and
control flow (e.g., loops, conditionals, assignments). Programs are
structured around sequences of commands that are executed in order.
• Functional:
Focuses on what the program should accomplish without specifying how
to achieve it.
Emphasizes the use of functions and expressions that produce values
without changing state.
Programs are structured around the composition of functions and the
application of functions to data.

2. State:
• Imperative:
Programs are stateful, and the emphasis is on changing the state of
variables.
Variables are mutable, and their values can be modified during program
execution.
Side effects (changes to state) are common and expected.
• Functional:
Programs are typically stateless, and the emphasis is on immutable data.
Variables are immutable, and once assigned, their values cannot be
changed.
Side effects are minimized, and functions are designed to be referentially
transparent (producing the same output for the same input).

3. Control Flow:
• Imperative:
Control flow is explicitly managed using statements like loops and
conditionals.
Emphasizes explicit sequencing and iteration.
• Functional:
Control flow is managed through function composition and recursion.
Emphasizes recursion and higher-order functions.

4. Data Mutation:
Imperative:
Supports mutable data structures, and changes to data are done in place.
Assignments and updates to variables are common.
• Functional:
Favors immutable data structures, and new data structures are created
rather than modified in place.
Avoids explicit assignments and updates, promoting a more declarative
style.

5. Side Effects:
• Imperative:
Programs often have side effects, such as modifying global variables,
performing I/O, or interacting with external state.
• Functional:
Minimizes or eliminates side effects to enhance predictability and ease
of reasoning about the code.

6. Concurrency:
• Imperative:
Often relies on locks and shared mutable state for managing
concurrency, which can lead to race conditions and synchronization
issues.
• Functional:
Emphasizes immutability and pure functions, which can simplify
concurrency by avoiding shared mutable state.

7. Examples:
• Imperative:
C, C++, Java, Python (to some extent), and most procedural languages.
• Functional:
Haskell, Lisp, ML, F#, and functional aspects of languages like Scala
and JavaScript.

8. Expression vs. Statement:


• Imperative:
Differentiates between expressions (returning values) and statements
(executing actions).
• Functional:
Tends to treat everything as an expression, where most constructs return
a value.

10 Explain the Basic primitives of LISP. Give suitable 10 M L2


examples.
LISP (List Processing) is a programming language known for its
simplicity and powerful support for symbolic expressions and symbolic
reasoning. LISP operates primarily on symbolic expressions, which are
represented as lists. Here are some of the basic primitives in LISP along
with examples:
1. Atoms:
Atoms are the simplest elements in LISP. They can be symbols,
numbers, or other constants.
; Examples of atoms
'hello ; Symbol
42 ; Number
'apple ; Symbol

2. Lists:
Lists are fundamental data structures in LISP. They can contain
atoms or other lists.
; Examples of lists
'(1 2 3) ; List of numbers
'(apple orange) ; List of symbols
'(1 (2 3) 4) ; Nested list

3. Symbols:
Symbols are used to represent names or identifiers. They can be
variables, function names, or other identifiers.
; Examples of symbols
'x
'length
'+

4. Numbers:
Numeric literals represent integers or floating-point numbers.
; Examples of numbers
42
-3.14

5. Functions:
Functions are a key feature of LISP. They can be defined using the
defun special form
; Example of defining a function
(defun square (x)
(* x x))

; Example of using a function


(square 5) ; Returns 25

6. Special Forms:
Special forms are expressions with special evaluation rules.
Examples include if, cond, and defun.
; Example of using if
(if (> 5 3)
'greater
'lesser) ; Returns 'greater

; Example of using cond


(cond
((= x 0) 'zero)
((< x 0) 'negative)
((> x 0) 'positive))

7. Variables:
Variables are used to store values. They are typically introduced
using setq or as function parameters

; Example of using variables


(setq x 10) ; Sets the value of x to 10
(+ x 5) ; Returns 15
8. Lambda Expressions:lambda expressions define anonymous
functions.
; Example of using lambda
(funcall (lambda (x) (* x x)) 3) ; Returns 9

9. Quoting:
Quoting prevents the evaluation of an expression, treating it as
data.
; Example of quoting
(setq y 5)
(list 'x y) ; Returns (x 5) without evaluating the value of y

10. Cons:
The cons function creates a new cons cell, forming a new pair.
; Example of cons
(cons 'a 'b) ; Returns (a . b)

..*****..

You might also like