Picat Pattern Matching Rules Questions and Answers — Questions and Answers
Question 1: A developer defines a predicate to verify if the two elements of a pair structure are identical. Which rule head correctly implements this check using only pattern matching?
- check_equal($p(X, Y)) => X == Y.
- check_equal($p(X, X)) => true. (Correct answer)
- check_equal($p(X, Y)) => X = Y.
- check_equal($p(X, Y), X == Y).
Correct answer: check_equal($p(X, X)) => true.
Picat supports non-linear patterns in rule heads. When a variable (in this case, `X`) appears more than once, it constrains the pattern to only match goals where the corresponding terms are identical. This enforces the equality check directly during the matching process without needing any code in the rule body.
Question 2: What is the primary purpose of the `@` operator (as-pattern) in a Picat rule head?
- To perform a type check on the matched term.
- To indicate a pointer or reference to a memory location.
- To create an alias for a complex pattern, binding the entire structure to a single variable while also deconstructing it. (Correct answer)
- To suppress unification and force a strict structural match.
Correct answer: To create an alias for a complex pattern, binding the entire structure to a single variable while also deconstructing it.
The `Var@Pattern` syntax, known as an as-pattern, is used to match a term against `Pattern` while simultaneously binding the entire, original term to the variable `Var`. This is highly useful for accessing both the whole structure and its individual parts within the rule's body.
Question 3: Consider the following Picat code. What is the output of the query `go`? ```picat go => classify(item(10, "food"), C), println(C). classify(item(Val, _), high) => Val > 20. classify(item(Val, _), medium) => Val > 5. classify(item(_, _), low). ```
- high
- low
- An error occurs.
- medium (Correct answer)
Correct answer: medium
The goal `classify(item(10, "food"), C)` first matches the head of the first rule, binding `Val` to 10. The guard `Val > 20` (10 > 20) is then evaluated, which fails. Picat backtracks and tries the second rule. The head matches again, binding `Val` to 10. The guard `Val > 5` (10 > 5) succeeds. `C` is then bound to `medium`, and the predicate call succeeds, printing 'medium'.
Question 4: Which of the following is an INVALID rule head for a Picat predicate?
- sum_list([H|T], H + sum_list(T)) => ... (Correct answer)
- process(ID, $record(Name, Age@val(V))) => ...
- find_pair([X, X | _]) => ...
- handle_default(Data) => ...
Correct answer: sum_list([H|T], H + sum_list(T)) => ...
Rule heads in Picat are for pattern matching, not for evaluation of expressions. The term `H + sum_list(T)` contains an arithmetic operation and a recursive call. Such computations are not valid patterns and must be placed in the rule's body or, for functions, after the `=` symbol.
Question 5: A programmer wants to handle lists, with a special case for lists starting with the atom 'a'. What is the result of the query `handle_list([a,b,c], Res)` with the following predicate definitions? ```picat handle_list(L, general) => length(L) > 0. handle_list([a|_], specific_a). handle_list([], empty). ```
- specific_a
- general (Correct answer)
- An error due to ambiguity.
- The query fails.
Correct answer: general
Picat attempts to match predicate rules from top to bottom. The goal `handle_list([a,b,c], Res)` first attempts to match `handle_list(L, general)`. This match succeeds, binding `L` to `[a,b,c]`. The guard `length(L) > 0` is then checked and succeeds. `Res` is bound to `general` and the call succeeds immediately. The second, more specific rule is never tried because a successful match was already found.
Question 6: In Picat, what is the outcome when a predicate is called with arguments that do not match the pattern of any of its defined rules?
- The program halts with an instantiation error.
- The call implicitly returns a `fail` atom.
- The call simply fails, and execution backtracks. (Correct answer)
- A syntax error is reported at compile time.
Correct answer: The call simply fails, and execution backtracks.
If a goal is called and Picat cannot find any rule (or fact) whose head matches the goal's arguments, the call fails. This is a fundamental concept of logic programming. Execution will then backtrack to the most recent choice point to try an alternative path. If no alternatives exist, the top-level query will fail.
A developer defines a predicate to verify if the two elements of a pair structure are identical.
Which rule head correctly implements this check using only pattern matching?