f(X, 3) = f(hello, Y) unifies by binding X=hello and Y=3. Unlike assignment, unification is bidirectional and works on structures.member(X, [1,2,3]), Prolog first tries X=1. If subsequent goals fail, it backtracks and tries X=2, then X=3.\+ 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.= 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.\+ member(Next, Visited). This prevents revisiting nodes and creating infinite cycles in the graph.(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.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.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).cancelRequested inside synchronized markPrinting.closed = true (volatile). 2) Interrupt dispatcher. 3) Join dispatcher. 4) pool.shutdown(). 5) awaitTermination(5s). 6) If stuck, shutdownNow().synchronized for simple counters because no lock is needed.InterruptedException clears the interrupt flag. Restoring it lets outer code detect the interruption. Without this, the signal is silently lost.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.size Empty = 0 matches empty heaps; size (Node _ l r) = 1 + size l + size r matches nodes, binding subtrees.<, >, compare)." Functions like merge need it for comparing values. Functions like size don't compare, so they have no constraint.insertHeap creates a new heap rather than modifying the old one. This eliminates data races, simplifies reasoning, and enables referential transparency.take 5 [1..] works with an infinite list because only 5 elements are computed. Elegant but can cause space leaks.add 3 5 always equals 8. Java methods may return different values due to mutable state.add x y = x + y infers Num a => a -> a -> a. Prolog is dynamically typed; Java requires explicit declarations.map (*2) [1,2,3] applies (*2) to each element. All three languages support this: Haskell natively, Java via lambdas, Prolog via maplist/2.Ctrl+Alt+T, then code --no-sandbox for VSCode% 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: !
% 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).
:- 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.
= vs is vs =:=. (2) Bind vars BEFORE negation. (3) =< not <=.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
synchronized boolean transition(long id) { Record r = map.get(id); if (r == null || r.state != EXPECTED) return false; r.state = NEW_STATE; return true; }
closed = true; dispatcher.interrupt(); dispatcher.join(); pool.shutdown(); if (!pool.awaitTermination(5, TimeUnit.SECONDS)) pool.shutdownNow();
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); } }
package. (2) while + wait, never if + wait. (3) Restore interrupt flag after catch.-- 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
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]
main :: IO () main = do line <- getLine let nums = map read (words line) :: [Int] print (sum nums)
f x not f(x). (2) Ord a => for comparisons. (3) : is cons, ++ is concat.