Reputation: 1884
I am tasked with extending some existing Prolog code and I have run into an issue with the structure of a complex term. This complex term is passed as a parameter to a Prolog predicate that I am writing. Problem is that I need to extract two lists from this complex term and the structure of the term is not known in advanced or fixed.
Specifically, let's say I have a term "Param" like this:
lam(_G23075,
drs([_G23084], [eq(_G23084, person), ant(_G23084, mask, sg)])+_G23075*_G23084)
The drs term above has the two lists that I would like to extract.
If Param had the drs term only, I could do this:
drs(L1, L2) = Param.
And then L1 and L2 would contain the lists. How could this work with the complex term structure given above?
Cheers,
Martin
Upvotes: 3
Views: 1072
Reputation: 60004
I would write
extract_drs(Term,L1,L2) :-
compound(Term), (Term = drs(L1,L2) ; arg(_,Term,Arg), extract_drs(Arg,L1,L2)).
edit as noted by danielp, it's a SWI_prolog extension that allows to use arg/3 with first argument unbound. Then should be replaced by
extract_drs(Term,L1,L2) :-
compound(Term), (Term = drs(L1,L2) ; Term =.. [_|Args], member(Arg,Args), extract_drs(Arg,L1,L2)).
Upvotes: 1
Reputation: 1187
You can deconstruct the term e.g. with =..
:
The following predicate extract_drs(+Term,-L1,-L2)
returns the two occurring lists. It may have multiple solutions if there are multiple occurrences of matching terms.
extract_drs(drs(L1,L2),R1,R2) :- !,R1=L1,R2=L2. % the cut avoids that L1 or L2 are inspected
extract_drs(Term,L1,L2) :-
compound(Term), % check if it is a compound term and not a number, variable, etc.
Term =.. [_Functor|Args], % get the arguments of Term
member(Arg,Args), % choose one argument
extract_drs(Arg,L1,L2). % and try to extract there the drs term
Upvotes: 3