HR1
HR1

Reputation: 527

Dealing with Unbound variables & lists

Let's say I have the following 3x3 Grid of unbound variables & another list L of bound variables. I want to link both. For example.

Grid A:

[[_6308, _6314, _6308], [_6308, _6308, _6314], [_6314, _6308, _6308]]

List B:

[1 , 2 , 3]

I want to choose in order from left to right the variables and bound them to the unbound ones. in this case the 3 will be ignored cause I only have 2 unbound variables.

Result list should be:

[[1,2,1],[1,1,2],[2,1,1]]



?- fill([1,2,3],[[_6308, _6314, _6308], [_6308, _6308, _6314], [_6314, _6308, _6308]]).
[[2, 1, 2], [2, 2, 1], [1, 2, 2]]

Any idea how I can implement that? I tried this idea, but it's in complete as it only returns 1 for all elements.

fill(_,[])  .   
fill(L,[H|T]):- 
    helper(L,H),
    fill(L,T).
helper(_,[]).       
helper(L,[H|T]) :-
    member(H,L),
    helper(L,T).

Upvotes: 3

Views: 681

Answers (2)

lambda.xy.x
lambda.xy.x

Reputation: 4998

You can use term_variables/2 to find a list of variables in your term and claim it is a prefix of your term list:

prefix_of([],_).
prefix_of([X|Xs],[X|Ys]) :-
    prefix_of(Xs,Ys).

grid_pool(Grid,Pool) :-
    term_variables(Grid,Vs),
    prefix_of(Vs,Pool).

For your example you get:

?- G = [[A, B, A], [A, A, B], [B, A, A]], grid_pool(G, [1,2,3,4]).
G = [[1, 2, 1], [1, 1, 2], [2, 1, 1]],
A = 1,
B = 2.

The order of variables in Vs is the order of the term traversal: depth-first and left-to right.

Upvotes: 3

Paulo Moura
Paulo Moura

Reputation: 18663

How exactly you bound the variables with the values? For example, with the following rewrite of your code I'm unifying variables with the values chosen also left-to-right:

fill(Values, Variables) :-
    % invert argument order to take advantage
    % of first-argument indexing
    fill_variables(Variables, Values).

fill_variables([], _).
fill_variables([List| Lists], Values) :-
    helper(List, Values),
    fill_variables(Lists, Values).

helper([], _).       
helper([Variable| Variables], [Value| Values]) :-
    (   var(Variable) ->
        % unbound variable; unify with the next value
        Variable = Value,
        helper(Variables, Values)
    ;   % already bound variable
        helper(Variables, [Value| Values])
    ).

We get:

| ?- L = [[A, B, A], [A, A, B], [B, A, A]], fill([1,2,3], L).

A = 1
B = 2
L = [[1,2,1],[1,1,2],[2,1,1]]
yes

Upvotes: 1

Related Questions