Picat Pattern Matching Rules 5 — Questions and Answers
Question 1: In Picat, what is the difference between `==` and `=` when used in a rule body?
- `==` tests strict equality without binding; `=` performs unification which may bind variables (Correct answer)
- `==` performs unification; `=` tests equality without binding
- `==` is for arithmetic; `=` is for structural terms
- There is no difference between them
Correct answer: `==` tests strict equality without binding; `=` performs unification which may bind variables
`==` checks that two terms are identical without unifying them, while `=` attempts unification and may bind uninstantiated variables.
Question 2: A Picat rule written as `len([], Acc, Acc) => true.` is an example of what pattern technique?
- Using an accumulator argument that matches when the base case (empty list) is reached (Correct answer)
- Matching multiple return values simultaneously
- A guard that tests list emptiness
- An as-pattern binding the accumulator
Correct answer: Using an accumulator argument that matches when the base case (empty list) is reached
The pattern matches the empty list `[]` as the first argument and uses the same variable `Acc` twice to assert the accumulator equals the result at the base case.
Question 3: What does Picat do when a deterministic rule (`=>`) pattern matches but its body fails?
- It throws an error and does NOT try other clauses (Correct answer)
- It backtracks to try the next matching clause
- It silently succeeds
- It retries the same clause
Correct answer: It throws an error and does NOT try other clauses
Once a deterministic (`=>`) rule's head matches, Picat commits; body failure propagates as an exception rather than triggering backtracking.
Question 4: Which Picat pattern would match a struct term `point(X, Y)` only when both coordinates are integers?
- point(X, Y), integer(X), integer(Y) => ... (Correct answer)
- point(integer, integer) => ...
- point(X:int, Y:int) => ...
- point(int X, int Y) => ...
Correct answer: point(X, Y), integer(X), integer(Y) => ...
Picat uses guard conditions to further restrict matches; `integer(X)` and `integer(Y)` in the guard enforce the type constraint.
Question 5: In Picat, what is the outcome of `[1,2|T] = [1,2,3,4]`?
- T = [3,4] (Correct answer)
- T = [2,3,4]
- T = [3]
- Match fails
Correct answer: T = [3,4]
The pattern `[1,2|T]` matches a list starting with 1 and 2; T binds to the remaining tail `[3,4]`.
Question 6: When writing recursive list-processing predicates in Picat, which pair of clause heads handles both the base and recursive cases?
- One clause with `[]` and one with `[H|T]` (Correct answer)
- One clause with `[_]` and one with `[_,_]`
- One clause with `nil` and one with `cons(H,T)`
- One clause with `{}` and one with `{H|T}`
Correct answer: One clause with `[]` and one with `[H|T]`
The standard structural recursion pattern uses `[]` for the empty-list base case and `[H|T]` for the non-empty recursive case.
Question 7: In Picat, what does it mean for a pattern match to 'unify' with a compound term?
- The functor names and arities must match, and each corresponding argument must recursively unify (Correct answer)
- Only the functor name needs to match; arguments are ignored
- The terms must be bit-for-bit identical in memory
- The term must be an atom or integer only
Correct answer: The functor names and arities must match, and each corresponding argument must recursively unify
Unification of compound terms requires matching functor and arity, then recursively unifying each argument position pairwise.
In Picat, what is the difference between `==` and `=` when used in a rule body?