FrankTan
FrankTan

Reputation: 1686

prolog list of pairs

I have an input of a list of pairs:

[[abs_(p,X,Y,Z),abs_(f,X,Y,Z)],[abs_(p,X,Y,Z),abs_(l,Z,P)]]

I want check if a pair have the same number of arguments, in this case yes:

[abs_(p,X,Y,Z),abs_(f,X,Y,Z)]

In the second case the answer is no.

This is just an example because more generally, I want to know which pair have the same number of arguments. The output for the input should be:

[[abs_(p,X,Y,Z),abs_(f,X,Y,Z)]

What do I have to do?

Upvotes: 1

Views: 4073

Answers (3)

Gökhan Uras
Gökhan Uras

Reputation: 181

run( [], Tail) :- Tail=[].
run( [ [First,Second] | Tail ], Output ) :- First =.. List1, Second =.. List2, 
length(List1,N1), length(List2, N2), N2 is N1, !, run(Tail, Tail2), 
append( [ [First | [Second]] ], Tail2, Output ). 
run( [H|T], Output ) :- run(T, Output).

First rule is base case. Second rule checks the number of arguments in first pair if its same run the recursive call and append the output from recursive call with and this pair to Output. Because of cut if N2 equals N1 it doesn't call third rule. And third rule discard the unmatched pair and call itself with tail of the list. Hope it helps.

Upvotes: 1

prusswan
prusswan

Reputation: 7091

You can also use pattern matching to break each pair into terms, and use the functor predicate to check the arity of those terms.

Upvotes: -1

hardmath
hardmath

Reputation: 8823

Prolog provides a strange infix operator =.. called "univ" which converts between compound terms and a list that begins with the functor followed by the arguments to that functor.

Hence a Prolog query something like this:

?- abs_(p,X,Y,Z) =.. L.
L = [abs_,p,X,Y,Z]
yes

So I would use length/2 on the lists produced by the "univ" operator to check that two compound terms have an equal number of arguments.

Upvotes: 1

Related Questions