2

I have 2 lists with random number of elemets. Eg A=[1,2,4,5] and B=[1,2,3]. Result should be 2. Code that I tried:

domains
Numbers1 = integer*
Numbers2 = integer*
int_list=integer*

predicates
nondeterm prinadl(integer, int_list)

clauses
   //here going the code that read number that I've entered, and according to entered numer,programm should do something
 answer(T):- T=5, 
    P = 0,
    write ("Enter the 1st list"), readterm (int_list, L),
    write ("Enter the 2nd list"), readterm (int_list, L2),
    L2 = [H|V], prinadl(H, L), P1 = P + 1,
    write(L2, P1, V).

 prinadl (X, L):- L=[X|_], !.
 prinadl (X, L):- L=[_|T], prinadl (X, T).

I'm totally new with prolog. Can you please say me where I'm wrong? All I need is to get number of matches printed to the console. Thanks in advance.

Satevg
  • 1,601
  • 2
  • 16
  • 23
  • seems mostly random code... what's the logic your're following ? should be easy as visiting both lists and adding 1 to a result when both elements match – CapelliC Dec 25 '14 at 19:53
  • @CapelliC Yes, it almost random, I copied parts from different examples. Not sure how should I orginize 2 nested 'foreach's I mean: how can I pick the first element from the first list and check all elements in L2, then pick up the second element of L and check thorugh L2 – Satevg Dec 25 '14 at 20:02
  • Handle visiting *both* lists with a single recursive predicate, you should add a counter that gets incremented when both lists have the same head. Don't forget that the visit will stop when one of the lists gets empty. There you can 'initialize' the counter to 0. – CapelliC Dec 25 '14 at 20:07
  • You don't say what the error is. There are a lot of empty spaces between predicate names and argument lists, for example `write (...`. Does the code even compile? –  Dec 25 '14 at 20:24
  • Why don't you start with test cases? – false Dec 25 '14 at 20:38
  • 1
    What's the result for A=[1,1] and B=[1]? For A=[1,2], B=[2,1]? – Sergii Dymchenko Dec 28 '14 at 07:05
  • 1
    It looks like you are trying to use Turbo Prolog or Visual Prolog. Are you required to use this? Can you use "more real" Prolog, like SWI, for example? – Sergii Dymchenko Dec 28 '14 at 07:06

1 Answers1

2

This answer is based on two things: first, guesswork. second, if_/3 by @false.

Let's define the count_left_while2/4.

count_left_while2(P_2,Xs,Ys,N) counts the number N of corresponding list items in Xs and Ys fulfilling P_2. Proceeding from left to right, count_left_while2 stops at the first two items not satisfying P_2. It also stops when one list is empty, but the other one is not.

:- use_module(library(clpfd)).

:- meta_predicate count_left_while2(2,?,?,?).
count_left_while2(P_2,Xs,Ys,N) :-
    N #>= 0,
    list_list_countleft_while(Xs,Ys,N,P_2).

nil_or_cons([]).
nil_or_cons([_|_]).

:- meta_predicate list_list_countleft_while(?,?,?,2).
list_list_countleft_while([],Xs,0,_) :-
    nil_or_cons(Xs).
list_list_countleft_while([X|Xs],Ys,N,P_2) :-
    list_list_prev_countleft_while(Ys,Xs,X,N,P_2).

:- meta_predicate list_list_prev_countleft_while(?,?,?,?,2).
list_list_prev_countleft_while([],_,_,0,_).
list_list_prev_countleft_while([Y|Ys],Xs,X,N,P_2) :-
    if_(call(P_2,X,Y),
        ( N0 #>= 0, N #= N0+1, list_list_countleft_while(Xs,Ys,N0,P_2) ),
        N = 0).

Let's use it in combination with reified term equality predicate (=)/3, like this:

:- count_left_while2(=,[1,2,4,5],[1,2,3],N).
N = 2.
Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166