Prolog中rewrite/2谓词及rewrite('A', ['X', 'Y', 'Z'])功能与用法问询
rewrite/2 Predicate First off, let's get one key point straight: rewrite/2 isn't a built-in predicate in standard Prolog. It's almost always a user-defined predicate that you implement to handle some form of term rewriting, substitution, or expansion. Its core purpose is to take a term (the first argument) and replace or expand it into another term (the second argument)—but exactly how it does that depends entirely on the rules you define for it.
What does rewrite('A', ['X', 'Y', 'Z']) do?
Let's break down this specific call clearly:
- At its core, this predicate either:
- Defines a rule: "The atom
'A'should be rewritten to the list['X', 'Y', 'Z']", or - Acts as a query: "Does there exist a rule that rewrites
'A'to['X', 'Y', 'Z']? If so, what are the bindings?"
- Defines a rule: "The atom
Its role, use cases, and functionality
- Role: It establishes a direct mapping between a single atomic symbol (
'A') and a list of symbols (['X','Y','Z']). This is a simple form of expansion—taking a single entity and replacing it with a collection. - Common use cases:
- Symbol expansion in parsers/lexers: For example, expanding a non-terminal symbol in a context-free grammar into its production rules.
- Rule-based systems: Unpacking a single fact or rule into multiple sub-facts (e.g., "
Arepresents the set ofX,Y,Z"). - Template generation: Replacing a placeholder (
'A') with a predefined list of values.
- Functionality: When defined as a fact, it provides a static lookup. When used as a query, it can verify the mapping or retrieve the list associated with
'A'(if you use a variable for the second argument).
Example Prolog Program
Let's walk through concrete implementations to see this in action.
Basic Static Rewrite Rules
This example defines simple one-to-one mappings between atoms and lists, plus a helper to rewrite entire lists:
% Define core rewrite rules: map single atoms to lists of atoms rewrite('A', ['X', 'Y', 'Z']). rewrite('B', ['P', 'Q']). rewrite('C', ['R']). % Helper predicate: rewrite every element in a list (keep elements with no rule) rewrite_list([], []). rewrite_list([Term|Rest], [Rewritten|RestRewritten]) :- rewrite(Term, Rewritten), rewrite_list(Rest, RestRewritten). rewrite_list([Term|Rest], [Term|RestRewritten]) :- \+ rewrite(Term, _), % If no rule exists, leave the term unchanged rewrite_list(Rest, RestRewritten).
Example Queries & Outputs
Try these queries in a Prolog interpreter to see how it works:
% 1. Verify that 'A' rewrites to the specified list ?- rewrite('A', ['X', 'Y', 'Z']). true. % 2. Retrieve what 'A' rewrites to (use a variable for the second argument) ?- rewrite('A', Result). Result = ['X', 'Y', 'Z']. % 3. Rewrite a mixed list (some elements have rules, some don't) ?- rewrite_list(['A', 'B', 'D', 'C'], Output). Output = [['X', 'Y', 'Z'], ['P', 'Q'], 'D', ['R']] ; false.
More Flexible Rewrite Rules
You can also make rewrite/2 handle structured terms with variables for more dynamic use cases:
% Rewrite arithmetic terms into infix notation lists rewrite(multiply(A, B), [A, '*', B]). rewrite(add(A, B), [A, '+', B]). % Query this dynamic rule ?- rewrite(multiply(3, 5), Result). Result = [3, '*', 5].
内容的提问来源于stack exchange,提问作者otalpster

