PROBLEM 1 a) program main() var A, B, C: integer; // binding occurrences; let's call them main.A, main.B, main.C procedure p1() var X: integer; // binding occurrence; let's call it p1.X begin X:=A; // applied occurrences of X and A to p1.X and main.A, respectively A:=B; // applied occurrences of A and B to main.A and main.B, respectively B:=C; // applied occurrences of B and C to main.B and main.C, respectively C:=X; // applied occurrences of C and X to main.C and p1.X, respectively end; procedure p2() var B: integer; // binding occurrence; let's call it p2.B begin B:= A; // applied occurrences of X and A to p2.B and main.A, respectively p1(); end; b) static scoping output: 3, 1, 2 c) dynamic scoping output: 2, 3, 2 d) by using fully qualified expression, i.e., the "path prefix" leading to the corresponding binding occurrence, e.g., main.B vs. p2.B, or by some other renaming mechanism which produces unique names. PROBLEM 2 a) before swap() in main: i = 2, a[2] = 30; after swap() in main: i = 30, a[2] = 2; explanation: when the procedure is called, the REFERENCES to i and a[2] are passed in the ACTIVATION RECORD on the RUNTIME STACK. Hence, afterwards i will be 30 and a[2] will be 2. b) body of swap becomes: begin tmp := i; ( tmp = 2) i := a[i], ( i = 30) a[i] := tmp; ( a[30] = 2 <== ATTEMPTED, ... but leads to an ACCESS VIOLATION...) ...since we are attempting to access past end of array. Hence a runtime error will be reported in languages that check the array boundaries (e.g., IndexOutOfBounds). If they are not checked say when using C/C++ (often compilers allow to turn range checking at runtime on or off!), then we may get a "segmentation fault", "memory violation" because we may access memory that is "not ours", or we may read a memory location that happens to be accessible -- but we still access memory that has not been declared a part of the array!