From owner-prolog-standard@LISTSERV.UGA.EDU Fri Feb 12 18:39:43 2016 Date: Fri, 12 Feb 2016 18:27:08 +0100 From: Per MildnerSubject: [PROLOG-STANDARD] Comments on the DCG draft, dated November 10, 2015 To: PROLOG-STANDARD@LISTSERV.UGA.EDU My comments on "Definite clause grammar rules" dated November 10, 2015 (the "TR") (apparently available at https://www.complang.tuwien.ac.at/ulrich/iso-prolog/dcgs/dcgsdraft-2015-11-10.pdf). General: I think that a clearer distinction should be made between (abstract) grammar constructs and various representations of these constructs as Prolog terms. E.g., the grammar construct ALTERNATIVE can be represented in two different ways as compound terms but the grammar construct itself is not a Prolog "term" (and the grammar construct itself has none of the ambiguity, related to (->)/2, affecting its various term _representations_). Similarly for the abstract grammar construct(?) "sequence" vs. its representation as a compound term, neither of which have an entry among the definitions. Also see 3.13, below. I think it is good that phrase/2 is defined as bootstrapped using phrase/3. For this reason I think phrase/2 should not be used in 7.14 when explaining the behaviour of the constructs. Now there is pointless repetition, where there is first a (slightly incorrect and not general) explanations using phrase/2 and then a correct and general explanation (e.g. introduced with "More precisely taking semicontext into account: ...") using phrase/3. The phrase/2 parts of the explanations in 7.14 just brings confusion. Inconsistent hyphenation involving "non-", e.g. "non-terminal"/"non terminal", "terminal-sequence"/"terminal sequence". Details: "1 Scope" "... Corrigendum 1:2007-11 ..." is not the same designation as that used in "2 Normative references". "3 Definition" "3.1 alternative" It seems a little greedy to claim the use of the general word "alternative" for this specific use. Perhaps "grammar-body-alternative", e.g. similar to "grammar-body-sequence" (3.12). Also, why does "alternative" have a definition whereas "sequence" and "if-then-else" has not? "3.7 definite clause non-terminal definition" ".. is a sequence of grammar-rules." but should not all the grammar-rules define the same non-terminal? Otherwise there is little difference between 3.7 and "3.6 definite clause grammar". "3.10 grammar-body-element" "... grammar-body-cut (the atom !), or a grammar-goal, or a non-terminal, or ..." Remove the text "(the atom !)" (and add a proper definition for grammar-body-cut). "3.13 grammar-goal" "A compound term ... whose argument is a goal." but a "goal" (3.81) is not a term (a goal is more abstract), so it can not be the argument of a compound term. See my general remark above about lack of abstraction. "3.18 non-terminal (of a grammar rule)" "A ... term ... that denotes a ... of a grammar rule" This seems to imply that such a grammar rule must (potentially) exist somewhere. I think a "non-terminal" should be able to exist on its own, without reference to grammar rules. E.g., "[]" is a non-terminal (and []//0 is its non-terminal indicator) but there can be no associated grammar rule to denote. For the same reason the "(of a grammar rule)" seems a little strange. "3.23 steadfastness of a goal wrt. an argument" "Goal G is steadfast ... if the execution ... of G and (Gnw, Vnw=T) is the same" I (still) thinks this is too strong to be useful. I think a more informal definition is needed (like "refuse to give wrong answers even when the query has an unexpected form", from The Craft of Prolog). On the other hand I do not think its (single) use in this TR is needed or makes sense (more at 8.18.1.1 phrase/[2,3]). E.g., what does it mean for two executions to be "the same"? An execution (7.7.1) is a "sequence of activations" but what does it mean for two such sequences to be "the same"? If nothing else, the fact that the execution of G does not bind Vnw would seem to make the two executions different. Also, if one execution fails and one throws an exception, as could happen in 8.18.1.4d, then (surely?) they can not be said to be "the same" this would happen. Another example. Is the goal "app(A,[],C)" steadfast in its second arguent, given the program app(Xs,Ys,XsYs) :- var(Ys), !, XsYs=Xs. app(Xs,Ys,XsYs) :- append(Xs,Ys,XsYs). Surely the "execution"s of "app(A,[],C)" and "(app(A,Wnw,C),Wnw=[])" are not "the same" even though I think one would like to consider the goal steadfast in its second argument. (Furthermore, is it not so that the common usage of "steadfast" refers to procedures, not to individual goals?) "3.25 terminal-sequence" "A list ... 3.99 ..." This means that a terminal-sequence is a []-terminated list which is not how it is used everywhere in this TR. "3.26 terminal-sequence, comprehensive" "A terminal sequence containing a prefix, and the prefix covered (...) by a grammar-rule-body, i.e. accepted resp. generated by phrase/3 (...)" What is this trying to say? Saying that a terminal-sequence, i.e. a list, is "containing a prefix" is misleading if we are talking about a prefix _of_ the list. "... and the prefix (...) covered by" seems ungrammatical (no pun intended). Should it be ".. and the the prefix (...) _is_ covered by ..." or some such? "3.27 terminal-sequence, remaining" "... a comprehensive terminal-sequence without the leading terminal-sequence covered ..." Perhaps better if 3.26 and 3.27 use the same terminology to refer to the same parts of a comprehensive terminal-sequence, i.e. both should use "prefix" or both should use "leading terminal-sequence". "5.5 Extensions" "A processor may support ... any construct that is ... undefined in this TR or in ... 13211-1 ..." I assume it must be undefined in both, i.e. in "this TR _and_ in ...", or some such. "6.1.3 Variable names convention for termina-sequences" This uses "terminal-sequence" in a way that is not consistent with the requirement (Definition 3.25) that a "terminal-sequence" is a (proper, []-terminated) list. The intermidate states can be partial lists (and even non-lists?, see 7.14.7.2). "6.2.1.1 Directives" "Whenever directives are applicable to non-terminals, the non-terminal indictors ..., as arguments of these directives, shall be used like predicate indicators for the predicates, resulting from expanding these non-terminals." (I think this would be clearer without the last comma) There is some confusion about terminology here. "predicate indicators" (3.131) denote "procedures" not "predicates". What is the result of "expanding ... non-terminals"? Definitely not procedures. Perhaps "... predicate indicators for the procedures _corresponding to_ these non-terminals" is vague enough to convey the correct meaning. The note mentions that the directive dynamic/2 is applicable to non-terminals. What would the effect be? The directives mentioned by the note will cause empty procedures to be created. This makes it possible to create a procedure for NT//N without specifying any grammar rule for it. Other text in the TR seems to assume that there must exist at least one grammar rule for a procedure that corresponds to a non-terminal. Should the TR say something about mixing directives for NT//N and NT/M (where M is N+2)? E.g. if there are no clauses and no grammar rules but two directives ":- discontiguous(p//0). :- discontiguous(p/2).". Also, what about built-in predicates that takes predicate indicators as input or output arguments, e.g. abolish/1 and current_predicate/1? "6.2.1.4 Semicontexts" This entire subclause (6.2.1.4) should be removed. Section "6.2.1 Prolog text" defines the "top-level" constructs that can occur in Prolog text (e.g. in a Prolog file). In this context (once again, no pun intended), "Semicontexts" makes no sense. Semicontexts does not occur on their own in "Prolog text" and it makes absolutely no sense to define their priority. "7.4.2 Directives" "A non-terminal indicator .. may appear ... in .. dynamic/1, ..." What does it mean for a procedure (defined using grammar rules) to be "dynamic" (3.59)? In 7.5.2 is is prescribed that "A clause of a dynamic procedure can be altered" (a very strange wording) but what is the corresponding effect on a procedure defined by grammar rules? The text for dynamic/1 (7.4.2.1) et al. need to be extended to mention grammar rules where it now says things like "The first directive dynamic(PI) ... shall precede all clauses for P" (since it must also precede all grammar rules for P). "7.4.4 Grammar rules" "The grammar rule term in Prolog text (6.2.1.3) enables suitable clauses to be added to the database." However, the "database" (3.52) contains "procedures", not "clauses", so it is not possible for "clauses" to "be added to the database". Also see 7.4.4, where this is correctly described. "7.4.4 Grammar rules" "The non-terminal indicator ... of the grammar-rule-head shall not be ... a grammar control construct." This seems to contradict 7.13.2 that says, referring to the grammar rule "NonTerminal --> GRBody", "If NonTerminal is a grammar control construct its effect shall be implementation dependent." "During preparation for execution the Prolog processor converts grammar rule terms to Prolog procedures of the database." "Prolog" is superfluous here, I think. "7.5.1 Preparing a Prolog text for execution" I think more of the original text in 13211-1 need to be extended where it now mentions clauses and predicate indicator, e.g. is "Each procedure is identified by a unique predicate indicator" really true of a processor that strictly separates clause-based procedures and and grammar-rule-based procedures? "... a Prolog clause ... is already part of the extended database ..." "extended database" is not defined, I think. Should this say "complete database" (3.35)? Even that is a little strange since the complete data base is not present until execution is about to start. Also, as noted above, a "clause" is never part of the "database". 7.13.1 Terminals and non-terminals" "In grammar rule bodies, one or more terminals are represented by terms directly contained in lists in order to distinguish them from non-terminals. The empty terminal sequence (empty list) is possible. Non-terminals are represented by callable terms." Since (non-empty) "list" (3.114) is defined as a compound term with two arguments "terms directly contained in lists" is misleading. Instead, this should use "element (of a list)" (3.61). I think "directly contains in", as used in several places in this TR, should be replaced by more precise wording. "NOTE --- ... Definitions 3.23 and 3.17" Should be "... 3.24 and 3.18". "7.13.2 Format of grammar rules" Incorrect numbering of the referenced definitions. "The grammar-rule-head, is a non-terminal, or a non-terminal, followed by a terminal-sequence (a semicontext, see 7.13.3)" I think the punctuation is confusing here. Perhaps better as "The grammar-rule-head is a non-terminal, or a non-terminal followed by a terminal-sequence (a semicontext, see 7.13.3)"? "The control constructs that may be used in a body are described in subclause 7.14" "An empty body is represented by an empty terminal sequence" Just remove this (or move a reworded version of it to a NOTE). There are no empty grammar rule bodies, period. "NOTE -- There is no (-->)/1 form for grammar rules." The mention of "(-->)/1 form" is strange. Presumably this is trying to say that there is nothing corresponding to the way a fact can be defined in Prolog text by omitting the (implied true) body. But you would not describe such facts as "(:-)/1 forms for clauses". "7.13.3.1 Description" "A semicontext is a terminal-sequence ..., which follows, separated by a comma, the non-terminal of the head of a grammar rule ..." Remove ", separated by a comma,". A "grammar rule" is a Prolog term and at that level of abstraction there is no longer anything "separated" by anything else. The semicontext and the non-terminal of the head are the two arguments of a compund term with principal functor (',')/2 and the many possible textual appareances of this (sub-)term in Prolog text are not relevant here. "7.13.3.2 Exmaples" "Another example may be a small grammar rule with semicontext" "After preparation for execution this may occur ... as:" I do not understand why this example is split between normative text and non-normative NOTES in this particular way. Perhaps the expansion should be moved to the non-normative NOTES. Perhaps some example usage should be added for the two examples. Or not, this TR "is not a tutorial", after all. "NOTES" "3 There are cases, where the remaining terminal-sequence is the comprehensive terminal-sequence. See, e.g. the following grammar rule. There maybe a trailing terminal-sequence, however, as the following example shows." I find it a little hard to make sense of this. Are the first and last sentence opposing in some way? If not, why is "however" used? Also, perhaps it would be possible to remove some of the wordiness of using both "the following grammar rule" and "the following example" to introduce a single grammar rule. "There maybe" should be "There may be" "5 Some processors allow a cut in the semicontext" But then it is not a semicontext as defined in this TR. So, perhaps better as "... a cut in the head" or "... a cut together with the semicontext". "Moving a cut to the end of the grammar body, c.f. a, [word] -->b, !." Is "c.f." correct here? should it be "i.e."? "7.13.4 Non-terminal indicator" "The non-terminal indicator //(A, N) indicates the non-terminal of the head of a grammar rule where A is an atom, representing the non-terminal, and N is its arity, a non-negative integer." A nonterminal indicator, like //([],0) indicates a non-terminal regardless of whether there are, or could be, a grammar rule. So, the mention of grammar rule in this normative text only adds potentially confusion. "A is an atom, representing the non-terminal ..." No. A represents the identifier of the non-terminal. This subclause should be modelled on "7.1.6.6 Predicate indicator" and use that wording with suitable modifications. "NOTES" "2 ..." "Furthermore non-terminal indicators ... property ." Missing comma, I think, and extraneous space before full stop. Should be "Furthermore, non-terminal indicators ... property.". "In particular, using non-terminal indicators in predicate directives allows the details of the expansion of grammar rules into Prolog clauses to be abstracted" What is "predicate directives"? I do not see how the claim is true. How would _not_ using non-terminals in directives leak details (i.e. not allow abstracting the details) about how grammar rules are expanded into Prolog clauses? Are there any built-ins that take predicate indicators as argument and gives information about the _clauses_ of the designated procedures? "7.13.4.1 Examples" "The corresponding non-terminal indicator for the grammar rule left-hand side non-terminal is sentences//0." "left-hand side" is not used elsewhere for referring to the parts of a grammar rule. "grammar rule left-hand side" should be "grammar rule head" (or "grammar-rule-head") i.e. from 3.16. Or, rephrase it as "The non-terminal _of_ the grammar rule is sentence//2", i.e. as in "3.18 non-terminal (of a grammar-rule)". "7.14 Grammar control constructs" "After preparatation ... the non-terminals ... result in constrol constructs, respectively built-in predicates of ... 13211-1." This is not true for user defined non-terminals (i.e. preparing calls to user defined non-terminals will result in neither control constructs or build-ins). I am not sure what the purpose of the paragraph is. Perhaps it can just be removed. "7.14.4 (;)// -- alternative" "... (A;B) ..." Should there not be something about A not having principal functor (->)/2? (Alternatively, separate the abstrace grammar construct ALTERNATIVE from its various term representations. See "General", above.) "NOTE... may be understood best by application of write_canonical/1 ..." I do not think that using write_canonical/1 is appropriate here. As noted in Section 1, Scope, of 13211-1, the standard text "is intended for use by implementors and knowledgeable programmers, and is not a tutorial." so the intended audience should be expected to be able to make sense of Prolog term syntax. The grammar rule can be presented in the usual syntax instead. "... write_canonical ... --> (sentence, ..." There should not be any spaces between the "-->" and the "(". But, as argued above, this part should be removed. "7.14.5 (:)//2 with (->)//2 - if-then-else" "7.14.5.1 Description" This is one place where the failure to distinguish between grammar constructs (if-then-else) and their representations as terms ((A->B);C) brings trouble. I would argue that if-then-else is _not_ the non-terminal (;)//2 with a first argument being the non-terminal (->)//2. The non-terminal (->)//2 is a completely different construct (7.14.12) with different semantics and possible not even supported by an implementation (whereas if-then-else is mandatory). "NOTE - (;)//2 ... whether or not its first argument is a compound term with grammar control construct (->)//2." This makes no sense. As in 7.8.8, the argument of a compound term is a term, not a grammar control construct. So, similar to 7.8.8, it should say "... first argument ... is a compound term with functor (->)/2." "... for alternative ... when the first arument of (;)//2 does not immediatel contain a grammar control construct (->)//2." As above, a term can not contina a grammar control construct. Furthermore, all uses of "immediately contain" should be removed since they just brings confusion. Here too 7.8.8 gets it right (*) and the TR should say something like: "... for alternative ... when the first arument of (;)//2 is a compound term with functor (->)/2." "7.14.5.3" "phrase( ( ("1"|"2") ..." This depends on the Prolog flag double_quotes. It would be better to change the example to use plain list syntax. (*) Unrelated to this TR: I think 7.8.8 actually gets it wrong by using "unify with '->'(_,_)" instead of "being a compound term with functor (->)/2)", which makes a difference if the first argument to (;)/2 is a variable.). And, perhaps 7.8.8 means "principal functor", not just "functor". "7.14.6 ('|')//2 - second form of alternative" "7.14.6.1 Description" "The use of ('|')//2 instead of (;)//2 in an if-then-else, cf 7.14.5, shall be implementation-dependent." Is an implementation allowed to implement if-then (7.14.12) but not "use of ('|')//2 instead of (;)//2 in an if-then-else"? That is, is it allowed to treat '|'((A->B),C) as '|'(([],(A->B)),C) where the first argument of ('|')//2 is treated as a plain if-then? The translation program in Section 10 just happens to do the expected thing (treating '|'((A->B),C) as if-then-else) because it does not distinguish between the abstraction levels when translating compound terms with principal functor (;)/2 and ('|')/2. "7.14.7 {}//1 -- grammar-body-goal" "7.12.7.1" "If G immediately contains a cut ('!'), this i shandled like a ..." As noted above, "immediately contains" lacks a clear meaning and is just confusing. For instance does "{!}" immediately contain a cut? Does "{(!)}"? Does "{true,!}"? Etc. "7.14.7.2 Example" "phrase({true}, nonlist, S) ... succeeds, unifying S with nonlist." This example requires that phrase/3 does no error checking on its second argument (i.e. it does not verify that the second argument is a terminal sequence (or even partial list), contrary to what is suggested as the desirable behaviour in 8.18.1.4c). "7.14.8 call//1" "7.14.8.1 Description" Here, too, the initial description in terms of phrase/2 is just clutter. The following description in terms of phrase/3 is sufficient and clearer. "... phrase(call(G_2), S0,S) is true iff call(G_2, S0,S) is true." This equivalence can not hold if "phrase(call(G_2), S0,S) shall be steadfast ... in its third argument S" (8.18.1.1). Steadfast (3.23) requires that "the execution" of phrase(call(G_2), S0,S) is the same as "the execution" of (phrase(call(G_2), S0,Vnv), Vnv=S) but, since call/3 is not, in general, steadfast in its third argument, either: 1. phrase/3 is steadfast in its third argument but it is false that "phrase(call(G_2), S0,S) is true iff call(G_2, S0,S) is true." (contradicting the above equivalence), or 2. phrase/3 is not steadfast in its third argument (contradicting 8.18.1.1). For a concrete example, consider "S0=a,S=a, phrase(call(==), S0,S)" vs. "S0=a,S=a, phrase(call(==), S0,Vnv), Vnv=S" which clearly do not the the same "execution" (for sensible definitions of "execution"). One way of "fixing" this would be to require that phrase(A,B,C) always ensured steadfastness by being defined as "phrase(A,B,C) :- phrase_internal(A,B,Vnv),Vnv=C." (where phrase_internal/3 does whatever is needed to execute the grammar body A). Additionally, call//2 would need to be defined something like "... phrase(call(G_2), S0,S) is true iff call(G_2, S0,Vnv),Vnv=S". This "fix" would be easy to implement in the code for phrase/3 and in the translation of call//1. Howver, I suspect that such a change in semantics would differ from most current implementations of DCGs, and therefore would be unacceptable. "7.14.11 (\+)//1 -- grammar-body-not "The presence of (\+)//1 in gramamr rules shall be implementation dependant." Is that wording not a little strange? Surely the "presence [of (\+)//2] in grammar rules" depends on whatever grammar rules the user writes. What this standard describes is the _meaning_ of (\+)//1 in gramamr rules when the user has made it present in a grammar rule. "7.14.1.1 Description" "If present in (\+)//1 in grammar rules ..." What is it "present in"? The "If present in" seems to refer to something that got left out. "Implementations conforming to this TR shall not define or use a predicate (\+)/3" Should this say "Processors conforming ..."? Apparently (\+)//1 is a somewhat controversial construct (Quoting O'Keefe: "If someone wants to offer the general case as an exceptionally confusing extension, we can't stop them, but the blood should not be on *our* hands."), so there should be something in the NOTE section about why the construct may be problematic (and why it is not mandatory). The example of (\+)//2 in the NOTE should perhaps be a more realistic use-case? "7.14.12 (->)//2 -- if-then" "7.14.12.1 Description" "The grammar body element A -> B describes one of ( A, B )." Should be "The grammar body element A -> B describes ( A, B ).". (Compare if-then-else 7.14.5.2 where "... ( A -> B; C ) ... "describes one of ( A, B ) or C") Should there be something like "Implementations conforming to this TR shall not define or use a predicate (->)/4"? If not, why for the optional (\+)//2 but not for the optional (->)//2? "7.15 Executing clauses expanded from grammar rules" "If a grammar rule to be prepared for execution has a non-terminal indicator NT//N, ..." Better "If THE HEAD OF a grammar rule ..." "If a grammar rule ... NT//N, ... NT/M, with M is N + 2, ..." Better as "If a grammar rule ... NT//N, ... NT/M, WHERE M is ..." "If a grammar rule ... NT//N [and NT/M is a built-in predicate] ... expansion and behaviour ... is implementation dependent. This does not hold for the required non-terminals expanding to built-in predicates defined in 7.14." What is this trying to say? If the (head of) a grammar rule tries to (re-)define a built-in non-terminal or built-in predicate then something is really wrong in the grammar. How does this have anything to do with the "non-terminals expanding [in grammar bodies] to built-in predicates"? Is it not prohibited somewhere in this TR that grammar rules (for NT//N) must not define the build-in non-terminals NT//N (or built-in predicates NT//M, where M is N+2)? "When the database does not contain a procecure, prepared for execution from one or more grammar rules with non-terminal indicator NT//N during execution of a goal, prepared for execution from a non-terminal with non-terminal indicator NT//N, the behaviour shall be as follows:" "If the error handling ... is standard conforming as specified in subclause 7.7.7 ... then the error term .. shall be:" "existence_error(procedure, NT/M)" I think M should be defined again in this paragraph and not rely on the preceding, unrelated, M. "If the error handling of the processor supports definite clause grammar errors, the nthe error term shall be: existence_error(grammar_rule, NT/M)" Why not existence_error(grammar_rule, NT//N)? If the program understands 'grammar_rule' then it can also be taught to understand NT//N instead of some mixture concepts. Also see Note 1 later in the subclause. I strongly objects to adding a new form of existence error for grammar rules. Even more so when they are optional (and there is no way, as far as I can tell, for a user program to ask the processor whether they are supported or not). Realistically the ordinary procedures and the grammar-rule procedures shares a name space so there can not exist both foo/3 and foo//1 so there is no ambiguity in always using "existence_error(procedure, NT/M)". "When the database does not contain a procecure, prepared for execution from one or more grammar rules with non-terminal indicator NT//N during execution of a goal, prepared for execution from a non-terminal with non-terminal indicator NT//N, the behaviour shall be as follows: .... In other cases the behaviour shall be implementation specific." I think this is overly specific and misses several cases that should not be "implementation specific": 1. What if there are no grammar rules used for defining NT//N? E.g. the procedure is only defined by a directive, such as :-dynamic(foo//1).". Then "the database does not contain a procecure, prepared for execution from ONE OR MORE grammar rules with non-terminal indicator" foo//1. 2. What about all built-in procedures corresponding to non-terminals. Some or all of them may be defined without the use of any grammar rules. 3. What if NT//N has not been defined, but the procedure NT/M, with M = N+2, is defined? (I can understand if this case should left unspecified.) "... In other cases the behaviour shall be implementation specific." What other cases are there? What does this "implementation specific" "behaviour" mean for 5.1.e "... a strictly conforming mode which shall reject the use of an implementation specific feature ..." "NOTES" "1 Prolog processors shall report errors resulting from execution of grammar rules at the same abstraction level as grammar rules whenever possible" What does this mean. It may well be "possible" in cases where it would not be "desirable" (e.g existence_error above) or where it "would overburden a Prolog processors". "2 Parsing resp. generating of terminal sequences using grammar rules is defined in subclauses 8.18.1. Grammar rules are expanded there into Prolog clauses during preparion for execution, which maps the parsing or generaing with a grammar-rule-body into execution a goal given a sequence of predicate clauses. See subclause 7.7 ... for details" What is that paragraph trying to say? "Grammar rules are" NOT "expanded [in 8.18.1] into Prolog clauses" "execution a goal given a sequence of predicate clauses." What is this trying to say? Perhaps remove everything except the first sentence from that paragraph? "8.18.1 phrase/3, phrase/2" "8.18.1.1 Description" "In the absence of semicontexts phrase(GRBody, S), is true ..." Abscense from where? I.e. where should the semicontexts not be present? "In the absence of semicontexts phrase(GRBody, S), is true if S is a phrase covered by the non-terminal or more generally the grammar-rule-body GRBody." As I have noted elsewhere, I think that the more general descriptions are sufficent, clearer, and avoids confusion. So, better remove some text to get "In the absence of semicontexts phrase(GRBody, S), is true if S is a phrase covered by the grammar-rule-body GRBody." "In the absence of semicontexts phrase(GRBody, S0, S) is true if P is phrase covered by the non-terminal GRBody and ..." GRBody is a grammar-rule-body, not just a "non-terminal". Also, where should the semicontexts be absent? Better remove most text up to "In the presence of semicontext later in the subclause. "The description of phrase(GRBOdy, S0, S)) ..." One extra right bracket. "The description of phrase(GRBOdy, S0, S)) in the presnece of semicontext ..." Where are these semicontext present? "The description of phrase(GRBOdy, S0, S)) in the presnece of semicontext exploits the decomposition GRBody into a compound term ..." What does it mean that GRBody is decomposed _into_ a compound term? Is it trying to say that GRBody _is_ a compound term that is then decomposed (but what if GRBody is '[]'?). "The description of phrase(GRBOdy, S0, S)) in the presnece of semicontext exploits the decomposition GRBody into a compound term ... so that it is enough to provide a recursive description assuming that GRBody is a non terminal" But a valid values of GRBody is already a non-terminal. In particular the grammar control constructs, like (',')//2, are also non-terminals so there is no "compound term composed from non terminals" such that the "compound term" itself is not a non-terminal. Therefore there is no recursive "GRBody is not a non-terminal"-case. " In the presence of semicontexts phrase(NonTerminal, S0,S) is true if there is a gramma rule Nonterminal, Semicontext --> GRBody1 ... else there is no semicontext and there is a grammar rule Nonterminal --> GRBody1 ... " This is a much to imprecise definition of. Surely phrase/3 is just as complex as call/1 to describe (i.e. 7.8.3 and 7.7.7), so the above just brings confusion. Some details "In the presence of semicontexts ... else there is no semicontexts ..." WHERE should the semicontexts be present in order to exclude the second part of this disjunctive definition? "... phrase(NonTerminal, S0,S) is true ... there is a grammar rule Nonterminal --> GRBody1 ..." But the grammar rule must be reachable during execution (e.g. no preceding grammar rules must have used cut or thrown an exception). "... phrase(NonTerminal, S0,S) is true ... there is a grammar rule Nonterminal --> GRBody1 ..." But the first argument to phrase/3 need not be identical (i.e. exactly Nonterminal) to the head of the grammar rule (e.g. it suffice that they are unifiable). "Procedurally phrase(GRBody, S0, S) is executed as dcg_body(GRBody, S0, S, Goal), call(Goal) ..." "... is executed as IF dcg_body(..."? "phrase(GRBody, S0, S) shall be steadfast (cf. 3.22) in its third argument S." should be "... (cf. 3.23) ..." Is this trying to say that phrase(GRBody, S0, S) must be implemented something like the following? phrase(GRBody, S0, S) :- phrase(GRBody, S0, S) :- phrase_internal(GRBody, S0, Vnv), S = Vnv." (see my discussion of "7.14.8 call//1", above) It would be possible to pass S directly to the procedures that implements the grammar rules, while still keeping phrase(GRBody, S0, S) steadfast, by 1. Ensuring that clauses corresponding to grammar rules do not do output unification (of S) too early. 2. Ensure that call//1 is implemented so that the S does not leak into the third argument of the procedure called by call//1 (the current transformations in subclause 10 does _not_ implement call//1 in this way, i.e. the current transformations in subclause 10 leaks S to plain Prolog procedures. See my notes on call//1, above). "Execution of the predicate phrase/3 serves two goals: Firstly the final expansion(of a grammar rule) (cf. Definiton 3.7), when this has not taken place earlier, i.e. preparation for execution of its body and argumens; thereafter, secondly, the execution of the resulting Prolog goals." This sentence is very hard to make sense of. "Execution of the predicate phrase/3 serves ... the ... expansion(of a grammar rule) ..." But phrase/1 is never invoked on a grammar rule, its first argument is only a grammar-rule-body, so how can it serve the goal of "expansion (of a grammar rule)" (or even the "preparation for execution of the [the grammar rule's] body and arguments"?) The only normative text that I could find in this TR that defines preparing grammar rules for execution is subclause 7.4.4 which refers to Section 10. Section 10 does not use phrase/3 for anything, so I fail to see how phrase/3 is involved in preparing a grammar rule for execution. "... phrase/3 [does] the final expansion ..., when this has not taken place earlier" What does this mean? When could the final expansion have taken place (or not taken place) earlier? "... serves two goals: ..." Perhaps "... serves two purposes: ..." is better since "goals" has other important meanings in Prolog. "... final expansion(of a grammar rule) ..." Needs a space after "expansion". "... Definiton 3.7 ..." Should be "... Definiton 3.8 ...". "NOTE 1 -- If the simple grammar of example 7.14.1.1 is ..." Should be "NOTE 1 ... 7.13.1.1 ...". "8.18.1.4 Errors" (referring to phrase(GRBody, S0, S) although this is not made very clear in this subclause) "c) S0 is not a terminal-sequence ... type_error ... for phrase/2 error clause c is required. " This would disallow phrase(nt, S) since S (a variable) is not a "terminal-sequence" (3.25). Also, the example in 7.14.7.2 would not work if this error-case is implemented for phrase/3. "d) S is not a terminal-sequence ... type_error ... " Same here. In most cases S will be a variable, i.e. not a list (3.99) and therefore not a terminal-sequence (3.25), which should not cause an error. "8.18.1.5 Examples" "... the following grammar rules has been ..." Should be "... the following grammar rules HAVE been ..." "10 Logical Expansion" What is "logical" about the expansion? "% This program .... Prolog prologue." There should be some reference to what the "Prolog prologue" is and where it can be found. " dcg_body(NonTerminal, S0, S, Goal) :- nonvar(NonTerminal), \+ dcg_constr(NonTerminal), NonTerminal \= ( _ -> _ ), NonTerminal \= ( \+ _ ), dcg_non_terminal(NonTerminal, S0, S, Goal). " Why is (->//2) and (\+)//2 explicitly prohibited here? If the processor supports them then dcg_constr/1 will be true for them (making the extra NonTerminal \= ... superfluous), if the processor does not support them, then there should be nothing that prevents the user from defining rules for these non-terminals. "dcg_constr({_}). % 7.14.7" Should be "dcg_constr({_}). % 7.14.7 grammar-body-goal" Similar for the other clauses that just have a subclause number but no name in the comment. " dcg_cbody(( GRCond ; GRElse ), S0, S, ( Cond ; Else )) :- subsumes_term(( _GRIf -> _GRThen ), GRCond), dcg_cbody(GRCond, S0, S, Cond), dcg_body(GRElse, S0, S, Else). " The GRCond is unrelated to the grammar control construct if-then, and it is just an ugly hack to use dcg_body/4 for expanding it (even though this happens to "work"). "dcg_cbody(call(Cont), S0, S, call(Cont, S0, S))." Changing this to "dcg_cbody(call(Cont), S0, S, (call(Cont, S0, Vnv), S=Vnv))." would make steadfastness easier to obtain (it would prevent S from leaking into plain Prolog code). See my comments about call//2 and steadfastness, above. " dcg_cbody(( GREither '|' GROr ), S0, S, ( Either ; Or )) :- dcg_body(GREither, S0, S, Either), dcg_body(GROr, S0, S, Or). " This just happens to handle (A->B|C) as IF-THEN-ELSE(A,B,C) instead of of as ALTERNATIVE(IF-THEN(A,B),C). This is an ugly hack. Instead, these optional constructs should be explicitly handled or explicitly prevented, like dcg_constr/1 already do with, e.g. (\+)//1. End notes: I have given feedback before, e.g. to the DCG draft, dated April 8, 2014. Some of those comments may still apply, even if I do not repeat them here. Be advised that I am not a native english speaker, some of my comments on the language in the TR may be affected by that. Also, my language may sometimes be harsh but I realize what a huge effort that has been put into this TR by those involved. Regards, Per Mildner Per.Mildner@sics.se Swedish Institute of Computer Science (SICS Swedish ICT)