SWI-Prolog: Looking for some predicate which reduces a set in some generator set for some invariant predicate?

58 Views Asked by At

I am looking some predicate say generator1_inv which is able to convert invariant generator parameter +Inv (with Inv(a) = a) and some list +ListIn of form [...ai ... Inv(bi)] into some list +ListOut which has distinct members respect to +Inv and if a and Inv(b)=a are members of +ListIn, then Inv(Inv(...(a)) (not a) is a member of +ListOut, where Inv occurs +Order times.

Here some examples what generator1_inv(+ListIn, -ListOut, +Inv, +Order) should do:

Example 1)

?- generator1_inv([k(a), a, k(k(a)), v, b ], ListOut, k, 1)
ListOut = [k(a), v, b]

Example 2)

?- generator1_inv([k(a), r(a), a, k(k(a)), v, b ], ListOut, k, 1)
ListOut = [k(a), r(a), v, b

]

Example 3)

?- generator1_inv([r(a), a, r(abc), d(a), k(k(a)), v, b ], ListOut, k, 1)
ListOut = [r(a), k(a), r(abc), d(a) v, b]

Example 4)

?- generator1_inv([r(a), a, r(abc), d(a), k(k(a)), v, b ], ListOut, k, 0)
ListOut = [r(a), a, r(abc), d(a) v, b]
1

There are 1 best solutions below

0
Martin Kunze On BEST ANSWER

Found some solution based on this predicate calc_power:

generator_inv(ListIn, ListOut, Inv, Order) :-
    findall(X, ( member(Y, ListIn),  
                 member(Z, ListIn), 
                 not(Y = Z), 
                 calc_power(Y, X , Inv, _),
                 calc_power(Z, X , Inv, _),
                 not(calc_power(X, _, Inv, 1))), Roots),
    findall(X, (member(Y, Roots),
                member(X, ListIn),
                calc_power(X, Y , Inv, _)), ListSub),
    findall(X, (member(Y, Roots),
                calc_power(X, Y , Inv, Order)), List1),
    subtract(ListIn, ListSub, ListBase),
    union(ListBase, List1, ListOutD),
    sort(ListOutD, ListOut).