Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Rolando Grave De Peralta Gonzalez
semantique_2019
Commits
1ce77b12
Commit
1ce77b12
authored
May 20, 2019
by
Damien.Morard
Browse files
Add brainfuck prolog
parent
023a6adb
Changes
1
Hide whitespace changes
Inline
Side-by-side
Exercices/Exercice8/brainfuck.pl
0 → 100644
View file @
1ce77b12
% ---------------------------------------------------------------- %
% ---------------------------- Syntax ---------------------------- %
% ---------------------------------------------------------------- %
% Symbol of our syntax
bf
(
">"
).
bf
(
"<"
).
bf
(
"+"
).
bf
(
"-"
).
bf
(
"."
).
bf
(
","
).
% Program syntax
prog
([],
X
,
X
).
% prog(["[", P, "]" | T]) :-
% prog(P), prog(T).
prog
([
"["
|
T
],
X
,
Y
)
:-
Xp
is
X
+
1
,
prog
(
T
,
Xp
,
Y
).
prog
([
"]"
|
T
],
X
,
Y
)
:-
Yp
is
Y
+
1
,
prog
(
T
,
X
,
Yp
).
prog
([
H
|
T
],
X
,
Y
)
:-
bf
(
H
),
prog
(
T
,
X
,
Y
).
progP
(
P
)
:-
prog
(
P
,
0
,
0
).
% ---------------------------------------------------------------- %
% -------------------------- Semantic ---------------------------- %
% ---------------------------------------------------------------- %
% Return the value depends on the pointer
findVal
([
H
|
_
],
0
,
H
).
findVal
([
_
|
T
],
P
,
Res
)
:-
findVal
(
T
,
Pp
,
Res
),
P
is
Pp
+
1
.
% Count number of elements in a list (need it to know number of instruction in a prog)
count
([],
0
).
count
([
_
|
T
],
Res
)
:-
count
(
T
,
R
),
Res
is
R
+
1
.
% Inc the value in the table at the position Pt
incValue
([
H
|
T
],
0
,
[
Hp
|
T
])
:-
Hp
is
H
+
1
.
incValue
([
H
|
T
],
Pt
,
[
H
|
Res
])
:-
incValue
(
T
,
Ptp
,
Res
),
Pt
is
Ptp
+
1
.
% Dec the value in the table at the position Pt
decValue
([
0
|
T
],
0
,
[
0
|
T
]).
decValue
([
H
|
T
],
0
,
[
Hp
|
T
])
:-
H
>
0
,
Hp
is
H
-
1
.
decValue
([
H
|
T
],
Pt
,
[
H
|
Res
])
:-
decValue
(
T
,
Ptp
,
Res
),
Pt
is
Ptp
+
1
.
% ---------------------------------------------------------------- %
% Giving a position Pi, we return a Program where only the elements after Pi in the prog
% Element in Pi position is not returned. (Put 1 instead of 0 if you want element in Pi position)
cutProgram
(
P
,
0
,
P
).
cutProgram
([
_
|
T
],
Pi
,
SubP
)
:-
Pip
is
Pi
-
1
,
cutProgram
(
T
,
Pip
,
SubP
).
% Return the close bracket depending on the open bracket.
% Does not necessarily return the first close bracket
posCloseBracket
([
"]"
|
_
],
1
,
0
).
posCloseBracket
([
"["
|
T
],
Nb
,
Res
)
:-
Nbp
is
Nb
+
1
,
posCloseBracket
(
T
,
Nbp
,
R
),
Res
is
R
+
1
.
posCloseBracket
([
"]"
|
T
],
Nb
,
Res
)
:-
Nbp
is
Nb
-
1
,
posCloseBracket
(
T
,
Nbp
,
R
),
Res
is
R
+
1
.
posCloseBracket
([
H
|
T
],
Nb
,
Res
)
:-
H
\
=
"["
,
H
\
=
"]"
,
posCloseBracket
(
T
,
Nb
,
R
),
Res
is
R
+
1
.
% posCB find the next bracket depending on the position of Pi and the open bracket
% Normally Pi point on an open bracket instruction.
% To return the position of the next good bracket, we count from Pi the number
% of elements we browse until we find the good close bracket.
% We add this result with Pi and we obtain the position of the next close bracket
% in the program P
posCB
(
P
,
Pi
,
Res
)
:-
cutProgram
(
P
,
Pi
,
SubP
),
posCloseBracket
(
SubP
,
0
,
SubR
),
Res
is
Pi
+
SubR
.
% ---------------------------------------------------------------- %
% Reverse a list with a define nb of elements
reverse
([
H
|
_
],
0
,
[
H
]).
reverse
([
H
],
_
,
[
H
]).
reverse
([
H
|
_
],
1
,
[
H
]).
reverse
([
H
|
T
],
Nb
,
Res
)
:-
Nb
>
1
,
Nbp
is
Nb
-
1
,
reverse
(
T
,
Nbp
,
Resp
),
append
(
Resp
,
[
H
],
Res
).
% Return the open bracket depending on the close bracket.
% Does not necessarily return the first open bracket
posOpenBracket
([
"["
|
_
],
1
,
0
).
posOpenBracket
([
"]"
|
T
],
Nb
,
Res
)
:-
Nbp
is
Nb
+
1
,
posOpenBracket
(
T
,
Nbp
,
R
),
Res
is
R
+
1
.
posOpenBracket
([
"["
|
T
],
Nb
,
Res
)
:-
Nbp
is
Nb
-
1
,
posOpenBracket
(
T
,
Nbp
,
R
),
Res
is
R
+
1
.
posOpenBracket
([
H
|
T
],
Nb
,
Res
)
:-
H
\
=
"["
,
H
\
=
"]"
,
posOpenBracket
(
T
,
Nb
,
R
),
Res
is
R
+
1
.
% posOB find the last bracket depending on the position of the close bracket
% P is a Program, Pi the position of the close bracket in the program, and Res
% the result
% Example: posOB(["+", "-", "[", "[", "+", "+", "]", "]"], 7, Res).
% Res = 2. % Not 3
% The method to find the last bracket is to reverse P (which is a program
% and representend by a list in Prolog). However we cut the list at the Pi position,
% keep elements before and after this we reverse the list.
% Finally we try to find the first open bracket (in the reverse list) and we return its position.
posOB
(
P
,
Pi
,
Res
)
:-
reverse
(
P
,
Pi
+
1
,
Prog
),
posOpenBracket
(
Prog
,
0
,
R
),
Res
is
Pi
-
R
.
% ---------------------------------------------------------------- %
% When it's finished
eval
(
_
,
_
,
_
,
_
,
""
).
% When we have ">", we have two case. If we have already declared
% the case in the table, we just move the pointer on it
% Otherwise we need to increase the size of our table and initialize with 0.
eval
(
Pi
,
Pt
,
Tab
,
Prog
,
">"
)
:-
Pip
is
Pi
+
1
,
Ptp
is
Pt
+
1
,
count
(
Tab
,
Nb
),
Ptp
+
1
=<
Nb
,
findVal
(
Prog
,
Pip
,
Inst
),
eval
(
Pip
,
Ptp
,
Tab
,
Prog
,
Inst
).
eval
(
Pi
,
Pt
,
Tab
,
Prog
,
">"
)
:-
Pip
is
Pi
+
1
,
Ptp
is
Pt
+
1
,
count
(
Tab
,
Nb
),
Ptp
+
1
>
Nb
,
append
(
Tab
,
[
0
],
Tabp
),
findVal
(
Prog
,
Pip
,
Inst
),
eval
(
Pip
,
Ptp
,
Tabp
,
Prog
,
Inst
).
% When we have "<", we have two cases.
% If we have Pt on 0, we stay on 0 as many times as needed
% Otherwise we decrement Pt by 1.
eval
(
Pi
,
Pt
,
Tab
,
Prog
,
"<"
)
:-
Pt
>
0
,
Pip
is
Pi
+
1
,
Ptp
is
Pt
-
1
,
findVal
(
Prog
,
Pip
,
Inst
),
eval
(
Pip
,
Ptp
,
Tab
,
Prog
,
Inst
).
eval
(
Pi
,
Pt
,
Tab
,
Prog
,
"<"
)
:-
Pip
is
Pi
+
1
,
Pt
==
0
,
findVal
(
Prog
,
Pip
,
Inst
),
eval
(
Pip
,
Pt
,
Tab
,
Prog
,
Inst
).
% We increment the value at the position Pt on Tab
eval
(
Pi
,
Pt
,
Tab
,
Prog
,
"+"
)
:-
Pip
is
Pi
+
1
,
incValue
(
Tab
,
Pt
,
Tabp
),
findVal
(
Prog
,
Pip
,
Inst
),
eval
(
Pip
,
Pt
,
Tabp
,
Prog
,
Inst
).
% We decrement the value at the position Pt on Tab
eval
(
Pi
,
Pt
,
Tab
,
Prog
,
"-"
)
:-
Pip
is
Pi
+
1
,
decValue
(
Tab
,
Pt
,
Tabp
),
findVal
(
Prog
,
Pip
,
Inst
),
eval
(
Pip
,
Pt
,
Tabp
,
Prog
,
Inst
).
% We print the result
eval
(
Pi
,
Pt
,
Tab
,
Prog
,
"."
)
:-
Pip
is
Pi
+
1
,
findVal
(
Prog
,
Pip
,
Inst
),
print
(
Tab
),
eval
(
Pip
,
Pt
,
Tab
,
Prog
,
Inst
).
% Case where Value on Pt (in the table) is different from 0
eval
(
Pi
,
Pt
,
Tab
,
Prog
,
"["
)
:-
findVal
(
Tab
,
Pt
,
Res
),
Res
\
=
0
,
Pip
is
Pi
+
1
,
findVal
(
Prog
,
Pip
,
Inst
),
eval
(
Pip
,
Pt
,
Tab
,
Prog
,
Inst
).
% Case where Value on Pt (in the table) is 0
eval
(
Pi
,
Pt
,
Tab
,
Prog
,
"["
)
:-
findVal
(
Tab
,
Pt
,
Res
),
Res
==
0
,
posCB
(
Prog
,
Pi
,
NextPos
),
NextP
is
NextPos
+
1
,
findVal
(
Prog
,
NextP
,
Inst
),
eval
(
NextP
,
Pt
,
Tab
,
Prog
,
Inst
).
% Case where Value on Pt (in the table) is different from 0
eval
(
Pi
,
Pt
,
Tab
,
Prog
,
"]"
)
:-
findVal
(
Tab
,
Pt
,
Res
),
Res
\
=
0
,
posOB
(
Prog
,
Pi
,
NextPos
),
NextP
is
NextPos
+
1
,
findVal
(
Prog
,
NextP
,
Inst
),
eval
(
NextP
,
Pt
,
Tab
,
Prog
,
Inst
).
% Case where Value on Pt (in the table) is 0
eval
(
Pi
,
Pt
,
Tab
,
Prog
,
"]"
)
:-
findVal
(
Tab
,
Pt
,
Res
),
Res
==
0
,
Pip
is
Pi
+
1
,
findVal
(
Prog
,
Pip
,
Inst
),
eval
(
Pip
,
Pt
,
Tab
,
Prog
,
Inst
).
% Function to call to test his own program
% I introduced "" to know when it's the end of the file
evalp
(
Prog
,
Tab
)
:-
progP
(
Prog
),
append
(
Prog
,
[
""
],
ProgEOF
),
findVal
(
Prog
,
0
,
Inst
),
eval
(
0
,
0
,
Tab
,
ProgEOF
,
Inst
).
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment