title: Predicate to match list (all possibilities) with no duplicate integers, have length N, and be within a domain of 1 to N
body: <p><strong>This is for GNU-Prolog</strong></p>
  
  <p>I'm having trouble getting a certain predicate to work. Its functionality is that it matches a list of integers
  that have a domain of 1 to <code>N</code> with no duplicates and length <code>N</code>.  Basically what I want to do is have this as inputs and outputs:</p>
  
  <pre><code>| ?- row_valid(X, 3).
  
  X = [1, 2, 3] ? ;
  X = [1, 3, 2] ? ;
  X = [2, 1, 3] ? ;
  X = [2, 3, 1] ? ;
  X = [3, 1, 2] ? ;
  X = [3, 2, 1] ? ;
  
  no
  
  | ?- row_valid(X, 2).
  
  X = [1, 2] ? ;
  X = [2, 1] ? ;
  
  no
  
  | ?- row_valid(X, 1).
  
  X = [1] ? ;
  
  no
  </code></pre>
  
  <p>But right now, this is what is happening:</p>
  
  <pre><code>| ?- row_valid(X, 3).
  
  X = [] ? ;
  
  no
  </code></pre>
  
  <p>This is probably happening because of the <code>row_valid([], _).</code> predicate I have in the code. However, I can verify that the predicate matches correctly since:</p>
  
  <pre><code>| ?- row_valid([1,2,3], 3).
  
  true ?
  
  yes
  </code></pre>
  
  <p>Here are the predicates defined. Do you have any suggestions on how I could get this to work the way I want? Thanks for your time.</p>
  
  <pre><code>% row_valid/2: matches if list of integers has domain of 1 to N and is not duplicated
  % 1 - list of integers
  % 2 - N
  row_valid([], _).
  row_valid(Row, N) :-
      length(Row, N),                % length
      no_duplicates_within_domain(Row, 1, N),
      row_valid(RestRow, N).
  
  % no_duplicates/1: matches if list doesn't have repeat elements
  % 1 - list
  no_duplicates([]).        % for empty list always true
  no_duplicates([Element | RestElements]) :-
      \+ member(Element, RestElements),        % this element cannot be repeated in the list
      no_duplicates(RestElements).
  
  % within_domain/3 : matches if list integers are within a domain
  % 1 - list
  % 2 - min
  % 3 - max
  within_domain(Integers, Min, Max) :-
      max_list(Integers, Max),
      min_list(Integers, Min).
  
  % no_duplicates_within_domain/3: matches if list integers are within a domain and isn't repeated
  % 1 - list
  % 2 - min
  % 3 - max
  no_duplicates_within_domain(Integers, Min, Max) :-
      no_duplicates(Integers),
      within_domain(Integers, Min, Max). 
  </code></pre>