Pattern Matching Rules Flashcards
6 cards from real Picat practice questions. Tap to flip, then mark Knew It or Still Learning โ missed cards come back until you master them.
Read the first 6 Pattern Matching Rules flashcards as text
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?
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.
What is the primary purpose of the `@` operator (as-pattern) in a Picat rule head?
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.
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). ```
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'.
Which of the following is an INVALID rule head for a Picat predicate?
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.
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). ```
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.
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?
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.