Dear friends:
In swi-prolog I can do such thing "sentence --> nounphrase, verbphrase."
The "-->" which is called DCG(Definite Clasue Grammer).
and in swi-prolog I can take ";" as "if else" to use.
Whether can visual prolog do things like above?
two queries about swi-prolog and visual-prolog
I am a rookee coming here to learn from friends.
- Thomas Linder Puls
- VIP Member
- Posts: 1399
- Joined: 28 Feb 2000 0:01
Let us start with the simple one: ";" is a backtracking "or" both in swi-Prolog and in Visual Prolog. I.e. means the same.
Visual Prolog does not (directly) support Definite Clause Grammars (DCG).
DCG is however a quite simple syntactic sugaring.
Is simply short for
I.e. each nonterminal is extended with an input and an output argument, the overall input becomes input in the first nonterminal, each output goes as input to the next, and the final output becomes the overall output.
Semantic actions (enclosed in { .. }) are treated as regular predicate calls. So
means
Terminals (enclosed in [ .. ]) means match a list head. So
means:
Maybe (my memory is not completely "fresh" on this matter) the list match is actually performed in an auxiliary predicate:
The grammar clauses can use additional argumentswhich are simply maintained in the translation. So
Means:
Visual Prolog does not (directly) support Definite Clause Grammars (DCG).
DCG is however a quite simple syntactic sugaring.
Code: Select all
sentence --> nounphrase, verbphrase
Code: Select all
clauses
sentence(S1, S0) :-
nounphrase(S1, S2),
verbphrase(S2, S3),
S0 = S3. % S0 is normally used directly instead of S3
Semantic actions (enclosed in { .. }) are treated as regular predicate calls. So
Code: Select all
sentence --> nounphrase, {action}, verbphrase
Code: Select all
clauses
sentence(S1, S0) :-
nounphrase(S1, S2),
action(),
verbphrase(S2, S0).
Code: Select all
sentence --> ["The"], nounphrase, {action}, verbphrase
Code: Select all
clauses
sentence(S1, S0) :-
["The"|S2] = S1,
nounphrase(S2, S3),
action(),
verbphrase(S3, S0).
Code: Select all
clauses
sentence(S1, S0) :-
match(["The"], S1, S2),
nounphrase(S2, S3),
action(),
verbphrase(S3, S0).
Code: Select all
sentence(sentence(N,V)) --> ["The"], nounphrase(N), {action}, verbphrase(V)
Code: Select all
clauses
sentence(sentence(N,V), S1, S0) :-
match(["The"], S1, S2),
nounphrase(N, S2, S3),
action(),
verbphrase(V, S3, S0).
Regards Thomas Linder Puls
PDC
PDC
Wow,Thomas,you are a genius.Thank you
The "DCG" is perfectly solved beyond my expectation.
And I have tested the ";" again.There is a problem here.When I define such a predicate:
class predicates
fact:(integer N, integer Res) procedure (i,o).
clauses
fact(N, F) :-
(N<=1,F=1);
(N>1,fact(N-1, F1),F=F1*N).
I thought the "fact" should be "procedure",but it results in "nondeterm"
ERROR: 'fact/2 (i,o)', which is declared as 'procedure', is actually 'nondeterm'
Where is it wrong?
The "DCG" is perfectly solved beyond my expectation.
And I have tested the ";" again.There is a problem here.When I define such a predicate:
class predicates
fact:(integer N, integer Res) procedure (i,o).
clauses
fact(N, F) :-
(N<=1,F=1);
(N>1,fact(N-1, F1),F=F1*N).
I thought the "fact" should be "procedure",but it results in "nondeterm"
ERROR: 'fact/2 (i,o)', which is declared as 'procedure', is actually 'nondeterm'
Where is it wrong?
I am a rookee coming here to learn from friends.
- Thomas Linder Puls
- VIP Member
- Posts: 1399
- Joined: 28 Feb 2000 0:01
N <= 1 and N >1 are:
To convince the "dumb" compiler that you have a procedure, you will either have to use cut and "external" reasoning:
If the first case match the cut (!) will remove the backtrack point to the second case, so the predicate can no longer return with an active backtrack point, the second case omits the test (we will only get to the second case if the first case fails i.e. if not(N <= 1) which is the same as N > 1) so the compiler sees something that always succeeds. And therefore the compiler now sees a procedure.
Alternatively, and to keep a declarative cut-less reading of the program you can use the if-then-else construction (which you will not find in swi-Prolog):
As a final update I will suggest creating a function instead (also not in swi-Prolog):
Or skipping the variable F using an if-then-else expression instead:
Have you been through the Fundamental Visual Prolog Tutorials?
- complete: all integers are handled
- non-overlapping: no integer match both cases
To convince the "dumb" compiler that you have a procedure, you will either have to use cut and "external" reasoning:
Code: Select all
clauses
fact(N, F) :-
(N <= 1, !, F = 1);
(fact(N-1, F1), F = F1 * N).
If the first case match the cut (!) will remove the backtrack point to the second case, so the predicate can no longer return with an active backtrack point, the second case omits the test (we will only get to the second case if the first case fails i.e. if not(N <= 1) which is the same as N > 1) so the compiler sees something that always succeeds. And therefore the compiler now sees a procedure.
Alternatively, and to keep a declarative cut-less reading of the program you can use the if-then-else construction (which you will not find in swi-Prolog):
Code: Select all
clauses
fact(N, F) :-
if N <= 1 then
F = 1)
else
fact(N-1, F1),
F = F1 * N
end if.
Code: Select all
class predicates
fact : (integer N) -> integer Fac.
clauses
fact(N) = F :-
if N <= 1 then
F = 1
else
F = N * fact(N-1)
end if.
Code: Select all
class predicates
fact : (integer N) -> integer Fac.
clauses
fact(N) = if N <= 1 then 1 else N * fact(N-1) end if.
Regards Thomas Linder Puls
PDC
PDC