Loading ...
Sorry, an error occurred while loading the content.
 

Re: [pcgen-xml] Nested Prerequisites (Was: Examples)

Expand Messages
  • Frugal
    ... There are 2 reasons I can think of: 1 - As you said yourself boolean logic is not easily comprehended by most people. 2 -
    Message 1 of 29 , Apr 14, 2004
      <quote who="Jenni A. Merrifield">
      > Is there any particular reason, with this *internal* data
      > representation,
      > to avoid using traditional Boolean operators such as "AND", "OR", "XOR"
      > and
      > "NOT"? Using it, we could be quite sure of what prerequisites were being
      > requested and their relationships to each other.

      There are 2 reasons I can think of:

      1 - As you said yourself boolean logic is not easily comprehended by most
      people.

      2 - There are cases where boolean logic will not suffice. A prime example
      is "you must have 2 of these following 3 feats".

      I used the syntax of:

      <prereq kind=""
      key=""
      subkey=""
      operator="=,!=,<,<=,>,>="
      operand=""
      countmultiples="true|false" />

      Because it copes with every single case. It also allows for things like:

      <prereq kind="feat"
      key="weapon focus"
      operator=">="
      operand="2"
      countmultiples="true" />

      For "You must have taken weapon focus with at least 2 weapons.

      --
      regards,
      Frugal
      -OS Chimp
    • Jenni Merrifield
      {Bah. I apologize if this shows up twice - I tried to use the Yahoo! Post function last night and even though it said it had been posted, I don t see this
      Message 2 of 29 , Apr 15, 2004

          {Bah.  I apologize if this shows up twice – I tried to use the Yahoo ! "Post" function last night and even though it said it had been posted, I don't see this or the other message I'm about to send on the web site.

        =JAMM}

         

        <quote who="Frugal" when="Wed, 14 Apr, 2004  12:50 +0100 (BST)">

        > <quote who="Jenni A. Merrifield">

        > >   Is there any particular reason, with this *internal* data

        > > representation, to avoid using traditional Boolean operators

        > > such as "AND", "OR", "XOR" and "NOT"?  Using it, we could be

        > > quite sure of what prerequisites were being requested and their

        > > relationships to each other.

        >

        > There are 2 reasons I can think of:

        >

        > 1 - As you said yourself boolean logic is not easily comprehended

        > by most people.

         

          True, but "most people" won't be working with the *internal* data structure right?  Programmers work with it, so *external* data can be converted into it and it can be loaded by the application, but I'd be willing to hazzard a guess that "most programmers" do understand boolean logic.

         

          Nonetheless, Keith did make some very good arguments about his min/max method and I would have to agree that it is more elegant, consistent, and less complicated.

         

        > 2 - There are cases where boolean logic will not suffice. A prime

        > example is "you must have 2 of these following 3 feats".

         

          Technically, "2 of the following 3 feats" is possible with strict Boolean, although in a very long, annoying out manner:

         

          (A && B && !C) || (A && !B && C) || (!A && B && C)

         

          Of course, as Keith pointed out, adding a "select/pick/choose" option would provide a more straightforward mechanism.

         

          Of course, he didn't bother to mention that such a "pick" option is really identical to his basic min/max recommendation, as it defaults to "AND" and can be used for "OR", "XOR" as well as all the other options such as "n of m", "at least n", "no more than n", "between n and m".  So I agree with Keith - why implement it as Boolean logic when a min/max implementation will do it all.

         

        > I used the syntax of:

        >

        > <prereq kind=""

        >         key=""

        >         subkey=""

        >         operator="=,!=,<,<=,>,>="

        >         operand=""

        >         countmultiples="true|false" />

        >

        > Because it copes with every single case.

         

          True, but it also suffers from the need to do string comparisons just like Boolean operands, whereas Keith's numerical method does not and is (as he explained) more straightforward to implement.

         

          Each of your operators can also be acheived using his method:

         

        *** Frugal's operator method:

         

          <!-- Any N of the following M items -->

          <prereq [...] operator="=" operand="n">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

          <!-- Not equal to N of the following M items -->

          <!-- Note: both < N and > N will be allowed -->

          <prereq [...] operator="!=" operand="n">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

          <!-- Less than N of the following M items -->

          <prereq [...] operator="<" operand="n">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

          <!-- No more than N of the following M items -->

          <prereq [...] operator="<=" operand="n">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

          <!-- More than N of the following M items -->

          <prereq [...] operator=">" operand="n">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

          <!-- No less than N of the following M items -->

          <prereq [...] operator=">=" operand="n">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

         

        *** Kieth's min/max method:

         

          <!-- Any N of the following M items -->

          <prereq [...] min="n">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

          <!-- Not equal to N of the following M items -->

          <!-- Note: does need a way to specify "not" -->

          <prereq [...] not="1" min="n" max="n">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

          <!-- Less than N of the following M items -->

          <prereq [...] max="n-1">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

          <!-- No more than N of the following M items -->

          <prereq [...] max="n">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

          <!-- More than N of the following M items -->

          <prereq [...] min="n+1">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

          <!-- No less than N of the following M items -->

          <prereq [...] min="n">

            <option 1 .../>

              [...]

            <option M .../>

          </prereq>

         

          PLUS it also easily handles

         

          <!-- between N and M of the following Q items -->

          <prereq [...] min="n" max="m">

            <option 1 .../>

              [...]

            <option Q .../>

          </prereq>

         

          <!-- less than N or more than M of the following Q items -->

          <!-- Note: also needs a way to specify "not" -->

          <prereq [...] not="1" min="n" max="m">

            <option 1 .../>

              [...]

            <option Q .../>

          </prereq>

         

        > It also allows for things like:

        >

        > <prereq kind="feat"

        >         key="weapon focus"

        >         operator=">="

        >         operand="2"

        >         countmultiples="true" />

        >

        > For "You must have taken weapon focus with at least 2 weapons.

         

          <prereq kind="feat" key="weapon-focus" min="2" countmult="1">

         

          ;-)

         

        Questions:

         

        To all:  Can we find a better name for an attribute than "countmultiples" or "countmult"?  They're both kind of long...

         

        To Frugal:  What is the "subkey" attribute meant to be used for?

         

        Jenni

         

        --

        Jenni A. M. Merrifield (strawberry @ jamm . com)

        Software User Experience Professional

        Designing to Requirements and walking on Water is EASY. . .

        . . . So long as both are Frozen.

        --

         

        --
        Jenni A. M. Merrifield (JenniM @ microsoft . com)
        User Experience PM - TrustBridge - Windows Security Core
        Designing to Requirements and walking on Water is EASY. . .
        . . . So long as both are Frozen.
        ----------
        E-Mail & WinIM: [jennim @ microsoft.com]
        V-Mail: [425/707-8150 (x78150)] | Fax: [425/936-7329]
        Office: [40/6213]
        --

         

      • Keith Davies
        ... heh, doublespaced, too... that s odd. ... Though this will fail if all three conditions are met; you ve implemented two and only two . The fix is pretty
        Message 3 of 29 , Apr 15, 2004
          On Thu, Apr 15, 2004 at 11:56:02AM -0700, Jenni Merrifield wrote:
          > {Bah. I apologize if this shows up twice - I tried to use the Yahoo!
          > "Post" function last night and even though it said it had been posted, I
          > don't see this or the other message I'm about to send on the web site.
          >
          > =JAMM}

          heh, doublespaced, too... that's odd.


          > <quote who="Frugal" when="Wed, 14 Apr, 2004 12:50 +0100 (BST)">
          >
          > > <quote who="Jenni A. Merrifield">
          >
          > > > Is there any particular reason, with this *internal* data
          > > > representation, to avoid using traditional Boolean operators
          > > > such as "AND", "OR", "XOR" and "NOT"? Using it, we could be
          > > > quite sure of what prerequisites were being requested and their
          > > > relationships to each other.
          > >
          > > There are 2 reasons I can think of:
          > >
          > > 1 - As you said yourself boolean logic is not easily comprehended
          > > by most people.
          >
          > True, but "most people" won't be working with the *internal* data
          > structure right? Programmers work with it, so *external* data can be
          > converted into it and it can be loaded by the application, but I'd be
          > willing to hazzard a guess that "most programmers" do understand boolean
          > logic.
          >
          > Nonetheless, Keith did make some very good arguments about his min/max
          > method and I would have to agree that it is more elegant, consistent,
          > and less complicated.
          >
          > > 2 - There are cases where boolean logic will not suffice. A prime
          > > example is "you must have 2 of these following 3 feats".
          >
          > Technically, "2 of the following 3 feats" is possible with strict
          > Boolean, although in a very long, annoying out manner:
          >
          > (A && B && !C) || (A && !B && C) || (!A && B && C)

          Though this will fail if all three conditions are met; you've
          implemented 'two and only two'. The fix is pretty obvious.

          This gets *really* ugly if the conditions are complex.

          > Of course, as Keith pointed out, adding a "select/pick/choose" option
          > would provide a more straightforward mechanism.
          >
          > Of course, he didn't bother to mention that such a "pick" option is
          > really identical to his basic min/max recommendation, as it defaults to
          > "AND" and can be used for "OR", "XOR" as well as all the other options
          > such as "n of m", "at least n", "no more than n", "between n and m". So
          > I agree with Keith - why implement it as Boolean logic when a min/max
          > implementation will do it all.
          >
          >
          > > I used the syntax of:
          > >
          > > <prereq kind=""
          > > key=""
          > > subkey=""
          > > operator="=,!=,<,<=,>,>="
          > > operand=""
          > > countmultiples="true|false" />
          > >
          > > Because it copes with every single case.
          >
          > True, but it also suffers from the need to do string comparisons just
          > like Boolean operands, whereas Keith's numerical method does not and is
          > (as he explained) more straightforward to implement.
          >
          > Each of your operators can also be acheived using his method:
          >
          > *** Frugal's operator method:
          >
          > <!-- Any N of the following M items -->
          > <prereq [...] operator="=" operand="n">
          > <option 1 .../>
          > [...]
          > <option M .../>
          > </prereq>
          >
          > <!-- Not equal to N of the following M items -->
          > <!-- Note: both < N and > N will be allowed -->
          >
          > <prereq [...] operator="!=" operand="n">
          > <option 1 .../>
          > [...]
          > <option M .../>
          > </prereq>
          >
          > <!-- Less than N of the following M items -->
          > <prereq [...] operator="<" operand="n">
          > <option 1 .../>
          > [...]
          > <option M .../>
          > </prereq>
          >
          > <!-- No more than N of the following M items -->
          > <prereq [...] operator="<=" operand="n">
          > <option 1 .../>
          > [...]
          > <option M .../>
          > </prereq>
          >
          > <!-- More than N of the following M items -->
          > <prereq [...] operator=">" operand="n">
          > <option 1 .../>
          > [...]
          > <option M .../>
          > </prereq>
          >
          > <!-- No less than N of the following M items -->
          > <prereq [...] operator=">=" operand="n">
          > <option 1 .../>
          > [...]
          > <option M .../>
          > </prereq>
          >
          >
          > *** Kieth's min/max method:
          >
          > <!-- Any N of the following M items -->
          > <prereq [...] min="n">
          > <option 1 .../>
          > [...]
          > <option M .../>
          > </prereq>
          >
          > <!-- Not equal to N of the following M items -->
          > <!-- Note: does need a way to specify "not" -->
          > <prereq [...] not="1" min="n" max="n">
          > <option 1 .../>
          > [...]
          > <option M .../>
          > </prereq>

          I don't see this case coming up, to be honest. If I were encoding such
          a thing (and the 'not' attribute wasn't there) I'd either lean toward an
          operator attribute (which I was *never* happy with, or just wrap it
          thus:

          <prereq max='0'>
          <prereq min='n' max='n'>
          <!-- n+m children -->
          </prereq>
          </prereq>

          or I might do

          <prereq min='1'>
          <prereq min='n+1' />
          <prereq max='n-1' />
          </prereq>

          Hmm... I think I like this one better, though I suppose it depends on
          how ugly the child lists are.

          These are a bit hackish and kludgey, but follows the simple model without
          introducing more. I try to design for the common case; something I
          don't *really* expect to happen, I don't mind having be a little more
          work.

          > <!-- Less than N of the following M items -->
          > <!-- No more than N of the following M items -->
          > <!-- More than N of the following M items -->
          > <!-- No less than N of the following M items -->
          >
          > PLUS it also easily handles
          >
          > <!-- between N and M of the following Q items -->

          All correct.

          > <!-- less than N or more than M of the following Q items -->
          > <!-- Note: also needs a way to specify "not" -->
          > <prereq [...] not="1" min="n" max="m">
          > <option 1 .../>
          > [...]
          > <option Q .../>
          > </prereq>

          We don't have '<option>' at this point, they're still <prereq>. Nit.

          As above, that can be split into two tests "((x < n) || (x > m))".

          It's a little odd, but I *might* consider allowing a special case where
          min > max, that it treats it in the way you're describing:

          <prereq min='m' max='n'>
          <!-- stuff -->
          </prereq>

          could be treated as equivalent to

          <prereq min='1'>
          <prereq min='m' />
          <prereq max='n' />
          </prereq>

          I don't *like* special cases, though.

          Does this sort of thing come up often enough to actually make it worth
          adding other operators, attributes, or special cases? I'm not
          specifically against doing so, but when something can and does do the
          job, I like to question changing it.

          > > It also allows for things like:
          > >
          > > <prereq kind="feat"
          > > key="weapon focus"
          > > operator=">="
          > > operand="2"
          > > countmultiples="true" />
          > >
          > > For "You must have taken weapon focus with at least 2 weapons.
          >
          > <prereq kind="feat" key="weapon-focus" min="2" countmult="1">

          'countmult'? I'm still not quite sure what that actually means.

          <prereq kind='feat' key='feat.weapon-focus' min='2' />

          means in my schema 'the entity has the Weapon Focus feat at least
          twice'.

          > Questions:
          >
          > To all: Can we find a better name for an attribute than
          > "countmultiples" or "countmult"? They're both kind of long...

          Attribute length isn't that important, I think. Long attributes are a
          bit inconvenient when typing, but meaningful names are more important.

          > To Frugal: What is the "subkey" attribute meant to be used for?

          Weapon Focus (Longsword), Spell Focus(Alteration), etc.

          key='feat.weapon-focus' means "Weapon Focus with some weapon"

          key='feat.weapon-focus' subkey='equip.longsword' means "Weapon Focus
          with longsword".


          Keith
          --
          Keith Davies I gave my 2yo daughter a strawberry
          keith.davies@... Naomi: "Strawberry!"
          me: "What do you say?"
          Naomi: "*MY* strawberry!"
        • Frugal
          ... It was to cope with prerequisites like: You must have a total of 20 ranks in jump , balance and Tumble combined.
          Message 4 of 29 , Apr 16, 2004
            <quote who="Keith Davies">
            > On Thu, Apr 15, 2004 at 11:56:02AM -0700, Jenni Merrifield wrote:
            >> <quote who="Frugal" when="Wed, 14 Apr, 2004 12:50 +0100 (BST)">
            >> > <quote who="Jenni A. Merrifield">
            >>
            >> > > Is there any particular reason, with this *internal* data
            >> > > representation, to avoid using traditional Boolean operators
            >> > > such as "AND", "OR", "XOR" and "NOT"? Using it, we could be
            >> > > quite sure of what prerequisites were being requested and their
            >> > > relationships to each other.
            >> >
            >> > There are 2 reasons I can think of:
            >> >
            >> > 1 - As you said yourself boolean logic is not easily comprehended
            >> > by most people.
            >>
            >> True, but "most people" won't be working with the *internal* data
            >> structure right? Programmers work with it, so *external* data can be
            >> converted into it and it can be loaded by the application, but I'd be
            >> willing to hazzard a guess that "most programmers" do understand boolean
            >> logic.
            >>
            >> Nonetheless, Keith did make some very good arguments about his min/max
            >> method and I would have to agree that it is more elegant, consistent,
            >> and less complicated.
            >>
            >> > 2 - There are cases where boolean logic will not suffice. A prime
            >> > example is "you must have 2 of these following 3 feats".
            >>
            >> Technically, "2 of the following 3 feats" is possible with strict
            >> Boolean, although in a very long, annoying out manner:
            >>
            >> (A && B && !C) || (A && !B && C) || (!A && B && C)
            >
            > Though this will fail if all three conditions are met; you've
            > implemented 'two and only two'. The fix is pretty obvious.
            >
            > This gets *really* ugly if the conditions are complex.
            >
            >> Of course, as Keith pointed out, adding a "select/pick/choose" option
            >> would provide a more straightforward mechanism.
            >>
            >> Of course, he didn't bother to mention that such a "pick" option is
            >> really identical to his basic min/max recommendation, as it defaults to
            >> "AND" and can be used for "OR", "XOR" as well as all the other options
            >> such as "n of m", "at least n", "no more than n", "between n and m". So
            >> I agree with Keith - why implement it as Boolean logic when a min/max
            >> implementation will do it all.
            >>
            >>
            >> > I used the syntax of:
            >> >
            >> > <prereq kind=""
            >> > key=""
            >> > subkey=""
            >> > operator="=,!=,<,<=,>,>="
            >> > operand=""
            >> > countmultiples="true|false" />
            >> >
            >> > Because it copes with every single case.
            >>
            >> True, but it also suffers from the need to do string comparisons just
            >> like Boolean operands, whereas Keith's numerical method does not and is
            >> (as he explained) more straightforward to implement.
            >>
            >> Each of your operators can also be acheived using his method:
            >>
            >> *** Frugal's operator method:
            >>
            >> <!-- Any N of the following M items -->
            >> <prereq [...] operator="=" operand="n">
            >> <option 1 .../>
            >> [...]
            >> <option M .../>
            >> </prereq>
            >>
            >> <!-- Not equal to N of the following M items -->
            >> <!-- Note: both < N and > N will be allowed -->
            >>
            >> <prereq [...] operator="!=" operand="n">
            >> <option 1 .../>
            >> [...]
            >> <option M .../>
            >> </prereq>
            >>
            >> <!-- Less than N of the following M items -->
            >> <prereq [...] operator="<" operand="n">
            >> <option 1 .../>
            >> [...]
            >> <option M .../>
            >> </prereq>
            >>
            >> <!-- No more than N of the following M items -->
            >> <prereq [...] operator="<=" operand="n">
            >> <option 1 .../>
            >> [...]
            >> <option M .../>
            >> </prereq>
            >>
            >> <!-- More than N of the following M items -->
            >> <prereq [...] operator=">" operand="n">
            >> <option 1 .../>
            >> [...]
            >> <option M .../>
            >> </prereq>
            >>
            >> <!-- No less than N of the following M items -->
            >> <prereq [...] operator=">=" operand="n">
            >> <option 1 .../>
            >> [...]
            >> <option M .../>
            >> </prereq>
            >>
            >>
            >> *** Kieth's min/max method:
            >>
            >> <!-- Any N of the following M items -->
            >> <prereq [...] min="n">
            >> <option 1 .../>
            >> [...]
            >> <option M .../>
            >> </prereq>
            >>
            >> <!-- Not equal to N of the following M items -->
            >> <!-- Note: does need a way to specify "not" -->
            >> <prereq [...] not="1" min="n" max="n">
            >> <option 1 .../>
            >> [...]
            >> <option M .../>
            >> </prereq>
            >
            > I don't see this case coming up, to be honest. If I were encoding such
            > a thing (and the 'not' attribute wasn't there) I'd either lean toward an
            > operator attribute (which I was *never* happy with, or just wrap it
            > thus:
            >
            > <prereq max='0'>
            > <prereq min='n' max='n'>
            > <!-- n+m children -->
            > </prereq>
            > </prereq>
            >
            > or I might do
            >
            > <prereq min='1'>
            > <prereq min='n+1' />
            > <prereq max='n-1' />
            > </prereq>
            >
            > Hmm... I think I like this one better, though I suppose it depends on
            > how ugly the child lists are.
            >
            > These are a bit hackish and kludgey, but follows the simple model without
            > introducing more. I try to design for the common case; something I
            > don't *really* expect to happen, I don't mind having be a little more
            > work.
            >
            >> <!-- Less than N of the following M items -->
            >> <!-- No more than N of the following M items -->
            >> <!-- More than N of the following M items -->
            >> <!-- No less than N of the following M items -->
            >>
            >> PLUS it also easily handles
            >>
            >> <!-- between N and M of the following Q items -->
            >
            > All correct.
            >
            >> <!-- less than N or more than M of the following Q items -->
            >> <!-- Note: also needs a way to specify "not" -->
            >> <prereq [...] not="1" min="n" max="m">
            >> <option 1 .../>
            >> [...]
            >> <option Q .../>
            >> </prereq>
            >
            > We don't have '<option>' at this point, they're still <prereq>. Nit.
            >
            > As above, that can be split into two tests "((x < n) || (x > m))".
            >
            > It's a little odd, but I *might* consider allowing a special case where
            > min > max, that it treats it in the way you're describing:
            >
            > <prereq min='m' max='n'>
            > <!-- stuff -->
            > </prereq>
            >
            > could be treated as equivalent to
            >
            > <prereq min='1'>
            > <prereq min='m' />
            > <prereq max='n' />
            > </prereq>
            >
            > I don't *like* special cases, though.
            >
            > Does this sort of thing come up often enough to actually make it worth
            > adding other operators, attributes, or special cases? I'm not
            > specifically against doing so, but when something can and does do the
            > job, I like to question changing it.
            >
            >> > It also allows for things like:
            >> >
            >> > <prereq kind="feat"
            >> > key="weapon focus"
            >> > operator=">="
            >> > operand="2"
            >> > countmultiples="true" />
            >> >
            >> > For "You must have taken weapon focus with at least 2 weapons.
            >>
            >> <prereq kind="feat" key="weapon-focus" min="2" countmult="1">
            >
            > 'countmult'? I'm still not quite sure what that actually means.
            >
            > <prereq kind='feat' key='feat.weapon-focus' min='2' />
            >
            > means in my schema 'the entity has the Weapon Focus feat at least
            > twice'.

            It was to cope with prerequisites like: You must have a total of 20 ranks
            in "jump", "balance" and "Tumble" combined.

            count-multiples="true" effectively means: Instead of returning '1' for
            pass and '0' for fail, return 'n' for pass and '0' for fail where 'n' is
            the total value of the prerequisite:

            <prereq min="20">
            <prereq kind="skill_rank" key="jump" min="1" count-multiples="true"/>
            <prereq kind="skill_rank" key="balance" min="1" count-multiples="true"/>
            <prereq kind="skill_rank" key="tumble" min="1" count-multiples="true"/>
            </prereq>

            --
            regards,
            Frugal
            -OS Chimp
          • Keith Davies
            ... [bigsnip] ... Ah, okay. ... Hmm... I m not sure like changing prereq semantics so they no longer return pass (true) or fail (false). ... I had a different
            Message 5 of 29 , Apr 16, 2004
              On Fri, Apr 16, 2004 at 09:48:16AM +0100, Frugal wrote:
              >
              > <quote who="Keith Davies">

              [bigsnip]

              > > 'countmult'? I'm still not quite sure what that actually means.
              > >
              > > <prereq kind='feat' key='feat.weapon-focus' min='2' />
              > >
              > > means in my schema 'the entity has the Weapon Focus feat at least
              > > twice'.
              >
              > It was to cope with prerequisites like: You must have a total of 20 ranks
              > in "jump", "balance" and "Tumble" combined.

              Ah, okay.

              > count-multiples="true" effectively means: Instead of returning '1' for
              > pass and '0' for fail, return 'n' for pass and '0' for fail where 'n' is
              > the total value of the prerequisite:

              Hmm... I'm not sure like changing prereq semantics so they no longer
              return pass (true) or fail (false).

              > <prereq min="20">
              > <prereq kind="skill_rank" key="jump" min="1" count-multiples="true"/>
              > <prereq kind="skill_rank" key="balance" min="1" count-multiples="true"/>
              > <prereq kind="skill_rank" key="tumble" min="1" count-multiples="true"/>
              > </prereq>

              I had a different syntax for this sort of thing, but buggered if I can
              remember what it was. Probably something like

              <prereq kind='cumulative-ranks' min='20'>
              <progression-ref key='skill.jump' />
              <progression-ref key='skill.balance' />
              <progression-ref key='skill.tumble' />
              </prereq>

              I know it wasn't progression-ref (I've never seen it before in my life,
              and it's a lousy name). Still, I think this probably represents the
              'cumulative total' behavior a little more clearly than by nesting
              prereqs with changed semantics.


              Keith
              --
              Keith Davies I gave my 2yo daughter a strawberry
              keith.davies@... Naomi: "Strawberry!"
              me: "What do you say?"
              Naomi: "*MY* strawberry!"
            • Jenni A. Merrifield
              {Double-Bah. I just realized this other message, which was actually written before either of my last two, never showed up on the list. If any of my comments
              Message 6 of 29 , Apr 16, 2004
                {Double-Bah. I just realized this other message, which was actually written
                before either of my last two, never showed up on the list. If any of my
                comments referring to my own previous comments seemed confusing, this might
                explain why. :-P }

                <quote who="Keith Davies" when="Tue, 13 Apr 2004 12:04:53 -0700">
                > On Tue, Apr 13, 2004 at 07:06:51AM -0700, Jenni A. Merrifield wrote:
                > >
                > > Is there any particular reason, with this *internal* data
                > > representation, to avoid using traditional Boolean operators such as
                > > "AND", "OR", "XOR" and "NOT"? Using it, we could be quite sure of what
                > > prerequisites were being requested and their relationships to each other.
                >
                > I'd be willing to use this for the external data representation; I was
                > using 'min' and 'max' to allow for 'at least two of the following' (or
                > 'no more than two of the following', for that matter) cases. The same
                > mechanism would successfully deal with the cases described below, so I
                > didn't bother pursuing your suggestion (I *did* think of it, but numbers
                > served the same purpose across more cases).

                [...SNIP...]

                > Your suggestion is probably simpler in most cases; I'd be willing to use
                > it. The only thing it fails to handle (as written) is the 'n of m'
                > case, and even that can be handled by another operand
                >
                > <prereq kind='mult' operand='select' min='2'>
                > <prereq kind='alignment' key='lawful.good' />
                > <prereq kind='feat' key='feat.eschew-materials' />
                > <prereq kind='feat' key='feat.silent-spell' />
                > </prereq>
                >
                > 'select' is a lousy operand name, need a better one.

                How about one of:

                * "selection"
                * "pick" <-- I like this one
                * "choose" <-- this would be familiar to LST writers
                * "choice"
                * "subset"

                > Still, I like the numbers version better -- it's a little clearer what's
                > going on and can be implemented using a single chain of logic:
                >
                > min = numChildren;
                > max = numChildren;
                > if (minSet) {
                > min = attribs.getAttrib( "min");
                > }
                > if (maxSet) {
                > max = attribs.getAttrib( "max");
                > }
                > childrenMatched = checkPrereqs( entity, children);
                > if ((min <= childrenMatched) &&
                > (childrenMatched <= max)) {
                > doWePassed();
                > } else {
                > doWeFailed();
                > }
                >
                > This does not require string examination of the operand attribute, nor
                > the logic necessary to handle the various cases.

                Your algorithmic argument is a fairly good one - the lack of a need to do
                string examination would probably make it somewhat more performant.

                > The 'and' case is
                > implicit (if min and max aren't set, it requires all children to pass),
                > the 'or' case is handled as '1 of m', and it handles both 'n of m' and
                > 'no more than n of m' cases consistently.

                With Boolean terms "and" would still be implicit if there is no operator
                and no min or max. In addition "pick"/"choose" is almost implicit if there
                is no operator but there is a min and/or a max (e.g., a subset of the options
                must apply for the prereq to apply)

                > I'd be willing to use 'and' or 'or' operands, but this is, IMO, more
                > elegant, consistent, and simpler to implement and use.

                Perhaps you are right. It would definitely seem to be more consistent.

                Two remaining questions:

                1) How does one negate the numerical version for prerequisites? I can think
                of three options:

                A. A "not" or "inv" attribute set to "1" when it applies:

                <!-- Not this -->
                <prereq kind='feat' inv='1' key='feat.eschew-materials' />

                <!-- Not both -->
                <prereq kind='mult' inv='1'>
                <prereq kind='feat' key='feat.eschew-materials' />
                <prereq kind='feat' key='feat.silent-spell' />
                </prereq>

                <!-- Neither -->
                <prereq kind='mult' min='1' max='1' inv='1'>
                <prereq kind='feat' key='feat.eschew-materials' />
                <prereq kind='feat' key='feat.silent-spell' />
                </prereq>

                <!-- No more than two -->
                <prereq kind='mult' min='2' inv='1'>
                <prereq kind='feat' key='feat.enlarge-spell' />
                <prereq kind='feat' key='feat.eschew-materials' />
                <prereq kind='feat' key='feat.silent-spell' />
                </prereq>


                B. A "kind" attribute with the value "not"

                <!-- Not this -->
                <prereq kind='not'>
                <prereq kind='feat' inv='1' key='feat.eschew-materials' />
                </prereq>

                <!-- Not Both -->
                <prereq kind='not'>
                <prereq kind='mult'>
                <prereq kind='feat' key='feat.eschew-materials' />
                <prereq kind='feat' key='feat.silent-spell' />
                </prereq>
                </prereq>

                <!-- Neither -->
                <prereq kind='not'>
                <prereq kind='mult' min='1' max='1'>
                <prereq kind='feat' key='feat.eschew-materials' />
                <prereq kind='feat' key='feat.silent-spell' />
                </prereq>
                </prereq>

                <!-- No more than two -->
                <prereq kind='not'>
                <prereq kind='mult' min='2'>
                <prereq kind='feat' key='feat.enlarge-spell' />
                <prereq kind='feat' key='feat.eschew-materials' />
                <prereq kind='feat' key='feat.silent-spell' />
                </prereq>
                </prereq>


                C. Adding ".inv" to the "kind" attribute

                <!-- Not this -->
                <prereq kind='feat.inv' key='feat.eschew-materials' />

                <!-- Not both -->
                <prereq kind='mult.inv'>
                <prereq kind='feat' key='feat.eschew-materials' />
                <prereq kind='feat' key='feat.silent-spell' />
                </prereq>

                <!-- Neither -->
                <prereq kind='mult.inv' min='1' max='1'>
                <prereq kind='feat' key='feat.eschew-materials' />
                <prereq kind='feat' key='feat.silent-spell' />
                </prereq>

                <!-- No more than two -->
                <prereq kind='mult.inv' min='2'>
                <prereq kind='feat' key='feat.enlarge-spell' />
                <prereq kind='feat' key='feat.eschew-materials' />
                <prereq kind='feat' key='feat.silent-spell' />
                </prereq>


                2) How would one achieve the Boolean XOR -- e.g., A || B && !(A && B); one or
                the other but not both -- using the numerical method? Would it have to be
                written the long way, as follows (I'm using option C for NOT) or is there an
                easier way that I'm overlooking:

                <prereq kind='mult'>
                <prereq kind='mult' min="1" max="1">
                <prereq kind='feat' key='feat.eschew-materials' />
                <prereq kind='feat' key='feat.silent-spell' />
                </prereq>
                <prereq kind='mult.inv'>
                <prereq kind='feat' key='feat.eschew-materials' />
                <prereq kind='feat' key='feat.silent-spell' />
                </prereq>
                </prereq>

                Jenni

                --
                Jenni A. M. Merrifield (strawberry @ jamm . com)
                Software User Experience Professional
                Designing to Requirements and walking on Water is EASY. . .
                . . . So long as both are Frozen.
                --
              • Jenni A. Merrifield
                {Oh man....} {Resending with a subject and some comments I left off the end.} {I m really not having much luck with this list lately, am I? :-P}
                Message 7 of 29 , Apr 17, 2004
                  {Oh man....}

                  {Resending with a subject and some comments I left off the end.}

                  {I'm really not having much luck with this list lately, am I? :-P}


                  <quote who="Keith Davies" when="Fri, 16 Apr, 2004 07:23:33 -0700">
                  > On Fri, Apr 16, 2004 at 09:48:16AM +0100, Frugal wrote:
                  > >
                  > > <quote who="Keith Davies">
                  >
                  > [bigsnip]
                  >
                  > > > 'countmult'? I'm still not quite sure what that actually means.
                  > > >
                  > > > <prereq kind='feat' key='feat.weapon-focus' min='2' />
                  > > >
                  > > > means in my schema 'the entity has the Weapon Focus feat at least
                  > > > twice'.
                  > >
                  > > It was to cope with prerequisites like: You must have a total of 20
                  > > ranks in "jump", "balance" and "Tumble" combined.
                  >
                  > Ah, okay.
                  >
                  > > count-multiples="true" effectively means: Instead of returning '1' for
                  > > pass and '0' for fail, return 'n' for pass and '0' for fail where 'n' is
                  > > the total value of the prerequisite:
                  >
                  > Hmm... I'm not sure like changing prereq semantics so they no longer
                  > return pass (true) or fail (false).

                  I would tend to agree. Among User Experience Professionals a guideline we
                  try to enforce is that anything which means one thing in a particular context
                  may only be used in a different context if it will mean exactly the same
                  thing there. Allowing it to be used in a context where it would end up with
                  a different meaning (even only a slightly different meaning) engenders
                  confusion and increases the risk of errors occurring while users are
                  interacting with it.

                  Most UX guidelines have been developed over time based on facts around
                  human physiology and psychology, applicable to all humans - including
                  developers as well as end users. So, if you accept than an XML schema (or an
                  API, a programming language, &c) is a piece of the developer "user
                  experience" then this guideline is one that is worth remembering. ;-)

                  > > <prereq min="20">
                  > > <prereq kind="skill_rank" key="jump" min="1" count-multiples="true"/>
                  > > <prereq kind="skill_rank" key="balance" min="1" count-
                  > > multiples="true"/>
                  > > <prereq kind="skill_rank" key="tumble" min="1" count-
                  > > multiples="true"/>
                  > > </prereq>
                  >
                  > I had a different syntax for this sort of thing, but buggered if I can
                  > remember what it was. Probably something like
                  >
                  > <prereq kind='cumulative-ranks' min='20'>
                  > <progression-ref key='skill.jump' />
                  > <progression-ref key='skill.balance' />
                  > <progression-ref key='skill.tumble' />
                  > </prereq>
                  >
                  > I know it wasn't progression-ref (I've never seen it before in my life,
                  > and it's a lousy name). Still, I think this probably represents the
                  > 'cumulative total' behavior a little more clearly than by nesting
                  > prereqs with changed semantics.

                  Couldn't we do this with additional prereq tags with a kind sent to
                  'skill-rank', and allowing min and max to set limits on how few/man each
                  skill is allowed to supply to the total?

                  Eg: At least 20 cumulative ranks (total-ranks?) from the specified skills,
                  with at least 4 ranks and no more than 10 coming from each one:

                  <prereq kind='cumulative-ranks' min='20'>
                  <prereq kind='skill-ranks' key='skill.jump' min='4' max='10' />
                  <prereq kind='skill-ranks' key='skill.balance' min='4' max='10' />
                  <prereq kind='skill-ranks' key='skill.tumble' min='4' max='10' />
                  </prereq>

                  This is then similar to the format that would be used to set a prerequisite
                  that required at least N ranks in any M of the specified skills:

                  Eg: At least 10 ranks in at least one of the specified skills:

                  <prereq kind='mult' min='1' max='1'>
                  <prereq kind='skill-ranks' key='skill.jump' min='10' />
                  <prereq kind='skill-ranks' key='skill.balance' min='10' />
                  <prereq kind='skill-ranks' key='skill.tumble' min='10' />
                  </prereq>

                  Jenni

                  --
                  Jenni A. M. Merrifield (strawberry @ jamm . com)
                  Software User Experience Professional
                  Designing to Requirements and walking on Water is EASY. . .
                  . . . So long as both are Frozen.
                  --
                • Jenni A.M. Merrifield
                  ... I realized I made an error when I tried to give negation examples for not more than two . That is best accomplished without needing a negation anyway:
                  Message 8 of 29 , Apr 17, 2004
                    > 1) How does one negate the numerical version for prerequisites? I
                    > can think of three options:

                    I realized I made an error when I tried to give "negation"
                    examples for "not more than two". That is best accomplished without
                    needing a negation anyway:

                    <!-- No more than two -->
                    <prereq kind='mult' max='2'>
                    <prereq kind='feat' key='feat.enlarge-spell' />
                    <prereq kind='feat' key='feat.eschew-materials' />
                    <prereq kind='feat' key='feat.heighten-spell' />
                    <prereq kind='feat' key='feat.silent-spell' />
                    </prereq>


                    --
                    Jenni A. M. Merrifield (strawberry @ jamm . com)
                    Software User Experience Professional
                    Designing to Requirements and walking on Water is EASY. . .
                    . . . So long as both are Frozen.
                    --
                  • Frugal
                    ... So instead of a common case where always evaulates to an integer and can only contain objects you want to move
                    Message 9 of 29 , Apr 19, 2004
                      <quote who="Keith Davies">
                      > I had a different syntax for this sort of thing, but buggered if I can
                      > remember what it was. Probably something like
                      >
                      > <prereq kind='cumulative-ranks' min='20'>
                      > <progression-ref key='skill.jump' />
                      > <progression-ref key='skill.balance' />
                      > <progression-ref key='skill.tumble' />
                      > </prereq>

                      So instead of a common case where <prereq> always evaulates to an integer
                      and can only contain <prereq> objects you want to move to a system where
                      <prereq> always returns true/false but can contain an arbitrary number of
                      any element.

                      This is exactly what I was trying to get away from, going down this road
                      is what led to the dogs dinner that is the current LST syntax.

                      --
                      regards,
                      Frugal
                      -OS Chimp
                    • Frugal
                      ... No. You can not define to evaluate to {true|false} and then get a minimum of 20 from 3 elements. What
                      Message 10 of 29 , Apr 19, 2004
                        <quote who="Jenni A. Merrifield">
                        > Couldn't we do this with additional prereq tags with a kind sent to
                        > 'skill-rank', and allowing min and max to set limits on how few/man each
                        > skill is allowed to supply to the total?
                        >
                        > Eg: At least 20 cumulative ranks (total-ranks?) from the specified
                        > skills,
                        > with at least 4 ranks and no more than 10 coming from each one:
                        >
                        > <prereq kind='cumulative-ranks' min='20'>
                        > <prereq kind='skill-ranks' key='skill.jump' min='4' max='10' />
                        > <prereq kind='skill-ranks' key='skill.balance' min='4' max='10' />
                        > <prereq kind='skill-ranks' key='skill.tumble' min='4' max='10' />
                        > </prereq>

                        No. You can not define <prereq> to evaluate to {true|false} and then get a
                        minimum of "20" from 3 <prereq> elements.

                        What you presented will evaulate to:
                        <prereq kind="cumulative-ranks" min="30">
                        <true|false>
                        <true|false>
                        <true|false>
                        </prereq>

                        How do you propose to get a min of "30" cumulative ranks from 3 true/false
                        values.

                        What you are trying to do is exactly the same thing that I did exlpicitly,
                        but you are trying to do do it by side effect.

                        --
                        regards,
                        Frugal
                        -OS Chimp
                      • Jenni A. Merrifield
                        Message 11 of 29 , Apr 19, 2004
                          <quote who="Frugal" when="Mon, 19 Apr 2004 09:04:47 +0100 (BST)"
                          > <quote who="Jenni A. Merrifield">
                          > > Couldn't we do this with additional prereq tags with a kind sent to
                          > > 'skill-rank', and allowing min and max to set limits on how few/man each
                          > > skill is allowed to supply to the total?
                          > >
                          > > Eg: At least 20 cumulative ranks (total-ranks?) from the specified
                          > > skills,
                          > > with at least 4 ranks and no more than 10 coming from each one:
                          > >
                          > > <prereq kind='cumulative-ranks' min='20'>
                          > > <prereq kind='skill-ranks' key='skill.jump' min='4' max='10' />
                          > > <prereq kind='skill-ranks' key='skill.balance' min='4' max='10' />
                          > > <prereq kind='skill-ranks' key='skill.tumble' min='4' max='10' />
                          > > </prereq>
                          >
                          > No. You can not define <prereq> to evaluate to {true|false} and then get a
                          > minimum of "20" from 3 <prereq> elements.
                          >
                          > What you presented will evaulate to:
                          > <prereq kind="cumulative-ranks" min="30">
                          > <true|false>
                          > <true|false>
                          > <true|false>
                          > </prereq>
                          >
                          > How do you propose to get a min of "30" cumulative ranks from 3 true/false
                          > values.

                          D'oh! Despite reading Keith's previous email about "always true/false" I
                          was still expecting numerical values to be output from the prereq tags.

                          Keith: In a true/false context, usually any value != 0 is considered
                          "false". Thus, even if a prereq tag *does* return an appropriate count
                          (number of times a character has the feat, the number of ranks held in a
                          skill, &c. -- basically whatever was appropriate) whenever the stated
                          prerequisite was met and always returns a zero value whenever the
                          prerequisite wasn't met, it can still be evaluated as "true/false" if that's
                          all that mattered (i.e., does or doesn't the character meet the prereq).
                          However, this also allows (as in the example above) cumulative scores when
                          that's what matters.

                          This would keeps the syntax consistent across the board: prereq always
                          contains prereq (avoiding the "dogs dinner" of LST syntax as you so aptly put
                          it), eliminates the need for any "countmultiples" attribute (multiples are
                          always counted) AND if all you want is true/false you just ignore the
                          magnitude of a succesful return values in most cases (where all that matters
                          is "is it false (0) or is it true (not 0)").

                          What do you think?

                          Jenni

                          --
                          Jenni A. M. Merrifield (strawberry @ jamm . com)
                          Software User Experience Professional
                          Designing to Requirements and walking on Water is EASY. . .
                          . . . So long as both are Frozen.
                          --
                        • Brass Tilde
                          ... Did you mean to say true there? Unless usually doesn t include languages such as C/C++, where zero is false and non-zero is true. Or did I
                          Message 12 of 29 , Apr 19, 2004
                            > Keith: In a true/false context, usually any value != 0 is considered
                            > "false".

                            Did you mean to say "true" there? Unless "usually" doesn't include
                            languages such as C/C++, where zero is false and non-zero is true.

                            Or did I misinterpret?
                          • Frugal
                            ... Which takes us back to the way I originally proposed that everyone disliked ;O) ... You still need to have a flag to
                            Message 13 of 29 , Apr 19, 2004
                              <quote who="Jenni A. Merrifield">
                              > <quote who="Frugal" when="Mon, 19 Apr 2004 09:04:47 +0100 (BST)"
                              >> No. You can not define <prereq> to evaluate to {true|false} and then get
                              >> a
                              >> minimum of "20" from 3 <prereq> elements.
                              >>
                              >> What you presented will evaulate to:
                              >> <prereq kind="cumulative-ranks" min="30">
                              >> <true|false>
                              >> <true|false>
                              >> <true|false>
                              >> </prereq>
                              >>
                              >> How do you propose to get a min of "30" cumulative ranks from 3
                              >> true/false
                              >> values.
                              >
                              > D'oh! Despite reading Keith's previous email about "always true/false"
                              > I
                              > was still expecting numerical values to be output from the prereq tags.
                              >
                              > Keith: In a true/false context, usually any value != 0 is considered
                              > "false". Thus, even if a prereq tag *does* return an appropriate count
                              > (number of times a character has the feat, the number of ranks held in a
                              > skill, &c. -- basically whatever was appropriate) whenever the stated
                              > prerequisite was met and always returns a zero value whenever the
                              > prerequisite wasn't met, it can still be evaluated as "true/false" if
                              > that's
                              > all that mattered (i.e., does or doesn't the character meet the prereq).
                              > However, this also allows (as in the example above) cumulative scores when
                              > that's what matters.

                              Which takes us back to the way I originally proposed that everyone
                              disliked ;O)

                              > This would keeps the syntax consistent across the board: prereq always
                              > contains prereq (avoiding the "dogs dinner" of LST syntax as you so aptly
                              > put
                              > it), eliminates the need for any "countmultiples" attribute (multiples are
                              > always counted) AND if all you want is true/false you just ignore the
                              > magnitude of a succesful return values in most cases (where all that
                              > matters
                              > is "is it false (0) or is it true (not 0)").

                              You still need to have a flag to count the multiples otherwise it is
                              impossible to tell the difference between

                              <!-- at least 20 ranks in total in Balance, Jump and Climb -->
                              <prereq kind="mult" operator="gteq" operand="20">
                              <prereq kind="skill.ranks" key="balance" operator="gteq" operand="1"/>
                              <prereq kind="skill.ranks" key="climb" operator="gteq" operand="1"/>
                              <prereq kind="skill.ranks" key="jump" operator="gteq" operand="1"/>
                              </prereq>

                              and

                              <!-- must have ranks in at least 2 of Balance, Jump or Climb -->
                              <prereq kind="mult" operator="gteq" operand="2">
                              <prereq kind="skill.ranks" key="balance" operator="gteq" operand="1"/>
                              <prereq kind="skill.ranks" key="climb" operator="gteq" operand="1"/>
                              <prereq kind="skill.ranks" key="jump" operator="gteq" operand="1"/>
                              </prereq>


                              If you always return multiples then you can pass the second one by having
                              at least 2 ranks in a 1 skill rather than by having at least 1 rank in at
                              least 2 skills. If you always return 0/1 then you can never satisfy the
                              first example...

                              --
                              regards,
                              Frugal
                              -OS Chimp
                            • Keith Davies
                              ... I think you contradicted yourself above (I split the paragraphs to make it more evident). 0 is often interpreted as false, non-zero as true. ... I never
                              Message 14 of 29 , Apr 19, 2004
                                On Mon, Apr 19, 2004 at 07:13:18AM -0700, Jenni A. Merrifield wrote:
                                > <quote who="Frugal" when="Mon, 19 Apr 2004 09:04:47 +0100 (BST)"
                                > > <quote who="Jenni A. Merrifield">
                                > > > Couldn't we do this with additional prereq tags with a kind sent to
                                > > > 'skill-rank', and allowing min and max to set limits on how few/man each
                                > > > skill is allowed to supply to the total?
                                > > >
                                > > > Eg: At least 20 cumulative ranks (total-ranks?) from the specified
                                > > > skills,
                                > > > with at least 4 ranks and no more than 10 coming from each one:
                                > > >
                                > > > <prereq kind='cumulative-ranks' min='20'>
                                > > > <prereq kind='skill-ranks' key='skill.jump' min='4' max='10' />
                                > > > <prereq kind='skill-ranks' key='skill.balance' min='4' max='10' />
                                > > > <prereq kind='skill-ranks' key='skill.tumble' min='4' max='10' />
                                > > > </prereq>
                                > >
                                > > No. You can not define <prereq> to evaluate to {true|false} and then get a
                                > > minimum of "20" from 3 <prereq> elements.
                                > >
                                > > What you presented will evaulate to:
                                > > <prereq kind="cumulative-ranks" min="30">
                                > > <true|false>
                                > > <true|false>
                                > > <true|false>
                                > > </prereq>
                                > >
                                > > How do you propose to get a min of "30" cumulative ranks from 3 true/false
                                > > values.
                                >
                                > D'oh! Despite reading Keith's previous email about "always
                                > true/false" I was still expecting numerical values to be output from
                                > the prereq tags.
                                >
                                > Keith: In a true/false context, usually any value != 0 is considered
                                > "false".
                                >
                                > Thus, even if a prereq tag *does* return an appropriate count (number
                                > of times a character has the feat, the number of ranks held in a
                                > skill, &c. -- basically whatever was appropriate) whenever the stated
                                > prerequisite was met and always returns a zero value whenever the
                                > prerequisite wasn't met, it can still be evaluated as "true/false" if
                                > that's all that mattered (i.e., does or doesn't the character meet the
                                > prereq). However, this also allows (as in the example above)
                                > cumulative scores when that's what matters.

                                I think you contradicted yourself above (I split the paragraphs to make
                                it more evident). 0 is often interpreted as false, non-zero as true.

                                > This would keeps the syntax consistent across the board: prereq
                                > always contains prereq (avoiding the "dogs dinner" of LST syntax as
                                > you so aptly put it), eliminates the need for any "countmultiples"
                                > attribute (multiples are always counted) AND if all you want is
                                > true/false you just ignore the magnitude of a succesful return
                                > values in most cases (where all that matters is "is it false (0) or
                                > is it true (not 0)").

                                I never called it a dogs dinner. I don't disagree, but someone else
                                said that.

                                > What do you think?

                                As a predominantly C++ programmer and Perl scripter I am comfortable
                                with the idea of 0/non-0 examination for false/true. However, in this
                                model <prereq> is doing two things, and now neither of them is
                                particularly obvious.

                                0/non-0 examination, while easy for many people to understand, is not as
                                obvious as false/true values (that's why Java got rid of implicit
                                conversion of int to boolean). Also, you now have prereqs performing
                                calculations; that's not what they're for, but people will use them that
                                way.

                                Two non-obvious things. One of them can do what was originally
                                intended, but with an extra step that could be overlooked. At this
                                point I don't think it is the correct way to go. I am willing to
                                reconsider if someone presents a convincing argument.

                                Personally, I'd rather see

                                <prereq kind='cumulative' min='20'>
                                <count kind='skill-ranks' key='skill.jump' />
                                <count kind='skill-ranks' key='skill.balance' />
                                <count kind='skill-ranks' key='skill.tumble' />
                                </prereq>

                                If there are further requirements (such as 'each skill must have at
                                least four and no more than ten ranks') then treat those as separate
                                prereqs:

                                <prereq kind='mult'>
                                <prereq kind='cumulative' min='20'>
                                <count kind='skill-ranks' key='skill.jump' />
                                <count kind='skill-ranks' key='skill.balance' />
                                <count kind='skill-ranks' key='skill.tumble' />
                                </prereq>
                                <prereq kind='skill-ranks' key='skill.jump' min='4' max='10' />
                                <prereq kind='skill-ranks' key='skill.balance' min='4' max='10' />
                                <prereq kind='skill-ranks' key='skill.tumble' min='4' max='10' />
                                </prereq>

                                This keeps the semantics of each element fairly simple. This looks like
                                a very odd case here, and I don't like to complicate the general model
                                to make it more convenient -- but less clear -- to encode something I
                                don't expect to happen.


                                Keith
                                --
                                Keith Davies I gave my 2yo daughter a strawberry
                                keith.davies@... Naomi: "Strawberry!"
                                me: "What do you say?"
                                Naomi: "*MY* strawberry!"
                              • Keith Davies
                                ... Misspoke, I think. She was pretty consistent about 0 == false, !0 == true later. Keith -- Keith Davies I gave my 2yo daughter a strawberry
                                Message 15 of 29 , Apr 19, 2004
                                  On Mon, Apr 19, 2004 at 10:21:28AM -0400, Brass Tilde wrote:
                                  > > Keith: In a true/false context, usually any value != 0 is considered
                                  > > "false".
                                  >
                                  > Did you mean to say "true" there? Unless "usually" doesn't include
                                  > languages such as C/C++, where zero is false and non-zero is true.
                                  >
                                  > Or did I misinterpret?

                                  Misspoke, I think. She was pretty consistent about 0 == false,
                                  !0 == true later.


                                  Keith
                                  --
                                  Keith Davies I gave my 2yo daughter a strawberry
                                  keith.davies@... Naomi: "Strawberry!"
                                  me: "What do you say?"
                                  Naomi: "*MY* strawberry!"
                                • Keith Davies
                                  ... in her example. It is flagged. ... Her example would work. It s predicated on the always returning a
                                  Message 16 of 29 , Apr 19, 2004
                                    On Mon, Apr 19, 2004 at 03:25:51PM +0100, Frugal wrote:
                                    > <quote who="Jenni A. Merrifield">
                                    > > <quote who="Frugal" when="Mon, 19 Apr 2004 09:04:47 +0100 (BST)"
                                    > >> No. You can not define <prereq> to evaluate to {true|false} and then get
                                    > >> a
                                    > >> minimum of "20" from 3 <prereq> elements.
                                    > >>
                                    > >> What you presented will evaulate to:
                                    > >> <prereq kind="cumulative-ranks" min="30">
                                    > >> <true|false>
                                    > >> <true|false>
                                    > >> <true|false>
                                    > >> </prereq>
                                    > >>
                                    > >> How do you propose to get a min of "30" cumulative ranks from 3
                                    > >> true/false
                                    > >> values.
                                    > >
                                    > > D'oh! Despite reading Keith's previous email about "always true/false"
                                    > > I
                                    > > was still expecting numerical values to be output from the prereq tags.
                                    > >
                                    > > Keith: In a true/false context, usually any value != 0 is considered
                                    > > "false". Thus, even if a prereq tag *does* return an appropriate count
                                    > > (number of times a character has the feat, the number of ranks held in a
                                    > > skill, &c. -- basically whatever was appropriate) whenever the stated
                                    > > prerequisite was met and always returns a zero value whenever the
                                    > > prerequisite wasn't met, it can still be evaluated as "true/false" if
                                    > > that's
                                    > > all that mattered (i.e., does or doesn't the character meet the prereq).
                                    > > However, this also allows (as in the example above) cumulative scores when
                                    > > that's what matters.
                                    >
                                    > Which takes us back to the way I originally proposed that everyone
                                    > disliked ;O)
                                    >
                                    > > This would keeps the syntax consistent across the board: prereq always
                                    > > contains prereq (avoiding the "dogs dinner" of LST syntax as you so aptly
                                    > > put
                                    > > it), eliminates the need for any "countmultiples" attribute (multiples are
                                    > > always counted) AND if all you want is true/false you just ignore the
                                    > > magnitude of a succesful return values in most cases (where all that
                                    > > matters
                                    > > is "is it false (0) or is it true (not 0)").
                                    >
                                    > You still need to have a flag to count the multiples otherwise it is
                                    > impossible to tell the difference between
                                    >
                                    > <!-- at least 20 ranks in total in Balance, Jump and Climb -->
                                    > <prereq kind="mult" operator="gteq" operand="20">
                                    > <prereq kind="skill.ranks" key="balance" operator="gteq" operand="1"/>
                                    > <prereq kind="skill.ranks" key="climb" operator="gteq" operand="1"/>
                                    > <prereq kind="skill.ranks" key="jump" operator="gteq" operand="1"/>
                                    > </prereq>

                                    <prereq kind='cumulative-ranks' min='20' />

                                    in her example. It is flagged.

                                    > and
                                    >
                                    > <!-- must have ranks in at least 2 of Balance, Jump or Climb -->
                                    > <prereq kind="mult" operator="gteq" operand="2">
                                    > <prereq kind="skill.ranks" key="balance" operator="gteq" operand="1"/>
                                    > <prereq kind="skill.ranks" key="climb" operator="gteq" operand="1"/>
                                    > <prereq kind="skill.ranks" key="jump" operator="gteq" operand="1"/>
                                    > </prereq>
                                    >
                                    > If you always return multiples then you can pass the second one by having
                                    > at least 2 ranks in a 1 skill rather than by having at least 1 rank in at
                                    > least 2 skills. If you always return 0/1 then you can never satisfy the
                                    > first example...

                                    Her example would work. It's predicated on the <prereq> always
                                    returning a numerical value that can be examined to determine the truth
                                    of the <prereq>. How these are interpreted depends on the parent.

                                    If parent/@kind is 'mult' it looks at the truth of the children and
                                    counts. If parent/@kind is 'cumulative-ranks' it adds up the value of
                                    the children and examines the total. It presumably passes that total
                                    on.

                                    Ewww... if the test fails it must by definition return 0, but if not has
                                    the option of passing back 1 (true) or the cumulative number of ranks
                                    (20+). Anyone else see people abusing this function and complaining
                                    when it doesn't work right?

                                    As far as I know, <prereq> will work correctly if it returns true or
                                    false only for *all* cases except when nested for the purpose of
                                    determining cumulative totals. When examining cumulative totals,
                                    though, the individual values that go into are not prerequisites but
                                    operands; they do not themselves have true or false values, just numeric
                                    (which can be interpreted as true and false under some circumstances, I
                                    know). That the example shows them also being used as actual prereqs
                                    (4 <= ranks <= 10) I think confuses the matter, as the model is showing
                                    it being used for two things at once, rather than splitting them.

                                    The English text of the combination might be:

                                    "At least 20 ranks in Balance, Jump, and Tumble, with at least four
                                    ranks and no more than ten ranks in each."

                                    This is most cleanly encoded as two (sets of) prereqs. The first
                                    handles the first clause:

                                    <prereq kind='cumulative' min='20'>
                                    <value kind='skill-ranks' key='skill.balance' />
                                    <value kind='skill-ranks' key='skill.jump' />
                                    <value kind='skill-ranks' key='skill.tumble' />
                                    </prereq>

                                    and the second handles the second clause:

                                    <prereq kind='skill-ranks' key='skill.balance' min='4' max='10' />
                                    <prereq kind='skill-ranks' key='skill.jump' min='4' max='10' />
                                    <prereq kind='skill-ranks' key='skill.tumble' min='4' max='10' />

                                    This provides the cleanest encoding of the information and the clearest,
                                    with no overloading of terms or element interpretation.


                                    Keith
                                    --
                                    Keith Davies I gave my 2yo daughter a strawberry
                                    keith.davies@... Naomi: "Strawberry!"
                                    me: "What do you say?"
                                    Naomi: "*MY* strawberry!"
                                  • Keith Davies
                                    ... In the absence of a better way of describing this sort of prerequisite, I m willing to bend on prereqs contain only prereqs , if it is necessary to encode
                                    Message 17 of 29 , Apr 19, 2004
                                      On Mon, Apr 19, 2004 at 08:59:38AM +0100, Frugal wrote:
                                      > <quote who="Keith Davies">
                                      > > I had a different syntax for this sort of thing, but buggered if I can
                                      > > remember what it was. Probably something like
                                      > >
                                      > > <prereq kind='cumulative-ranks' min='20'>
                                      > > <progression-ref key='skill.jump' />
                                      > > <progression-ref key='skill.balance' />
                                      > > <progression-ref key='skill.tumble' />
                                      > > </prereq>
                                      >
                                      > So instead of a common case where <prereq> always evaulates to an integer
                                      > and can only contain <prereq> objects you want to move to a system where
                                      > <prereq> always returns true/false but can contain an arbitrary number of
                                      > any element.
                                      >
                                      > This is exactly what I was trying to get away from, going down this road
                                      > is what led to the dogs dinner that is the current LST syntax.

                                      In the absence of a better way of describing this sort of prerequisite,
                                      I'm willing to bend on 'prereqs contain only prereqs', if it is
                                      necessary to encode this sort of thing. I don't want to allow 'any'
                                      element, but allowing <prereq> to contain an element that can do what
                                      <prereq> is designed not to... while it should be avoided when possible,
                                      should not be outright verboten, I think.

                                      And yes, I know that the two examples I posted today use different names
                                      for the child element. I've got a cold.


                                      Keith
                                      --
                                      Keith Davies I gave my 2yo daughter a strawberry
                                      keith.davies@... Naomi: "Strawberry!"
                                      me: "What do you say?"
                                      Naomi: "*MY* strawberry!"
                                    • Keith Davies
                                      ... It fails, though, if only max is set (oops). I need something like if (minSet) { min = attribs.getAttrib( min ); } if (maxSet) { max = attribs.getAttrib(
                                      Message 18 of 29 , Apr 19, 2004
                                        On Fri, Apr 16, 2004 at 06:46:32PM -0700, Jenni A. Merrifield wrote:
                                        > {Double-Bah. I just realized this other message, which was actually written
                                        > before either of my last two, never showed up on the list. If any of my
                                        > comments referring to my own previous comments seemed confusing, this might
                                        > explain why. :-P }
                                        >
                                        > <quote who="Keith Davies" when="Tue, 13 Apr 2004 12:04:53 -0700">
                                        > > On Tue, Apr 13, 2004 at 07:06:51AM -0700, Jenni A. Merrifield wrote:
                                        > > >
                                        > > > Is there any particular reason, with this *internal* data
                                        > > > representation, to avoid using traditional Boolean operators such as
                                        > > > "AND", "OR", "XOR" and "NOT"? Using it, we could be quite sure of what
                                        > > > prerequisites were being requested and their relationships to each other.
                                        > >
                                        > > I'd be willing to use this for the external data representation; I was
                                        > > using 'min' and 'max' to allow for 'at least two of the following' (or
                                        > > 'no more than two of the following', for that matter) cases. The same
                                        > > mechanism would successfully deal with the cases described below, so I
                                        > > didn't bother pursuing your suggestion (I *did* think of it, but numbers
                                        > > served the same purpose across more cases).
                                        >
                                        > [...SNIP...]
                                        >
                                        > > Your suggestion is probably simpler in most cases; I'd be willing to use
                                        > > it. The only thing it fails to handle (as written) is the 'n of m'
                                        > > case, and even that can be handled by another operand
                                        > >
                                        > > <prereq kind='mult' operand='select' min='2'>
                                        > > <prereq kind='alignment' key='lawful.good' />
                                        > > <prereq kind='feat' key='feat.eschew-materials' />
                                        > > <prereq kind='feat' key='feat.silent-spell' />
                                        > > </prereq>
                                        > >
                                        > > 'select' is a lousy operand name, need a better one.
                                        >
                                        > How about one of:
                                        >
                                        > * "selection"
                                        > * "pick" <-- I like this one
                                        > * "choose" <-- this would be familiar to LST writers
                                        > * "choice"
                                        > * "subset"
                                        >
                                        > > Still, I like the numbers version better -- it's a little clearer what's
                                        > > going on and can be implemented using a single chain of logic:
                                        > >
                                        > > min = numChildren;
                                        > > max = numChildren;
                                        > > if (minSet) {
                                        > > min = attribs.getAttrib( "min");
                                        > > }
                                        > > if (maxSet) {
                                        > > max = attribs.getAttrib( "max");
                                        > > }
                                        > > childrenMatched = checkPrereqs( entity, children);
                                        > > if ((min <= childrenMatched) &&
                                        > > (childrenMatched <= max)) {
                                        > > doWePassed();
                                        > > } else {
                                        > > doWeFailed();
                                        > > }
                                        > >
                                        > > This does not require string examination of the operand attribute, nor
                                        > > the logic necessary to handle the various cases.
                                        >
                                        > Your algorithmic argument is a fairly good one - the lack of a need
                                        > to do string examination would probably make it somewhat more
                                        > performant.

                                        It fails, though, if only max is set (oops). I need something like

                                        if (minSet) {
                                        min = attribs.getAttrib( "min");
                                        }
                                        if (maxSet) {
                                        max = attribs.getAttrib( "max");
                                        if (!minSet) {
                                        min = max;
                                        }
                                        }

                                        so that we don't require something that can't happen.

                                        > > The 'and' case is
                                        > > implicit (if min and max aren't set, it requires all children to pass),
                                        > > the 'or' case is handled as '1 of m', and it handles both 'n of m' and
                                        > > 'no more than n of m' cases consistently.
                                        >
                                        > With Boolean terms "and" would still be implicit if there is no operator
                                        > and no min or max.

                                        This is (to date) the normal case, though variable prereqs are becoming
                                        more popular (this feat or this class, plus these conditions)

                                        > In addition "pick"/"choose" is almost implicit if there is no operator
                                        > but there is a min and/or a max (e.g., a subset of the options must
                                        > apply for the prereq to apply)

                                        It is, but let's make it explicit anyway.

                                        > > I'd be willing to use 'and' or 'or' operands, but this is, IMO, more
                                        > > elegant, consistent, and simpler to implement and use.
                                        >
                                        > Perhaps you are right. It would definitely seem to be more consistent.
                                        >
                                        > Two remaining questions:
                                        >
                                        > 1) How does one negate the numerical version for prerequisites? I can think
                                        > of three options:
                                        >
                                        > A. A "not" or "inv" attribute set to "1" when it applies:
                                        >
                                        > <!-- Not this -->
                                        > <prereq kind='feat' inv='1' key='feat.eschew-materials' />

                                        <prereq kind='feat' key='feat.eschew-materials' max='0'/>

                                        > <!-- Not both -->
                                        > <prereq kind='mult' inv='1'>
                                        > <prereq kind='feat' key='feat.eschew-materials' />
                                        > <prereq kind='feat' key='feat.silent-spell' />
                                        > </prereq>

                                        This one passes when neither feat is available.

                                        <prereq kind='mult' min='1' max='1'>
                                        <prereq kind='feat' key='feat.eschew-materials' />
                                        <prereq kind='feat' key='feat.silent-spell' />
                                        </prereq>

                                        > <!-- Neither -->
                                        > <prereq kind='mult' min='1' max='1' inv='1'>
                                        > <prereq kind='feat' key='feat.eschew-materials' />
                                        > <prereq kind='feat' key='feat.silent-spell' />
                                        > </prereq>

                                        Both available, or none?

                                        <prereq kind='mult' min='1' max='1'>
                                        <prereq kind='mult' min='2'>
                                        <prereq kind='feat' key='feat.eschew-materials' />
                                        <prereq kind='feat' key='feat.silent-spell' />
                                        </prereq>
                                        <prereq kind='mult' max='0'>
                                        <prereq kind='feat' key='feat.eschew-materials' />
                                        <prereq kind='feat' key='feat.silent-spell' />
                                        </prereq>
                                        </prereq>

                                        Yuck. Better might be

                                        <prereq kind='mult' max='0'>
                                        <prereq kind='mult' min='1' max='1'>
                                        <prereq kind='feat' key='feat.eschew-materials' />
                                        <prereq kind='feat' key='feat.silent-spell' />
                                        </prereq>
                                        </prereq>

                                        That's a little unobvious, but it is consistent with other behavior.

                                        I am *considering* allowing:

                                        <prereq kind='mult' min='2' max='0'>
                                        <prereq kind='feat' key='feat.eschew-materials' />
                                        <prereq kind='feat' key='feat.silent-spell' />
                                        </prereq>

                                        It's... not something I'm happy about yet. However, I am willing to
                                        consider the case of 'min > max' to mean 'outside the defined range'. I
                                        don't know that it comes up often enough to be worth it, though.

                                        > <!-- No more than two -->
                                        > <prereq kind='mult' min='2' inv='1'>
                                        > <prereq kind='feat' key='feat.enlarge-spell' />
                                        > <prereq kind='feat' key='feat.eschew-materials' />
                                        > <prereq kind='feat' key='feat.silent-spell' />
                                        > </prereq>

                                        <prereq kind='mult' max='2'>
                                        <prereq kind='feat' key='feat.enlarge-spell' />
                                        <prereq kind='feat' key='feat.eschew-materials' />
                                        <prereq kind='feat' key='feat.silent-spell' />
                                        </prereq>


                                        > B. A "kind" attribute with the value "not"

                                        Possibly, though it's synonymous with "kind='mult' max='0'"

                                        > <!-- Not this -->
                                        > <prereq kind='not'>
                                        > <prereq kind='feat' inv='1' key='feat.eschew-materials' />
                                        > </prereq>

                                        probably meant

                                        <prereq kind='feat' key='feat.eschew-materials' />

                                        here. (You left the @inv in when you cut&paste.)

                                        > <!-- Not Both -->
                                        > <prereq kind='not'>
                                        > <prereq kind='mult'>
                                        > <prereq kind='feat' key='feat.eschew-materials' />
                                        > <prereq kind='feat' key='feat.silent-spell' />
                                        > </prereq>
                                        > </prereq>

                                        You could say

                                        <prereq kind='mult' max='0'>
                                        <prereq kind='mult'>
                                        <prereq kind='feat' key='feat.eschew-materials' />
                                        <prereq kind='feat' key='feat.silent-spell' />
                                        </prereq>
                                        </prereq>

                                        But it's even simpler to say

                                        <prereq kind='mult' max='1'>
                                        <prereq kind='feat' key='feat.eschew-materials' />
                                        <prereq kind='feat' key='feat.silent-spell' />
                                        </prereq>

                                        '0 or 1 of the following, but not 2'.

                                        I made a mistake in the pseudocode I showed in another message; if min
                                        is not set but max is, min should be set to 0, not max. It makes more
                                        sense that 'max alone' means 'there is a maximum, but no minimum',
                                        especially since 'min alone' effectively means 'there is a minimum, but
                                        no maximum'. If neither is set, all are required, so min = max = number
                                        of children.

                                        > <!-- Neither -->
                                        > <prereq kind='not'>
                                        > <prereq kind='mult' min='1' max='1'>
                                        > <prereq kind='feat' key='feat.eschew-materials' />
                                        > <prereq kind='feat' key='feat.silent-spell' />
                                        > </prereq>
                                        > </prereq>

                                        <prereq kind='mult' max='0'>
                                        <prereq kind='feat' key='feat.eschew-materials' />
                                        <prereq kind='feat' key='feat.silent-spell' />
                                        </prereq>

                                        Your will say 'both or neither', probably not what you meant.

                                        > <!-- No more than two -->
                                        > <prereq kind='not'>
                                        > <prereq kind='mult' min='2'>
                                        > <prereq kind='feat' key='feat.enlarge-spell' />
                                        > <prereq kind='feat' key='feat.eschew-materials' />
                                        > <prereq kind='feat' key='feat.silent-spell' />
                                        > </prereq>
                                        > </prereq>

                                        <prereq kind='mult' max='2'>
                                        <prereq kind='feat' key='feat.enlarge-spell' />
                                        <prereq kind='feat' key='feat.eschew-materials' />
                                        <prereq kind='feat' key='feat.silent-spell' />
                                        </prereq>


                                        > C. Adding ".inv" to the "kind" attribute

                                        No, evil. No parsing of @kind.


                                        > 2) How would one achieve the Boolean XOR -- e.g., A || B && !(A && B); one or
                                        > the other but not both -- using the numerical method? Would it have to be
                                        > written the long way, as follows (I'm using option C for NOT) or is there an
                                        > easier way that I'm overlooking:
                                        >
                                        > <prereq kind='mult'>
                                        > <prereq kind='mult' min="1" max="1">
                                        > <prereq kind='feat' key='feat.eschew-materials' />
                                        > <prereq kind='feat' key='feat.silent-spell' />
                                        > </prereq>
                                        > <prereq kind='mult.inv'>
                                        > <prereq kind='feat' key='feat.eschew-materials' />
                                        > <prereq kind='feat' key='feat.silent-spell' />
                                        > </prereq>
                                        > </prereq>

                                        <prereq kind='mult' min="1" max="1">
                                        <prereq kind='feat' key='feat.eschew-materials' />
                                        <prereq kind='feat' key='feat.silent-spell' />
                                        </prereq>

                                        is sufficient -- this is true if and only if one of the children is
                                        true, which in this case matches "(A || B) && !(A && B)". If you went
                                        three-way XOR, though, it'd be uglier... but I don't think it'll come
                                        up. In fact, I don't recall ever seeing an XOR prereq, though I'll
                                        posit their existence.


                                        Keith
                                        --
                                        Keith Davies I gave my 2yo daughter a strawberry
                                        keith.davies@... Naomi: "Strawberry!"
                                        me: "What do you say?"
                                        Naomi: "*MY* strawberry!"
                                      • Keith Davies
                                        ... This was incorrect; it doesn t follow the expected semantics (nor does my later correction, gah). What I *should* have had was: min = numChildren; max =
                                        Message 19 of 29 , Apr 19, 2004
                                          --- In pcgen-xml@yahoogroups.com, Keith Davies <keith.davies@k...>
                                          wrote:

                                          > min = numChildren;
                                          > max = numChildren;
                                          > if (minSet) {
                                          > min = attribs.getAttrib( "min");
                                          > }
                                          > if (maxSet) {
                                          > max = attribs.getAttrib( "max");
                                          > }
                                          > childrenMatched = checkPrereqs( entity, children);
                                          > if ((min <= childrenMatched) &&
                                          > (childrenMatched <= max)) {
                                          > doWePassed();
                                          > } else {
                                          > doWeFailed();
                                          > }

                                          This was incorrect; it doesn't follow the expected semantics (nor
                                          does my later correction, gah). What I *should* have had was:

                                          min = numChildren;
                                          max = numChildren;
                                          if (minSet) {
                                          min = attribs.getAttrib( "min");
                                          }
                                          if (maxSet) {
                                          max = attribs.getAttrib( "max");
                                          if (!minSet) {
                                          min = 0;
                                          }
                                          }
                                          childrenMatched = checkPrereqs( entity, children);
                                          if ((min <= childrenMatched) &&
                                          (childrenMatched <= max)) {
                                          doWePassed();
                                          } else {
                                          doWeFailed();
                                          }

                                          This correctly matches the logic:

                                          . if min and max are unset, all are required
                                          . if min is set and not max, at least min are required (the
                                          implicit 'no more than max' still works).
                                          . if max is set and not min, then it should be read as 'no more
                                          than max'; there is no minimum. I was handling this case
                                          incorrectly.
                                          . if min and max are set, min <= count <= max.
                                          . I have considered -- but don't like -- interpreting min and
                                          max set, but min > max, to mean 'min <= count || count <= max'
                                          but I'm not yet comfortable with it.


                                          Keith [posted via web]
                                        • Keith Davies
                                          ... *Still* not right. That describes equals behavior, not no more than . if (minSet) { min = attribs.getAttrib( min ); } if (maxSet) { max =
                                          Message 20 of 29 , Apr 19, 2004
                                            On Mon, Apr 19, 2004 at 08:49:57AM -0700, Keith Davies wrote:
                                            > On Fri, Apr 16, 2004 at 06:46:32PM -0700, Jenni A. Merrifield wrote:
                                            > >
                                            > > > Still, I like the numbers version better -- it's a little clearer what's
                                            > > > going on and can be implemented using a single chain of logic:
                                            > > >
                                            > > > min = numChildren;
                                            > > > max = numChildren;
                                            > > > if (minSet) {
                                            > > > min = attribs.getAttrib( "min");
                                            > > > }
                                            > > > if (maxSet) {
                                            > > > max = attribs.getAttrib( "max");
                                            > > > }
                                            > > > childrenMatched = checkPrereqs( entity, children);
                                            > > > if ((min <= childrenMatched) &&
                                            > > > (childrenMatched <= max)) {
                                            > > > doWePassed();
                                            > > > } else {
                                            > > > doWeFailed();
                                            > > > }
                                            > > >
                                            > > > This does not require string examination of the operand attribute, nor
                                            > > > the logic necessary to handle the various cases.
                                            > >
                                            > > Your algorithmic argument is a fairly good one - the lack of a need
                                            > > to do string examination would probably make it somewhat more
                                            > > performant.
                                            >
                                            > It fails, though, if only max is set (oops). I need something like
                                            >
                                            > if (minSet) {
                                            > min = attribs.getAttrib( "min");
                                            > }
                                            > if (maxSet) {
                                            > max = attribs.getAttrib( "max");
                                            > if (!minSet) {
                                            > min = max;
                                            > }
                                            > }

                                            *Still* not right. That describes 'equals' behavior, not 'no more
                                            than'.

                                            if (minSet) {
                                            min = attribs.getAttrib( "min");
                                            }
                                            if (maxSet) {
                                            max = attribs.getAttrib( "max");
                                            if (!minSet) {
                                            min = 0;
                                            }
                                            }

                                            This one has it right. Finally.


                                            Keith
                                            --
                                            Keith Davies I gave my 2yo daughter a strawberry
                                            keith.davies@... Naomi: "Strawberry!"
                                            me: "What do you say?"
                                            Naomi: "*MY* strawberry!"
                                          • Frugal
                                            ... I have never seen you take so long to get something right, go away and take something for your cold ;O) I recommend a large
                                            Message 21 of 29 , Apr 20, 2004
                                              <quote who="Keith Davies">
                                              > On Mon, Apr 19, 2004 at 08:49:57AM -0700, Keith Davies wrote:
                                              >> On Fri, Apr 16, 2004 at 06:46:32PM -0700, Jenni A. Merrifield wrote:
                                              > *Still* not right. That describes 'equals' behavior, not 'no more
                                              > than'.
                                              >
                                              > if (minSet) {
                                              > min = attribs.getAttrib( "min");
                                              > }
                                              > if (maxSet) {
                                              > max = attribs.getAttrib( "max");
                                              > if (!minSet) {
                                              > min = 0;
                                              > }
                                              > }
                                              >
                                              > This one has it right. Finally.

                                              I have never seen you take so long to get something right, go away and
                                              take something for your cold ;O) I recommend a large whiskey with a hot
                                              lemon squeezed into it.

                                              --
                                              regards,
                                              Frugal
                                              -OS Chimp
                                            • Frugal
                                              ... I did ;O) ... I can go with this because it satisfies Frugals First Law Of Programming: Never Do Anything Twice. Well, it almost
                                              Message 22 of 29 , Apr 20, 2004
                                                <quote who="Keith Davies">
                                                > On Mon, Apr 19, 2004 at 07:13:18AM -0700, Jenni A. Merrifield wrote:
                                                >> <quote who="Frugal" when="Mon, 19 Apr 2004 09:04:47 +0100 (BST)"
                                                > I never called it a dogs dinner. I don't disagree, but someone else
                                                > said that.

                                                I did ;O)

                                                > Personally, I'd rather see
                                                >
                                                > <prereq kind='cumulative' min='20'>
                                                > <count kind='skill-ranks' key='skill.jump' />
                                                > <count kind='skill-ranks' key='skill.balance' />
                                                > <count kind='skill-ranks' key='skill.tumble' />
                                                > </prereq>
                                                >
                                                > If there are further requirements (such as 'each skill must have at
                                                > least four and no more than ten ranks') then treat those as separate
                                                > prereqs:
                                                >
                                                > <prereq kind='mult'>
                                                > <prereq kind='cumulative' min='20'>
                                                > <count kind='skill-ranks' key='skill.jump' />
                                                > <count kind='skill-ranks' key='skill.balance' />
                                                > <count kind='skill-ranks' key='skill.tumble' />
                                                > </prereq>
                                                > <prereq kind='skill-ranks' key='skill.jump' min='4' max='10' />
                                                > <prereq kind='skill-ranks' key='skill.balance' min='4' max='10' />
                                                > <prereq kind='skill-ranks' key='skill.tumble' min='4' max='10' />
                                                > </prereq>

                                                I can go with this because it satisfies Frugals First Law Of Programming:
                                                Never Do Anything Twice. Well, it almost does.

                                                <prereq kind='skill-ranks' key='skill.jump' min='4' max='10' />

                                                can also be written as:

                                                <prereq kind="cumulative" min="4" max="10">
                                                <count kind='skill-ranks' key='skill.jump' />
                                                </prereq>

                                                So rather than having to have <prereq kind="skill-ranks"/> and <count
                                                kind="skill-ranks" /> we can just have <count/> and express <prereq/> in
                                                terms of <count/>

                                                So the only <prereq> kinds we need are "count" and "mult" where
                                                kind="count" can only have <count> children and kind="mult" can only have
                                                <prereq> children.

                                                As we can convert from all <prereq kind="skill-ranks"/> to a count nested
                                                inside a prereq on the fly this should not be a problem.


                                                As an aside in the very low level schema I think that
                                                <count kind='skill-ranks' key='skill.jump' />
                                                should actually be written as:
                                                <count kind='var' key='skill.jump.ranks' />
                                                because we are storing a lot more of the information as variables than the
                                                current system

                                                --
                                                regards,
                                                Frugal
                                                -OS Chimp
                                              • Keith Davies
                                                ... The diet I m on, I m not allowed lemon. Or tea (my preferred cold-time drink is tea with honey (verboten) and a couple of Fisherman s Friends (strong
                                                Message 23 of 29 , Apr 20, 2004
                                                  On Tue, Apr 20, 2004 at 08:33:36AM +0100, Frugal wrote:
                                                  >
                                                  > <quote who="Keith Davies">
                                                  > > On Mon, Apr 19, 2004 at 08:49:57AM -0700, Keith Davies wrote:
                                                  > >> On Fri, Apr 16, 2004 at 06:46:32PM -0700, Jenni A. Merrifield wrote:
                                                  > > *Still* not right. That describes 'equals' behavior, not 'no more
                                                  > > than'.
                                                  > >
                                                  > > if (minSet) {
                                                  > > min = attribs.getAttrib( "min");
                                                  > > }
                                                  > > if (maxSet) {
                                                  > > max = attribs.getAttrib( "max");
                                                  > > if (!minSet) {
                                                  > > min = 0;
                                                  > > }
                                                  > > }
                                                  > >
                                                  > > This one has it right. Finally.
                                                  >
                                                  > I have never seen you take so long to get something right, go away and
                                                  > take something for your cold ;O) I recommend a large whiskey with a hot
                                                  > lemon squeezed into it.

                                                  The diet I'm on, I'm not allowed lemon. Or tea (my preferred cold-time
                                                  drink is tea with honey (verboten) and a couple of Fisherman's Friends
                                                  (strong cough tablet things)).

                                                  The whiskey I am allowed, but I'm not much on whiskey.


                                                  Keith
                                                  --
                                                  Keith Davies I gave my 2yo daughter a strawberry
                                                  keith.davies@... Naomi: "Strawberry!"
                                                  me: "What do you say?"
                                                  Naomi: "*MY* strawberry!"
                                                • Keith Davies
                                                  ... Yeah, I read your post after. ... Well, we probably need others because there are tests that are binary (such as kind= feat ), but I suspect a number of
                                                  Message 24 of 29 , Apr 20, 2004
                                                    On Tue, Apr 20, 2004 at 08:43:36AM +0100, Frugal wrote:
                                                    > <quote who="Keith Davies">
                                                    > > On Mon, Apr 19, 2004 at 07:13:18AM -0700, Jenni A. Merrifield wrote:
                                                    > >> <quote who="Frugal" when="Mon, 19 Apr 2004 09:04:47 +0100 (BST)"
                                                    > > I never called it a dogs dinner. I don't disagree, but someone else
                                                    > > said that.
                                                    >
                                                    > I did ;O)

                                                    Yeah, I read your post after.

                                                    > > Personally, I'd rather see
                                                    > >
                                                    > > <prereq kind='cumulative' min='20'>
                                                    > > <count kind='skill-ranks' key='skill.jump' />
                                                    > > <count kind='skill-ranks' key='skill.balance' />
                                                    > > <count kind='skill-ranks' key='skill.tumble' />
                                                    > > </prereq>
                                                    > >
                                                    > > If there are further requirements (such as 'each skill must have at
                                                    > > least four and no more than ten ranks') then treat those as separate
                                                    > > prereqs:
                                                    > >
                                                    > > <prereq kind='mult'>
                                                    > > <prereq kind='cumulative' min='20'>
                                                    > > <count kind='skill-ranks' key='skill.jump' />
                                                    > > <count kind='skill-ranks' key='skill.balance' />
                                                    > > <count kind='skill-ranks' key='skill.tumble' />
                                                    > > </prereq>
                                                    > > <prereq kind='skill-ranks' key='skill.jump' min='4' max='10' />
                                                    > > <prereq kind='skill-ranks' key='skill.balance' min='4' max='10' />
                                                    > > <prereq kind='skill-ranks' key='skill.tumble' min='4' max='10' />
                                                    > > </prereq>
                                                    >
                                                    > I can go with this because it satisfies Frugals First Law Of Programming:
                                                    > Never Do Anything Twice. Well, it almost does.
                                                    >
                                                    > <prereq kind='skill-ranks' key='skill.jump' min='4' max='10' />
                                                    >
                                                    > can also be written as:
                                                    >
                                                    > <prereq kind="cumulative" min="4" max="10">
                                                    > <count kind='skill-ranks' key='skill.jump' />
                                                    > </prereq>
                                                    >
                                                    > So rather than having to have <prereq kind="skill-ranks"/> and <count
                                                    > kind="skill-ranks" /> we can just have <count/> and express <prereq/> in
                                                    > terms of <count/>
                                                    >
                                                    > So the only <prereq> kinds we need are "count" and "mult" where
                                                    > kind="count" can only have <count> children and kind="mult" can only have
                                                    > <prereq> children.

                                                    Well, we probably need others because there are tests that are binary
                                                    (such as kind='feat'), but I suspect a number of the numeric ones can be
                                                    reduced to your example.

                                                    OTOH, even feat can be:

                                                    <prereq kind='count' min='1'>
                                                    <count kind='feat' key='feat.alertness' />
                                                    </prereq>

                                                    OTOH, I can see someone getting hosed when they try to do

                                                    <prereq kind='count' min='3'>
                                                    <count kind='feat' key='feat.weapon-focus' />
                                                    <count kind='feat' key='feat.greater-weapon-focus' />
                                                    <cound kind='feat' key='feat.weapon-specialization' />
                                                    </prereq>

                                                    because it should be

                                                    <prereq kind='mult'>
                                                    <prereq kind='count' min='1'>
                                                    <count kind='feat' key='feat.weapon-focus' />
                                                    </prereq>
                                                    <prereq kind='count' min='1'>
                                                    <count kind='feat' key='feat.greater-weapon-focus' />
                                                    </prereq>
                                                    <prereq kind='count' min='1'>
                                                    <count kind='feat' key='feat.weapon-specialization' />
                                                    </prereq>
                                                    </prereq>

                                                    > As we can convert from all <prereq kind="skill-ranks"/> to a count
                                                    > nested inside a prereq on the fly this should not be a problem.

                                                    If this is reserved for internal use I don't think I'll argue, though I
                                                    expect to keep the more concise form for external. While I agree that
                                                    consistency is a benefit, I think I'd rather see the larger syntax used
                                                    when needed, but allow the more concise syntax for the more common case.

                                                    I don't like making *everything* harder in order accommodate something
                                                    that I don't expect to come up often. OTOH, I really dislike special
                                                    cases. Gah, I'm going to leave it for how.

                                                    > As an aside in the very low level schema I think that
                                                    > <count kind='skill-ranks' key='skill.jump' />
                                                    > should actually be written as:
                                                    > <count kind='var' key='skill.jump.ranks' />
                                                    > because we are storing a lot more of the information as variables than the
                                                    > current system

                                                    Fair enough. IIRC at one point skill ranks were handled differently.


                                                    Keith
                                                    --
                                                    Keith Davies I gave my 2yo daughter a strawberry
                                                    keith.davies@... Naomi: "Strawberry!"
                                                    me: "What do you say?"
                                                    Naomi: "*MY* strawberry!"
                                                  • Frugal
                                                    ... Are you allowed Chilli? the other cure I have for a cold is a good hot curry. -- regards, Frugal -OS Chimp
                                                    Message 25 of 29 , Apr 20, 2004
                                                      <quote who="Keith Davies">
                                                      > On Tue, Apr 20, 2004 at 08:33:36AM +0100, Frugal wrote:
                                                      >> I have never seen you take so long to get something right, go away and
                                                      >> take something for your cold ;O) I recommend a large whiskey with a hot
                                                      >> lemon squeezed into it.
                                                      >
                                                      > The diet I'm on, I'm not allowed lemon. Or tea (my preferred cold-time
                                                      > drink is tea with honey (verboten) and a couple of Fisherman's Friends
                                                      > (strong cough tablet things)).
                                                      >
                                                      > The whiskey I am allowed, but I'm not much on whiskey.

                                                      Are you allowed Chilli? the other cure I have for a cold is a good hot curry.

                                                      --
                                                      regards,
                                                      Frugal
                                                      -OS Chimp
                                                    • Keith Davies
                                                      ... Not really, no. Right now I m down to Vitamin C and hot water. I m at the worst part, the aw *shit*, I *am* sick part. Tomorrow I ll be in worse
                                                      Message 26 of 29 , Apr 20, 2004
                                                        On Tue, Apr 20, 2004 at 03:35:25PM +0100, Frugal wrote:
                                                        >
                                                        > <quote who="Keith Davies">
                                                        > > On Tue, Apr 20, 2004 at 08:33:36AM +0100, Frugal wrote:
                                                        > >> I have never seen you take so long to get something right, go away and
                                                        > >> take something for your cold ;O) I recommend a large whiskey with a hot
                                                        > >> lemon squeezed into it.
                                                        > >
                                                        > > The diet I'm on, I'm not allowed lemon. Or tea (my preferred cold-time
                                                        > > drink is tea with honey (verboten) and a couple of Fisherman's Friends
                                                        > > (strong cough tablet things)).
                                                        > >
                                                        > > The whiskey I am allowed, but I'm not much on whiskey.
                                                        >
                                                        > Are you allowed Chilli? the other cure I have for a cold is a good hot
                                                        > curry.

                                                        Not really, no. Right now I'm down to Vitamin C and hot water.

                                                        I'm at the worst part, the 'aw *shit*, I *am* sick' part. Tomorrow I'll
                                                        be in worse condition, but it won't bother me so much because I'll
                                                        likely be unconscious anyway.


                                                        Keith
                                                        --
                                                        Keith Davies I gave my 2yo daughter a strawberry
                                                        keith.davies@... Naomi: "Strawberry!"
                                                        me: "What do you say?"
                                                        Naomi: "*MY* strawberry!"
                                                      Your message has been successfully submitted and would be delivered to recipients shortly.