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

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

Expand Messages
  • Keith Davies
    ... 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
    Message 1 of 29 , Apr 13, 2004
      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 persuing your suggestion (I *did* think of it, but numbers
      served the same purpose across more cases).

      > Examples:
      >
      > <prereq kind="mult" operand="XOR">
      > <!-- Any Lawful or true neutral -->
      > <prereq kind="alignment" key="lawful.good"/>
      > <prereq kind="alignment" key="lawful.neutral"/>
      > <prereq kind="alignment" key="lawful.evil"/>
      > <prereq kind="alignment" key="neutral.neutral"/>
      > </prereq>
      > <!-- XOR is the most accurate option here, though OR would also work here
      > because no object should ever have more than one alignment anyway -->
      >
      > <prereq kind="mult" operand="AND">
      > <prereq kind="alignment" key="lawful.good" />
      > <prereq kind="mult" operand="OR">
      > <prereq kind="feat" key="feat.eschew-materials" />
      > <prereq kind="feat" key="feat.silent-spell" />
      > </prereq>

      <prereq>
      <prereq kind='alignment' key='align.lg' />
      <prereq min='1'>
      <prereq kind='feat' key='feat.eschew-materials' />
      <prereq kind='feat' key='feat.silent-spell' />
      </prereq>
      </prereq>

      This is a little shorter, but not enough to really care about.

      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.

      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. 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.

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

      > I recognize that many non-programmers get confused by Boolean logic
      > (especially when doing searches because it contradicts standard language
      > conventions - e.g., find boys AND girls) and so I wouldn't recommend Boolean
      > logic for an *external* representation, but why not use it *internally*?

      For something like this I think I'd like to keep it consistent between
      internal and external. While I don't mind transforming data to make it
      suit our purposes better (smashing all entity element types to an
      <entity> structure on load, for example), minor cosmetic differences
      complicate things without adding much.

      A friend of mine has spent a fair amount of time in Canada, Japan, and
      the US over the last few years (is Canadian, has been teaching in Japan,
      and his fiancee is from the US). He has fewer problems dealing with yen
      vs. Canadian dollars than US dollars vs. Canadian dollars simply because
      they had a different name.

      > > I'm not generally fond of implicit behavior... though in this case I see
      > > it as something of an 'explicit implicit' -- it's part of the defined
      > > behavior. Still, it doesn't *hurt* to say <prereq kind='mult'>, either.
      >
      > Can't you define both forms as valid? Full syntax requires
      > kind="mult" but if kind is for some reason omitted then kind="mult" is
      > assumed?

      That's what I was doing (in practice, if not in implementation). The
      only thing this leaves us vulnerable to is a change in interpretation,
      but I don't *expect* that to happen -- there are really no other
      reasonable interpretations of *any* prereq that has child prereqs; if
      the prereq doesn't have children, 'mult' is not an appropriate @kind
      anyway.


      Keith
      --
      Keith Davies I gave my 2yo daughter a strawberry
      keith.davies@... Naomi: "Strawberry!"
      me: "What do you say?"
      Naomi: "*MY* strawberry!"
    • 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 2 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 3 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 4 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 5 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 6 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 7 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 8 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 9 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 10 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 11 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 12 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 13 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 14 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 15 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 16 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 17 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 18 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 19 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 20 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 21 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 22 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 23 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 24 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 25 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 26 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 27 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.