V
Viva Preparation
10 Marks — 30 likely questions with model answers

Prolog Questions (10)

Q1. What is unification?
Unification is Prolog's way of making two terms identical by binding variables. For example, f(X, 3) = f(hello, Y) unifies by binding X=hello and Y=3. Unlike assignment, unification is bidirectional and works on structures.
Q2. Explain backtracking with an example.
When Prolog fails to satisfy a goal, it goes back to the most recent choice point and tries the next alternative. In member(X, [1,2,3]), Prolog first tries X=1. If subsequent goals fail, it backtracks and tries X=2, then X=3.
Q3. What does the cut (!) do?
Cut commits Prolog to the current clause and discards all choice points created since entering that clause. It prevents backtracking past the cut point, making the program more efficient (green cut) or changing its behavior (red cut).
Q4. Explain negation as failure.
\+ Goal succeeds if Goal fails and fails if Goal succeeds. It's not classical negation — it means "I cannot prove this." Critical rule: variables should be bound before negation, otherwise results may be logically incorrect.
Q5. What is the difference between =, is, and =:= ?
= is unification (structural matching). is evaluates the right-hand side arithmetically and unifies with the left. =:= evaluates both sides and checks arithmetic equality. X = 3+2 gives X=3+2 (a term); X is 3+2 gives X=5.
Q6. How does your graph traversal prevent infinite loops?
The route predicate maintains a "visited" list as an accumulator. Before moving to the next node, it checks \+ member(Next, Visited). This prevents revisiting nodes and creating infinite cycles in the graph.
Q7. Explain the three N-Queens approaches.
Generate-and-test generates all N^N boards and checks validity (slow). Permutation generates N! permutations (ensures unique columns) and checks diagonals. Incremental places queens row-by-row with column/diagonal sets, pruning early — fastest.
Q8. What is the R+C / R-C diagonal trick?
All cells on the same rising diagonal have the same Row+Col value, and all cells on the same falling diagonal have the same Row-Col value. By tracking these values in sets, we check diagonal conflicts in O(1).
Q9. What is a fail-driven loop?
A pattern like (Goal, fail ; true) that forces Prolog to find ALL solutions by always failing after each one, causing backtracking. Used to print every N-Queens solution.
Q10. Green cut vs red cut?
A green cut removes redundant computation without changing answers (optimization). A red cut changes program behavior — removing it gives different/extra answers. Red cuts are harder to reason about.

Java Concurrency Questions (10)

Q1. Why while(condition) wait() instead of if(condition) wait()?
Because of spurious wakeups — a thread can be woken without any notify call. Also, between the notify and acquiring the lock, another thread might have changed the condition. The while loop re-checks after every wakeup.
Q2. Why notifyAll() instead of notify()?
notify() wakes only one arbitrary thread. If that thread's condition isn't met, it goes back to waiting and no other thread wakes — potential deadlock. notifyAll() wakes all; each re-checks its condition.
Q3. volatile vs synchronized?
volatile ensures visibility — writes are immediately seen by other threads. But it's not atomic for compound ops like count++. synchronized provides both visibility AND mutual exclusion (only one thread at a time).
Q4. What is a race condition?
When correctness depends on thread timing. Two threads reading, incrementing, and writing a counter can lose updates. In A4, the cancel-vs-markPrinting race is handled by checking cancelRequested inside synchronized markPrinting.
Q5. Explain the SpoolerImpl shutdown sequence.
1) Set closed = true (volatile). 2) Interrupt dispatcher. 3) Join dispatcher. 4) pool.shutdown(). 5) awaitTermination(5s). 6) If stuck, shutdownNow().
Q6. What is a deadlock?
Two or more threads each waiting for a lock held by the other, creating a circular dependency. Prevention: never hold multiple locks, or always acquire in the same order. In A4, we hold one lock at a time.
Q7. What is the producer-consumer problem?
Producers add items to a bounded buffer; consumers remove them. If full, producers block; if empty, consumers block. Solved with synchronized + wait/notifyAll, as in BoundedJobQueue.
Q8. What is AtomicLong?
Atomic read-modify-write on a long using CPU-level CAS instructions. Faster than synchronized for simple counters because no lock is needed.
Q9. Why restore interrupt with Thread.currentThread().interrupt()?
Catching InterruptedException clears the interrupt flag. Restoring it lets outer code detect the interruption. Without this, the signal is silently lost.
Q10. What does the volatile cancelRequested flag do?
Enables fast, lock-free cancellation. The main thread sets it true; the worker checks between pages. Being volatile ensures the worker sees the update immediately without synchronized.

Haskell Questions (5)

Q1. What is an algebraic data type?
An ADT defines a type as a choice of constructors, each carrying data. data MinHeap a = Empty | Node a (MinHeap a) (MinHeap a) means a MinHeap is either Empty or a Node. Pattern matching is the primary way to work with ADTs.
Q2. Explain pattern matching.
Pattern matching decomposes values by their constructor. Multiple equations try each pattern top-to-bottom. size Empty = 0 matches empty heaps; size (Node _ l r) = 1 + size l + size r matches nodes, binding subtrees.
Q3. What does Ord a => mean?
A type class constraint: "type a must be orderable (supports <, >, compare)." Functions like merge need it for comparing values. Functions like size don't compare, so they have no constraint.
Q4. What is immutability?
Once created, values can't change. insertHeap creates a new heap rather than modifying the old one. This eliminates data races, simplifies reasoning, and enables referential transparency.
Q5. How does lazy evaluation work?
Haskell evaluates expressions only when needed. take 5 [1..] works with an infinite list because only 5 elements are computed. Elegant but can cause space leaks.

Cross-Cutting Questions (5)

