如何在SWI-Prolog中从事实生成姓名与国家的配对列表?
Hey there! Let's work through this Prolog problem together. You've got a set of person/3 facts storing each person's name, age, and country, and you want a predicate filter/1 that spits out a list of (Name, Country) pairs. Here's a straightforward solution:
Full Code Implementation
% Predefined person facts person(jessica,19,usa). person(james,18,uk). person(eric,34,italy). person(jake,24,france). % Predicate to generate name-country pairs filter(ResultList) :- findall( (Name, Country), person(Name, _, Country), ResultList ).
Breakdown of the Solution
The magic here comes from Prolog's built-in findall/3 predicate—it's perfect for collecting all matching results into a list. Let's break down each part:
- First argument of
findall/3:(Name, Country)is the structure we want to collect for each matching person. This creates a tuple pairing the name and country. - Second argument:
person(Name, _, Country)is our query. The_is an anonymous variable—we use it to ignore the age value since we don't need it in our final list. - Third argument:
ResultListis the variable that will hold the final list of pairs once the query completes.
Example Usage & Output
When you run this in your Prolog interpreter:
?- filter(L).
You'll get exactly the result you're looking for:
L = [(jessica, usa), (james, uk), (eric, italy), (jake, france)]
Bonus: Extending the Predicate
If you ever need to filter for specific conditions (like only adults), you can easily modify the query inside findall/3. For example:
% Filter only people over 20 filter_adults(ResultList) :- findall( (Name, Country), (person(Name, Age, Country), Age > 20), ResultList ).
Calling filter_adults(L) would return L = [(eric, italy), (jake, france)].
内容的提问来源于stack exchange,提问作者Angelrina

