Prologue: how to extract lists from a complex term

I was tasked with extending the existing Prolog code, and I ran into a problem with the structure of a complex term. This tricky term is being passed as a parameter to a Prolog predicate I'm writing. The problem is that I need to extract two lists from this complex term and the structure of the term is unknown in expanded or fixed form.

Specifically, let's say I have the term "Param" like this:

lam(_G23075,
   drs([_G23084], [eq(_G23084, person), ant(_G23084, mask, sg)])+_G23075*_G23084)

      

The drs term above has two lists that I would like to extract.

If the Param parameter only had a drs member, I could do this:

drs(L1, L2) = Param.

      

And then L1 and L2 will contain lists. How would this work with the complex terminology structure above?

Greetings,

Martin

+3


source to share


2 answers


You can deconstruct the term for example. with =..

:

The following predicate extract_drs(+Term,-L1,-L2)

returns two occurrences of lists. It can have multiple solutions if there are multiple occurrences of the same term.



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       

      

+3


source


I would write

extract_drs(Term,L1,L2) :-
  compound(Term), (Term = drs(L1,L2) ; arg(_,Term,Arg), extract_drs(Arg,L1,L2)).

      



edit as pointed out by danielp is a SWI_prolog extension that allows arg / 3 with the first unbound argument. Then it should be replaced with

extract_drs(Term,L1,L2) :-
  compound(Term), (Term = drs(L1,L2) ; Term =.. [_|Args], member(Arg,Args), extract_drs(Arg,L1,L2)).

      

+1


source







All Articles