Question

So I'm trying to get rid of the wrapper clause by using the sort library predicate directly inside split. What split does is just generating a list of numbers from a list that looks like this: [1:2,3:2,4:6] ---split--> [1,2,3,2,4,6]. But the generated list contains duplicates, and I don't want that, so I'm using the wrapper to combine split and sort, which then generates the desired result: [1,2,3,4,6].

I'd really like to get rid of the wrapper and just use sort within split, however I keep getting "ERROR: sort/2: Arguments are not sufficiently instantiated." Any ideas? Thanks :)

split([],[]).
split([H1:H2|T],[H1,H2|NT]) :-
    split(T,NT).

wrapper(L,Processed) :- 
    split(L,L2),
    sort(L2,Processed).
Was it helpful?

Solution

I'd really like to get rid of the wrapper and just use sort within split

Then use findall with a complex goal such as

split(Edges, NodeSet) :-
    findall(Node,
            (member(Edge, Edges), (Edge = (Node:_); Edge = (_:Node))),
            NodeList),
    sort(NodeList, NodeSet).

However, once you start using aggregating predicates, you could just as well skip the sort and use setof:

split(Edges, NodeSet) :-
    setof(Node, Edge^Pair^(member(Edge, Edges),
                           Edge =.. [:|Pair],
                           member(Node,Pair)),
          NodeSet).

Read as: get the set of all Node s.t. there exists Edge and there exists Pair s.t. (etc.) and call that NodeSet.

The =.. ("univ") operator deconstructs a pair: Edge =.. [:, Left, Right]. For better readability, you can write a separate predicate to get nodes from edges:

% endpoint(Edge, Node) is true iff Node is an endpoint of Edge
endpoint(Node:_, Node).
endpoint(_:Node, Node).

split(Edges, NodeSet) :-
    setof(Node, Edge^(member(Edge, Edges), endpoint(Edge, Node)), NodeSet).

EDIT Before you try this approach, see the discussion below this answer for whether or not this is a better idea than the OP's original code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top