On Quinta, Jun 12, 2003, at 03:30 Europe/Lisbon, Richard A. O'Keefe
Do you have other test cases that you are willing to share?
I'd be willing if I did, but I don't.
More precisely, I have some, but I've lost them.
I've got the residues of file structures from 6 different machines,
imperfectly melded...
Oops! For what is worth, where is my current version of the Logtalk DCG
translator:
% '$lgt_dcgrule_to_clause'(@dcgrule, -clause)
%
% converts a DCG rule to a normal clause
'$lgt_dcgrule_to_clause'(Rule, Clause) :-
catch(
'$lgt_dcg_rule'(Rule, Clause),
Error,
throw(error(Error, dcgrule(Rule)))).
% '$lgt_dcg_rule'(@dcgrule, -clause)
%
% converts a DCG rule to a normal clause
'$lgt_dcg_rule'((RHead --> RBody), CHead) :-
RBody == [],
!,
'$lgt_dcg_head'(RHead, CHead, _, _, S, S, _).
'$lgt_dcg_rule'((RHead --> RBody), (CHead :- CBody)) :-
'$lgt_dcg_head'(RHead, CHead, Body, Body2, S0, S, S1),
'$lgt_dcg_body'(RBody, Body, S0, S),
'$lgt_dcg_fold_unifications'(Body2, CBody, S1).
% '$lgt_dcg_head'(@dcghead, -head, @goal, -goal, @var, @var, -var)
%
% translates DCG rule head to a Prolog clause head
% (the last argument returns the variable representing the ouput list)
'$lgt_dcg_head'(RHead, _, _, _, _, _, _) :-
var(RHead),
throw(instantiation_error).
'$lgt_dcg_head'((_, Terminals), _, _, _, _, _, _) :-
\+ '$lgt_proper_list'(Terminals),
throw(type_error(list, Terminals)).
'$lgt_dcg_head'((Nonterminal, Terminals), CHead, Body, (Body,Goal), S0,
S, S1) :-
!,
'$lgt_dcg_terminals'(Terminals, Goal, S1, S),
'$lgt_dcg_goal'(Nonterminal, CHead, S0, S1).
'$lgt_dcg_head'(Nonterminal, CHead, Body, Body, S0, S, S) :-
'$lgt_dcg_goal'(Nonterminal, CHead, S0, S).
% '$lgt_dcg_body'(@dcgbody, -body, @var, @var)
%
% translates DCG rule body to a Prolog clause body
'$lgt_dcg_body'(Var, phrase(Var, S0, S), S0, S) :-
var(Var),
!.
'$lgt_dcg_body'(::Goal, ::phrase(Goal, S0, S), S0, S) :-
!.
'$lgt_dcg_body'(Object::Goal, Object::phrase(Goal, S0, S), S0, S) :-
!.
'$lgt_dcg_body'((RGoal,RGoals), (CGoal,CGoals), S0, S) :-
!,
'$lgt_dcg_body'(RGoal, CGoal, S0, S1),
'$lgt_dcg_body'(RGoals, CGoals, S1, S).
'$lgt_dcg_body'((RGoal1 -> RGoal2), (CGoal1 -> CGoal2), S0, S) :-
!,
'$lgt_dcg_body'(RGoal1, CGoal1, S0, S1),
'$lgt_dcg_body'(RGoal2, CGoal2, S1, S).
'$lgt_dcg_body'((RGoal1;RGoal2), (CGoal1;CGoal2), S0, S) :-
!,
'$lgt_dcg_body'(RGoal1, CGoal1, S0, S),
'$lgt_dcg_body'(RGoal2, CGoal2, S0, S).
'$lgt_dcg_body'({Goal}, (CGoal, S0=S), S0, S) :-
!,
(var(Goal) -> CGoal = call(Goal); CGoal = Goal).
'$lgt_dcg_body'(!, (!, S0=S), S0, S) :-
!.
'$lgt_dcg_body'(\+ RGoal, CGoal, S0, S) :-
!,
'$lgt_dcg_body'((RGoal -> {fail};{true}), CGoal, S0, S).
'$lgt_dcg_body'([], (S0=S), S0, S) :-
!.
'$lgt_dcg_body'([Terminal| Terminals], CGoal, S0, S) :-
!,
'$lgt_dcg_terminals'([Terminal| Terminals], CGoal, S0, S).
'$lgt_dcg_body'(Non_terminal, CGoal, S0, S) :-
'$lgt_dcg_goal'(Non_terminal, CGoal, S0, S).
% '$lgt_dcg_goal'(@goal, -goal, @var, @var)
%
% translates DCG goal to Prolog goal
'$lgt_dcg_goal'(RGoal, _, _, _) :-
\+ '$lgt_callable'(RGoal),
throw(type_error(callable, RGoal)).
'$lgt_dcg_goal'(RGoal, CGoal, S0, S) :-
RGoal =.. RList,
'$lgt_append'(RList, [S0, S], CList),
CGoal =.. CList.
% '$lgt_dcg_terminals'(@list, -goal, @var, @var)
%
% translate list of terminals
'$lgt_dcg_terminals'(Terminals, S0=List, S0, S) :-
'$lgt_dcg_terminals'(Terminals, S, List).
'$lgt_dcg_terminals'([], S, S).
'$lgt_dcg_terminals'([Terminal| Terminals], S, [Terminal| Rest]) :-
'$lgt_dcg_terminals'(Terminals, S, Rest).
% '$lgt_dcg_fold_unifications'(+goal, -goal, @var)
%
% folds redundant calls to =/2 by calling the unification
% goals execept for output unifications
'$lgt_dcg_fold_unifications'((Goal1 -> Goal2), (SGoal1 -> SGoal2), S) :-
!,
'$lgt_dcg_fold_unifications'(Goal1, SGoal1, S),
'$lgt_dcg_fold_unifications'(Goal2, SGoal2, S).
'$lgt_dcg_fold_unifications'((Goal1;Goal2), (SGoal1;SGoal2), S) :-
!,
'$lgt_dcg_fold_unifications'(Goal1, SGoal1, S),
'$lgt_dcg_fold_unifications'(Goal2, SGoal2, S).
'$lgt_dcg_fold_unifications'((Goal1,Goal2), SGoal, S) :-
!,
'$lgt_dcg_fold_unifications'(Goal1, SGoal1, S),
'$lgt_dcg_fold_unifications'(Goal2, SGoal2, S),
'$lgt_dcg_simplify_and'((SGoal1,SGoal2), SGoal).
'$lgt_dcg_fold_unifications'(S1=S2, S1=S2, S) :-
(S1 == S; S2 == S),
!.
'$lgt_dcg_fold_unifications'(S1=S2, true, _) :-
var(S2),
!,
S1 = S2.
'$lgt_dcg_fold_unifications'(Goal, Goal, _).
% '$lgt_dcg_simplify_and'(+goal, -goal)
%
% removes redundant calls to true/0 and flats a conjunction of goals
'$lgt_dcg_simplify_and'((Goal1 -> Goal2), (SGoal1 -> SGoal2)) :-
!,
'$lgt_dcg_simplify_and'(Goal1, SGoal1),
'$lgt_dcg_simplify_and'(Goal2, SGoal2).
'$lgt_dcg_simplify_and'((Goal1;Goal2), (SGoal1;SGoal2)) :-
!,
'$lgt_dcg_simplify_and'(Goal1, SGoal1),
'$lgt_dcg_simplify_and'(Goal2, SGoal2).
'$lgt_dcg_simplify_and'(((Goal1,Goal2),Goal3), Body) :-
!,
'$lgt_dcg_simplify_and'((Goal1,(Goal2,Goal3)), Body).
'$lgt_dcg_simplify_and'((true,Goal), Body) :-
!,
'$lgt_dcg_simplify_and'(Goal, Body).
'$lgt_dcg_simplify_and'((Goal,true), Body) :-
!,
'$lgt_dcg_simplify_and'(Goal, Body).
'$lgt_dcg_simplify_and'((Goal1,Goal2), (Goal1,Goal3)) :-
!,
'$lgt_dcg_simplify_and'(Goal2, Goal3).
'$lgt_dcg_simplify_and'(Goal, Goal).
Some notes:
1. The "funny" functors are a consequence of these predicates being
part of the internals of Logtalk.
2. The predicate '$lgt_dcg_head'/7 is based on a similar definition
found on a DCG translator posted by Richard A. O'Keefe a long time ago
in a mailing list discussion on DCGs. I've extended its definition to
return the variable that represents the output list of terminals in the
head. I need this variable to later fold redundant calls to =/2.
3. The flattening of conjunctions and removing of redundant calls to
true/0 is performed while folding redundant calls to unification goals.
4. We need a standard for DCG rule translation. I'm yet to find two
Prolog compilers compiling DCG rules in the same way (regarding open
source compilers, I've tried YAP, SWI-Prolog, GNU Prolog).
5. Logtalk is open source code, including the code above... that's of
course based on other open source and public domain code (the code for
folding unifications is invented by my... hope that it's not a silly
invention ;-).
Cheers,
Paulo
-----------------------------------------------------------
Paulo Jorge Lopes de Moura
Dep. of Informatics Office 4.3 Ext. 3257
University of Beira Interior Phone: +351 275319700
6201-001 Covilhã Fax: +351 275319891
Portugal
<mailto:***@di.ubi.pt>
<http://www.logtalk.org/pmoura.html>
-----------------------------------------------------------
----------------
* To UNSUBSCRIBE, please use the HTML form at
http://www.swi-prolog.org/mailinglist.html
or send mail to prolog-***@swi.psy.uva.nl using the Subject: "unsubscribe"
(without the quotes) and *no* message body.
** An ARCHIVE of this list is maintained at
http://www.swi.psy.uva.nl/projects/SWI-Prolog/mailinglist/archive/