i create something but it doesn't worked.The exercise was telling to delete a letter.Example ([c,o,m,k,p,u,t,e,r]) the k must be eliminated.
den([c,o,m,p,u,t,e,r]).
den([n,e,t,w,o,r,k]).
den([p,r,o,g,r,a,m]).
% (c) delete(X,L1,L2):-
% append(A,[X,T],L1),
% append(A,T,L2).
% <------------------ L -------------------->
% +-----------------------------------------+
% |<-> A <-> | X | <-> B <-> | Y | <-> C <->|
% +-----------------------------------------+
% <--------- F --------->
% +-------------------------------------+
% |<-> A <-> | <-> B <-> | Y | <-> C <->|
% +-------------------------------------+
% <-------------- CL --------------->
% +---------------------------------+
% |<-> A <-> | <-> B <-> | <-> C <->|
% +---------------------------------+
delete_extra(Word, CorrectWord) :-
append(Begin, [Letter1|Ypoloipo], Word),
append(Middle, [Letter2|End], Ypoloipo),
word(CorrectWord),
append(Begin, YpoloipoCW, CorrectWord),
append(Middle, End, YpoloipoCW),
Letter1 \= Letter2.
Could it be as simple as:
delete_extra(Word, CorrectWord) :-
select(_, Word, CorrectWord),
den(CorrectWord).
Sample call:
?- delete_extra([c,o,m,k,p,u,t,e,r], CorrectWord).
CorrectWord = [c, o, m, p, u, t, e, r] ;
false.
The select/3 predicate is a de facto standard library predicate over lists that non-deterministically selects an element from a list, returning it and the rest of the list.
Related
A,B,C,D,E,F is one list.
C is before E
A is after F
E is not in fifth
There are two between E and A
After B is E, B is adjacent to E
Which one is the fourth ?
Finally I solved the problem by myself
before(A,B) :- A<B.
after(A,B) :- A>B.
notInFifth(A) :- A \= 5.
adjacent(A,B) :- abs(A - B) =:= 1.
separatedByTwo(A,B) :- abs(A - B) =:= 2.
solution(A,B,C,D,E,F) :-
permutation([1,2,3,4,5,6], [A,B,C,D,E,F]),
notInFifth(E),
separatedByTwo(D,A),
adjacent(B,E),
before(C,E),
before(F,A),
before(E,B).
list is : c e b d f a
So I am trying to convert a grammar that defines variable definitions in a programming language. This is my first every prolog, and its very different from typical languages so I am confused. The grammar goes as follows:
S -> T S | T
T -> char F semicolon | int F semicolon
F -> id | id G
G -> comma F
So effectively it would return true for things like "char id semicolon" or "int id comma id semicolon char id semicolon".
I am trying to turn this into a prolog program to recognize this grammar. What I have so far is:
type([char|T],T).
type([int|T],T).
def([id|T], T).
com([comma|T], T).
semi([semicolon|T], T).
vardef(L,S) :-
type(L,S1),
def(S1,S2),
comma(S2,S3),
def(S3,S4),
semi(S4,S).
variable_definition(L) :-
vardef(L,[]).
However, this obviously only recognizes something that specifically "int/char id comma id semicolon". I don't know how to make it so it has a variable number of "id comma id" before a semicolon, or even have a full new variable definition after the first one. Other questions on this site about the same thing typically have to deal with grammars that are set in place like this, not ones that can have a variable amount of inputs.
EDIT: So the question is two-fold. First, how do I make it so it recognizes two different variable definitions, one right after the other. I assume I have to change the last line in order to complete this, but I am unsure how.
Second, how do I make it recognize a variable amount of "id"s followed by commas. So if I want it to recognize "char id semicolon" as well as "char id comma id semicolon".
The most natural way to express a grammar like this in Prolog is using Prolog's DCG notation:
S -> T S | T
T -> char F semicolon | int F semicolon
F -> id | id G
G -> comma F
s --> t, s | t.
t --> [char], f, [semicolon] | [int], f, [semicolon].
f --> [id] | [id], g.
g --> [comma], f.
The nice thing about DCG is that it expresses the notation more directly. You can then use phrase/2 to run it:
| ?- phrase(s, [char, id, semicolon]).
true ? ;
no
You can with this grammar, to some extent, generate valid phrases:
| ?- phrase(t, S).
S = [char,id,semicolon] ? ;
S = [char,id,comma,id,semicolon] ? ;
S = [char,id,comma,id,comma,id,semicolon] ? ;
...
However...
| ?- phrase(s, S).
Fatal Error: local stack overflow (size: 16384 Kb, reached: 16384 Kb,
environment variable used: LOCALSZ)
The word s is defined in such a way that it doesn't terminate. We can fix this by moving the recursive case later:
s --> t | t, s.
Then:
| ?- phrase(s, S).
S = [char,id,semicolon] ? ;
S = [char,id,comma,id,semicolon] ? ;
S = [char,id,comma,id,comma,id,semicolon] ? ;
...
You can see how this is implemented in standard notation by listing the Prolog code for the predicate:
| ?- listing(t).
% file: user
t(A, B) :-
( A = [char|C],
f(C, D),
D = [semicolon|B]
; A = [int|E],
f(E, F),
F = [semicolon|B]
).
yes
| ?-
You could write this more succinctly as:
t([char|T], B) :-
f(T, [semicolon|B]).
t([int|T], B) :-
f(T, [semicolon|B]).
Which would be called as t(L, []) (the equivalent result as phrase(t, L)).
If we list the rest of the predicates, you can get a complete solution in the form you are asking for:
| ?- listing.
s(A, B) :-
( t(A, B)
; t(A, C),
s(C, B)
).
t(A, B) :-
( A = [char|C],
f(C, D),
D = [semicolon|B]
; A = [int|E],
f(E, F),
F = [semicolon|B]
).
f(A, B) :-
( A = [id|B]
; A = [id|C],
g(C, B)
).
g([comma|A], B) :-
f(A, B).
Refactoring slightly (making it less verbose):
s(L, S) :-
t(L, S).
s(L, S) :-
t(L, S1),
s(S1, S).
t([char|T], S) :-
f(T, [semicolon|S]).
t([int|T], S) :-
f(T, [semicolon|S]).
f([id|S], S).
f([id|S1], S) :-
g(S1, S).
g([comma|S1], S) :-
f(S1, S).
And from here you can call: variable_definition(D) :- s(D, []).
Very, VERY new to Prolog here. My function needs to compare two lists of equal length by taking the larger number into a new list (e.g. larger([3, 12, 5], [6, 3, 11], X) returns X = [6, 12, 11].) This is what I have, but it is not getting me what I need:
larger([],[],[]).
larger([H|T],[E|A],X):- H > E, larger([T],[A],[H|X]).
larger([H|T],[E|A],X):- H < E, larger([T],[A],[E|X]).
Any help is much appreciated.
The other answer is OK, this is a slightly different approach.
Two clauses should be enough:
larger([], [], []).
larger([X|Xs], [Y|Ys], [Z|Zs]) :-
/* Z is the larger number from (X, Y) */
larger(Xs, Ys, Zs).
How you do the part in the comments depends on your exact problem statement and maybe the implementation. At least SWI-Prolog and GNU-Prolog both have an arithmetic function max() that you can use like this in the above:
larger([], [], []).
larger([X|Xs], [Y|Ys], [Z|Zs]) :-
Z is max(X, Y),
larger(Xs, Ys, Zs).
This is arguably nicer than the solution with three clauses because it won't leave behind unnecessary choice points. Like the other solution, it will work fine as long as the two lists have numbers in them.
This would be identical to using a maplist, for example like this:
larger(Xs, Ys, Zs) :-
maplist(max_number, Xs, Ys, Zs).
max_number(X, Y, Z) :- Z is max(X, Y).
You're not far.
Try with
larger([], [], []).
larger([H | T], [E | A], [H | X]) :-
H > E,
larger(T, A, X).
larger([H | T], [E | A], [E | X]) :-
H =< E,
larger(T, A, X).
If I'm not wrong, there are three errors in your code.
(1) you have to translate the bigger head value (H or E) in the third argument of larger/3, not in the recursive call
% ------- H added here ---v
larger([H | T], [E | A], [H | X]) :-
H > E,
larger(T, A, X).
% not here ----^
(2) T and A, the tails in [H|T] and [E|A], are lists, so you have to pass they recursively as T and A, not as [T] and [A]
larger([H | T], [E | A], [H | X]) :-
H > E,
larger(T, A, X).
% not larger([T], [A], X)
(3) if you have the cases H > E and H < E, your code fail when H is equal to E; one solution is H > E and H =< E; the secon case cover H equal to E.
This is the CFG:
S -> T | V
T -> UU
U -> aUb | ab
V -> aVb | aWb
W -> bWa | ba
so this will accept some form of:
{a^n b^n a^m b^m | n,m >= 1} U {a^n b^m a^m b^n | n,m >= 1}
And here is the code I'm working with:
in_lang([]).
in_lang(L) :-
mapS(L), !.
mapS(L) :-
mapT(L) ; mapV(L),!.
mapT(L) :-
append(L1, mapU(L), L), mapU(L1), !.
mapU([a|T]) :-
((append(L1,[b],T), mapU(L1)) ; (T = b)),!.
mapV([a|T]) :-
((append(L1,[b],T), mapV(L1)) ;
(append(L1,[b],T), mapW(L1))),
!.
mapW([b|T]) :-
((append(L1,[a],T), mapW(L1)) ;
(T = a)),
!.
As of right now, this is returning false for the following three strings:
[a,a,b,b,a,b] // this should be true
[a,a,a,b,b,a,a,b,b,b] // this should be true as well
[a,a,a,b,b,a,b,b,b] // this one IS false
Any help or insight would be greatly appreciated, I'm not too comfortable with Prolog so debugging this by myself has been a challenge.
Simply use a dcg! And library(double_quotes).
:- set_prolog_flag(double_quotes, chars).
s --> t | v.
t --> u, u.
u --> "a",u,"b" | "ab".
v --> "a",v,"b" | "a",w,"b".
w --> "b",w,"a" | "ba".
?- use_module(library(double_quotes)).
?- length(L,N), phrase(s, L).
L = "abab", N = 4
; L = "abab", N = 4
; L = "aabbab", N = 6
; L = "abaabb", N = 6
; L = "aababb", N = 6
; L = "abbaab", N = 6
; L = "aaabbbab", N = 8
; L = "aabbaabb", N = 8
; L = "abaaabbb", N = 8
; L = "aaababbb", N = 8
; ... .
First, note that this code doesn't make sense:
... append(L1, mapU(L), L) ...
In Prolog there are predicates, not functions...
A CFG production rule (a non terminal) should 'eat' a number of tokens, and in Prolog this means you need at least 2 arguments: the input token list, and what remains after a production has successfully matched the relevant part of input.
That is, append/3 is not required: just pattern matching, performed by unification operator (=)/2
mapS(L1, L) :- mapT(L1,L) ; mapV(L1,L).
mapT(L1, L) :- mapU(L1,L2), mapU(L2,L).
mapU(L1, L) :- L1=[a|L2], mapU(L2,L3), L3=[b|L] ; L1=[a,b|L].
... complete the translation
and then call it:
?- mapS([a,a,b,b,a,b],R).
R = [] ;
false.
R = [] means the entire sequence has been matched...
In the definition of mapT, you are trying to use the "return value" of mapU as an argument to append. But mapU is a predicate, and predicates don't have return values.
Instead one typically writes a predicate with an unbound variable which the predicate binds to the desired "return value"; after the predciate has been proven, the now bound variable can be used in subsequent predicates.
I am working on an assignment in prolog that scans a list of numerals and should return whether the list is a valid roman numeral and the decimal value of the numerals. Ex)
1 ?- roman(N, ['I'], []).
N = 1
true.
2 ?-
When I run the program that I feel should work, the decimal value is always right, so I'm guessing I got the synthesized attributes part right, but it always returns false for numeral lists that should return true. I'd also like to add that it aborts when it is supposed to if more than 3 Is, Xs, or Cs are present.
1 ?- roman(N, ['I'], []).
N = 1 ;
false.
2 ?- roman(N, ['I','I','I','I'], []).
Error: too many I's
% Execution Aborted
3 ?-
When I take out the N and throw in a {write('N = '), write(N)}, it works fine and returns true.
1 ?- roman(['I'], []).
N = 1
true.
When I remove {N is ValH + ValT + ValU} it returns true, however, it no longer displays the decimal value. Here is the top line of my code (because this is a current assignment, I would prefer to show as little as is necessary to get an answer):
roman(N) --> hundreds(ValH), tens(ValT), units(ValU), {N is ValH + ValT + ValU}.
Why is this returning false with N, but true without, and how do I fix it?
Assignment:
The following BNF specification defines the language of Roman numerals
less than 1000:
<roman> ::= <hundreds> <tens> <units>
<hundreds> ::= <low hundreds> | CD | D <low hundreds> | CM
<low hundreds> ::= e | <low hundreds> C
<tens> ::= <low tens> | XL | L <low tens> | XC
<low tens> ::= e | <low tens> X
<units> ::= <low units> | IV | V <low units> | IX
<low units> ::= e | <low units> I
Define attributes for this grammar to carry out two tasks:
a) Restrict the number of X’s in <low tens>, the I’s in <low units>, and
the C’s in <low hundreds> to no more than three.
b) Provide an attribute for <roman> that gives the decimal value of the
Roman numeral being defined.
Define any other attributes needed for these tasks, but do not change
the BNF grammar.
Did you noticed the grammar is formed of the same pattern (group//5) repeated 3 times, just with different symbols ? I like the compactness...
roman(N) -->
group('C','D','M',100, H),
group('X','L','C',10, T),
group('I','V','X',1, U),
{N is H+T+U}.
group(A,B,C, Scale, Value) -->
( g3(A, T)
; [A, B], {T = 4}
% thanks to Daniel and Will for catching bugs
; [B], g3(A, F), {T is 5+F}
; [B], {T is 5}
; [A, C], {T = 9}
; {T = 0}
), {Value is Scale * T}.
g3(C, 1) --> [C].
g3(C, 2) --> [C,C].
g3(C, 3) --> [C,C,C].
some test
?- atom_chars('CMXXX',L), phrase(roman(N),L).
L = ['C', 'M', 'X', 'X', 'X'],
N = 930 ;
false.
?- atom_chars('CMXLVIII',L), phrase(roman(N),L).
L = ['C', 'M', 'X', 'L', 'V', 'I', 'I', 'I'],
N = 943 ;
false.
Just a curiousity, showing DCG at work...
edit after Daniel and Will comments...
?- atom_chars('VIII',L), phrase(roman(N),L).
L = ['V', 'I', 'I', 'I'],
N = 8 .
?- phrase(roman(X), ['L','I','X']).
X = 59 .