0

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)).
lurker
  • 56,987
  • 9
  • 69
  • 103
Chis
  • 131
  • 10
  • 2
    It's expected on stackoverflow.com that you make some attempt at solving your problem, and ask a specific question about where you get stuck, showing what you've tried. Also, you need to think about and describe the conditions of the problem. Are the terms in question always single arity (only one argument, like `f(f(g(f(a)))`)? Or might they look like `f(f(b),g(f(f(a)))`? If they're single arity, you can solve your problem using a simple recursive approach. You might need to use a [term processing predicate](http://www.gprolog.org/manual/gprolog.html#sec81). – lurker Jan 17 '15 at 14:05
  • 3
    This is not the best problem for beginners, you would need to decompose function symbols. While that is possible, I very much doubt that you will learn a lot by this. Also, it is not clear what `f` means. One argument? Two arguments? Any number? In any case, this is not a good start. – false Jan 17 '15 at 21:58

2 Answers2

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),!.
fraber
  • 1,204
  • 1
  • 8
  • 21
0

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:

  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!

Community
  • 1
  • 1
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135