Q1. Compare the three paradigms.
Prolog (Logic): Declare facts/rules; engine searches. Java (Imperative/OO): Step-by-step, mutable state, classes. Haskell (Functional): Pure functions, immutable data, no side effects.
Q2. What is referential transparency?
An expression can be replaced by its value without changing the program. In Haskell, add 3 5 always equals 8. Java methods may return different values due to mutable state.
Q3. Prolog search vs Java iteration?
Prolog uses depth-first search with backtracking automatically. Java requires explicit loops and state management. Prolog excels at constraint problems; Java gives full control.
Q4. What is type inference?
The compiler deduces types without explicit annotations. In Haskell, add x y = x + y infers Num a => a -> a -> a. Prolog is dynamically typed; Java requires explicit declarations.
Q5. What are higher-order functions?
Functions that take or return functions. map (*2) [1,2,3] applies (*2) to each element. All three languages support this: Haskell natively, Java via lambdas, Prolog via maplist/2.
!
Exam-Day Checklist
April 8 — CSE Ground Floor BTech Lab

Before the Exam

  • Bring keyboard/mouse if you took one from the lab
  • No phones, smartwatches, smart glasses
  • User ID = your roll number; password given during exam
  • Arrive by 9:15 AM, log in to DOMjudge early
  • Open terminal: Ctrl+Alt+T, then code --no-sandbox for VSCode
  • PXE Ubuntu 24.04 — NO persistent storage, don't switch off!

First 5 Minutes

  • Read ALL problems before coding anything
  • Identify which problems map to which assignment patterns
  • Start with the problem you're most confident about
  • Make a small test submission to verify setup works

During the Exam

  • Check DOMjudge verdict after EVERY submission
  • "Compile Error" — check syntax, missing imports, package declarations
  • "Wrong Answer" — check output format (spaces, newlines, trailing output)
  • "Run Error" — check for exceptions, division by zero, empty input
  • If stuck 10+ min — move to next problem, come back later
  • Save code in VSCode frequently (no persistent storage!)

"If Stuck" Protocol

  1. Re-read the problem statement carefully
  2. Is this a pattern you studied? (graph traversal, bounded queue, tree recursion)
  3. Write the simplest version that handles the basic case
  4. Submit partial solutions — partial credit may be given
  5. After 10 min: move on, maximize total marks across all sections
R
Quick Reference Cards
Last-minute review — memorize these patterns

PROLOG QUICK REFERENCE

Syntax

% Fact, Rule, Query
parent(tom, bob).
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
?- grandparent(tom, Who).

% List: [Head | Tail]
% Arithmetic: X is 3+2, X =:= 5, X =\= 3
% Negation: \+ Goal, X \= Y
% Cut: !

Templates

% LIST RECURSION
f([], []).
f([H|T], [H2|T2]) :- transform(H, H2), f(T, T2).

% GRAPH TRAVERSAL
path(A, B, P) :- helper(A, B, [A], R), reverse(R, P).
helper(B, B, V, V).
helper(A, B, V, P) :- edge(A, N), \+ member(N, V),
                       helper(N, B, [N|V], P).

% N-QUEENS INCREMENTAL
place([], _, _, _, _, []).
place([R|Rs], N, Cs, Us, Ds, [C|M]) :-
    between(1,N,C), \+ member(C,Cs),
    U is R+C, \+ member(U,Us),
    D is R-C, \+ member(D,Ds),
    place(Rs, N, [C|Cs], [U|Us], [D|Ds], M).

I/O

:- initialization(main).
main :- read_line_to_string(user_input, L),
        split_string(L, " ", " \t\r\n", Ps),
        maplist(number_string, Nums, Ps),
        % ... process Nums ...
        halt.
Gotchas: (1) = vs is vs =:=. (2) Bind vars BEFORE negation. (3) =< not <=.

JAVA CONCURRENCY QUICK REFERENCE

The Pattern

synchronized void blockingOp() throws InterruptedException {
    while (!condition) wait();   // WHILE, not IF
    // do work
    notifyAll();                  // ALWAYS notifyAll
}

// volatile: simple flags (boolean closed, cancelRequested)
// AtomicLong: counters (incrementAndGet, get)
// synchronized: everything else

State Machine

synchronized boolean transition(long id) {
    Record r = map.get(id);
    if (r == null || r.state != EXPECTED) return false;
    r.state = NEW_STATE;
    return true;
}

Shutdown

closed = true; dispatcher.interrupt(); dispatcher.join();
pool.shutdown();
if (!pool.awaitTermination(5, TimeUnit.SECONDS)) pool.shutdownNow();

I/O

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        System.out.println(n);
    }
}
Gotchas: (1) No package. (2) while + wait, never if + wait. (3) Restore interrupt flag after catch.

HASKELL QUICK REFERENCE

Syntax

-- Function: name args = body
add :: Int -> Int -> Int
add x y = x + y

-- ADT
data Tree a = Leaf | Branch a (Tree a) (Tree a)

-- Pattern match
f Leaf = {- base -}
f (Branch v l r) = {- recursive -}

-- List comprehension
[x*x | x <- xs, even x]

-- Common: map, filter, foldl, words, read, show

MinHeap One-Liners

isEmpty Empty = True; isEmpty _ = False
findMin (Node v _ _) = v
insertHeap x h = merge (Node x Empty Empty) h
deleteMin (Node _ l r) = merge l r
evenHeap h = [x | x <- heapToList h, even x]
processHeap h = [x*x | x <- evenHeap h]

I/O

main :: IO ()
main = do
    line <- getLine
    let nums = map read (words line) :: [Int]
    print (sum nums)
Gotchas: (1) f x not f(x). (2) Ord a => for comparisons. (3) : is cons, ++ is concat.
CS 331 — Programming Languages Lab — IIT Guwahati
Good luck on April 8. You've got this.