Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

list length, inserting element

Tags:

list

prolog

I'm trying to write a program in Prolog, which will insert an element into a certain position, so e.g.

?- ins(a, [1,2,3,4,5], 3, X).
X = [1,2,a,3,4,5].

I have the following code:

ins(X,[H|T],P,OUT) :-
   length([T3],P),
   concatenate(X,[H],T),
   ins(...). 

The problem is that it is inserting element X in given index from back (I even know where the problem is -> the length([T3],P) which is obviously the length of the list from back not from head) . I was trying to remember how much elements did I cut off and insert X when "number of cut off elements" = P, but I can't really write that in Prolog. Any ideas?

like image 293
Johnzzz Avatar asked Feb 20 '23 21:02

Johnzzz


2 Answers

% ins(Val,List,Pos,Res)

ins(Val,[H|List],Pos,[H|Res]):- Pos > 1, !, 
                                Pos1 is Pos - 1, ins(Val,List,Pos1,Res). 
ins(Val, List, 1, [Val|List]).

The predicate fails if Pos = 0 or Pos > length(List) + 1

like image 77
Alexander Serebrenik Avatar answered Feb 27 '23 09:02

Alexander Serebrenik


Let's state what you want here. For example you could say: "I want to split my input List after Position - 1 elements so that I can insert a new element there".

A direct traduction with append/3 (DCG would be better btw):

ins(Element, List, Position, Result) :-
    PrefixLength is Position - 1,
    length(Prefix, PrefixLength),
    append(Prefix, Suffix, List),
    append(Prefix, [Element], Temp),
    append(Temp, Suffix, Result).

Or you could say: "I want to go through the elements of my List Position - 1 times without touching anything and then insert Element and then not touch anything again".

This time the direct traduction would be:

ins2(Element, List, 1, [Element|List]).
ins2(Element, [Head|Tail], Position, [Head|Result]) :-
    Position > 1,
    NewPosition is Position - 1,
    ins2(Element, Tail, NewPosition, Result).

you could too state that: "My input List is a list equal to my Result one except it hasn't my Element as Positionth element." and realize that if you use swi-prolog, a predicate solves this instantly:

ins3(Element, List, Position, Result) :-
    nth1(Position, Result, Element, List).

Bottom line is: state what the problem is clearly and the solution should appear in simple terms.

like image 29
m09 Avatar answered Feb 27 '23 09:02

m09