
% swap the i'th and j'th elements of a list
swapIJ(Orig, I, J, Swapped) :-
   same_length(Orig,Swapped),            % original and final versions of the list must be same length
   append(BeforeI,[Ith|AfterI],Orig),    % use append to subdivide original into parts before/after i'th element
   append(BeforeI,[Jth|AfterI],JMoved),  % JMoved built from Orig's parts, but with j'th element substituted in i'th spot
   append(BeforeJ,[Jth|AfterJ],JMoved),  % use append to subdivide JMoved into parts before/after its j'th element
   append(BeforeJ,[Ith|AfterJ],Swapped), % final version built from JMoved, but with original i'th value substituted in j'th position
   length(BeforeI,I), length(BeforeJ,J). % require the two "before" parts are correct lengths so appends grab the right length substrings

% ------------- sample run, showing the values of the variables
%               as they change during the backtracking process   -------------------
%
%?- swapIJ([10,20,30,40], 1, 2, L). 
%
%After first append
%    BeforeI [], Ith 10, AfterI [20,30,40] 
%
%After second append
%    BeforeI [], Jth _G2097, AfterI [20,30,40], JMoved [_G2097,20,30,40] 
%
%After third append
%    BeforeJ [], Jth _G2097, AfterJ [20,30,40], JMoved [_G2097,20,30,40] 
%
%After last append
%    BeforeJ [], Ith 10, AfterJ [20,30,40], Swapped [10,20,30,40] 
%
%After third append
%    BeforeJ [20], Jth 20, AfterJ [30,40], JMoved [20,20,30,40] 
%
%After last append
%    BeforeJ [20], Ith 10, AfterJ [30,40], Swapped [20,10,30,40] 
%
%After third append
%    BeforeJ [30,20], Jth 30, AfterJ [40], JMoved [30,20,30,40] 
%
%After last append
%    BeforeJ [30,20], Ith 10, AfterJ [40], Swapped [30,20,10,40] 
%
%After third append
%    BeforeJ [40,20,30], Jth 40, AfterJ [], JMoved [40,20,30,40] 
%
%After last append
%    BeforeJ [40,20,30], Ith 10, AfterJ [], Swapped [40,20,30,10] 
%
%After first append
%    BeforeI [10], Ith 20, AfterI [30,40] 
%
%After second append
%    BeforeI [10], Jth _G2100, AfterI [30,40], JMoved [10,_G2100,30,40] 
%
%After third append
%    BeforeJ [], Jth 10, AfterJ [10,30,40], JMoved [10,10,30,40] 
%
%After last append
%    BeforeJ [], Ith 20, AfterJ [10,30,40], Swapped [20,10,30,40] 
%
%After third append
%    BeforeJ [10], Jth _G2100, AfterJ [30,40], JMoved [10,_G2100,30,40] 
%
%After last append
%    BeforeJ [10], Ith 20, AfterJ [30,40], Swapped [10,20,30,40] 
%
%After third append
%    BeforeJ [10,30], Jth 30, AfterJ [40], JMoved [10,30,30,40] 
%
%After last append
%    BeforeJ [10,30], Ith 20, AfterJ [40], Swapped [10,30,20,40] 
%
%L = [10, 30, 20, 40]

