Words with repeating symbols in prolog v5.2

142 views Asked by At

I need to write prolog predicate that reads file and creates a list of words with repeating symbols. For example from text:

A dog and an apple and a pipe.

the result should be:

['apple', 'pipe']

I wrote this:

domains
file_ = f
s=string
c=char
i=integer
list=s*
list1=c*
 
predicates
str_a_list(s,list)
readfile(s,s)
example(s)
write_symbols(list1)
search(list1,list1,list1)
check(list)
str_list(s,list1)
search1(list1,c,i,i)
 
 
clauses
readfile(S,N):-existfile(N),!,
openread(F,N),  
readdevice(F),file_str(N,S).
 
str_a_list("",_):-!. 
str_a_list(" ",_):-!. 
str_a_list(S,[H|T]):-fronttoken(S,H,S1),
str_a_list(S1,T). 
        
search1([],_,I,I):-!.
search1([H|T],H,I,M):-I1=I+1,search1(T,H,I1,M).
search1([H|T],X,I,M):-H<>X,search1(T,X,I,M).
 
search([],_,_):-!.
search([H|T1],L,L0):-search1(L,H,0,M),M>=2,write_symbols(L0).
search([_|T],L,L0):-search(T,L,L0).
 
write_symbols([]):-write(" "),!.
write_symbols([H|T]):-write(H),write_symbols(T).
 
str_list("",[]).
str_list(S,[H|T]):- frontchar(S,H,S1),str_list(S1,T). 
 
check([]):-!.
check([H|T]):-str_list(H,L),search(L,L,L),check(T).
 
example(Y):-readfile(S,Y),str_a_list(S,L),check(L).
    
goal
write("Enter file name: "),
readln(Y),example(Y).

It's giving me this error:

This flow pattern doesn't exist openread(o,i)

on line:

openread(F,N)

1

There are 1 answers

2
Reema Q Khan On

I tried computing this prolog task, maybe you may find something useful in my solution that may help you with yours. I've written my code using basic prolog:

First: The first predicate separates the sentence into words. I have used the built-in function split_string.Example: "The dog" will become "The","dog".

g(B):-
    split_string(B,' ','', L),
    d(L).

Second: In the second predicate, we split each word into a separate list of characters. Example: "dog" will become ["d","o","g"].

stringsplit(A,L1):-
   atom_chars(A, L1).

Third: Then check each list if it contains doubles. the base case predicate tell to stop when get empty brackets. The checkdouble second predicate checks if a character is in the remaining list (using member). If yes then load the character in List R. Else, don't load the character in R.

    checkdouble([],[]):-!.
    checkdouble([H|T],[H|R]):-
    member(H,T),
    checkdouble(T,R).

    checkdouble([],[]).
    checkdouble([H|T],List):-
    \+member(H,T),
    checkdouble(T,List).

Fourth: By this point you will have a number of list: empty and those containing duplicates from each word. Example: For [bat] [apple] [polo] we will get [][p][o]. So now we use a predicate that simply prints the list of words that have doubles ignoring those words with no doubles i.e [].

s(_,B):-
    B=[].
s(D,B):-
    B\=[],
   write(D). 
 

Finally: Putting the code together:

g(B):-
    split_string(B,' ','', L),
    d(L).

d([]).
d([H|T]):-
    stringsplit(H,K),
    checkdouble(K,R),
    s([H],R),
    d(T).
    

s(_,B):-
    B=[].
s(D,B):-
    B\=[],
   write(D). 
    


 checkdouble([],[]):-!.
 checkdouble([H|T],[H|R]):-
 member(H,T),
 checkdouble(T,R).

 checkdouble([],[]).
 checkdouble([H|T],List):-
 \+member(H,T),
 checkdouble(T,List).
                
                
 stringsplit(A,L1):-
 atom_chars(A, L1).

Example:

?-g("A dog and an apple and a pipe").
OUTPUT:    
[apple][pipe]
1true
false

?-g("Two funny little red apples fell from a tree one day").
OUTPUT:
[funny][little][apples][fell][tree]
1true
false

?-g("On a hill upon the grass there sits a squirrel in the chill").
OUTPUT:
[hill][grass][there][sits][squirrel][chill]
1true
false