Flatten term Prolog

2020-05-08 17:50发布

问题:

I'm new in Prolog and I was trying to solve sucha problem so i wish if anybody could help.
I want to implement a ternary predicate flatten_term(Term, Function_symbol, Flattened_term) that succeeds if Flattened_term is obtained from Term by flattening out all nested occurrences of Function_symbol. It is assumed that Term contains no Prolog variables and no lists without checking the list.

?- flatten_term(f(f(x)), f, Flattened_term).
Flattened_term = f(x).

?- flatten_term(f(x), f, Flattened_term).
 Flattened_term = f(x).

 ?- flatten_term(a, f, Flattened_term).
Flattened_term = a.

?- flatten_term(g(f(x)), f, Flattened_term).
Flattened_term = g(f(x)).

?- flatten_term(g(f(f(x))), f, Flattened_term).
Flattened_term = g(f(x)).

回答1:

I'm using the code below in order to count the items in a term. Maybe this is similar to what you are looking for?

?- flatten_term(5+3*x=10,List).
List = [=, +, 5, *, 3, x, 10].

This is the source code:

flatten_term(Term,[Term]):-
    atomic(Term),!.
flatten_term(Term,Flat):-
    Term =.. TermList,
    flatten_term_list(TermList,Flat),!.

flatten_term_list([],[]):-!.
flatten_term_list([H|T],List):-
    flatten_term(H,HList),
    flatten_term_list(T,TList),
    append(HList,TList,List),!.


回答2:

As noted, you really should show an example of your work. But, here's a few hints for you to get you started:

  1. Flattening a list-of-lists like [a,[b,c],d,[e,[f,g,h]]] is just a simple recursive tree walk. There are several questions here on Stack Overflow that demonstrate how to do this, For instance, this question, How to implement flatten list in prolog ,with tail recursion?

  2. There are a number of predicates concerning type checking and the analysis, construction and decomposition of terms:

    • http://www.swi-prolog.org/pldoc/man?section=typetest
    • http://www.swi-prolog.org/pldoc/man?section=manipterm
  3. In particular, compound terms can be decomposed to a list using the univ operator =../2:

    foo(alpha,bravo,charlie) =.. L
    

    which yields L = [foo,alpha,bravo,charlie].

    One should also note that '=../2` is used to convert a list into a compound term:

    T =.. [foo,alpha,bravo,charlie]
    

    which yields, as one might expect T = foo(alpha,bravo,charlie).

Good luck!



标签: prolog