Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Objective-c > Quantifiers
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 5 Topic 930 of 1008
Post > Topic >>

Quantifiers

by "Xcriber51" <ken@[EMAIL PROTECTED] > Dec 12, 2007 at 04:30 AM

Hi everyone

I'm trying to write a very simple module with a handful of quantifiers and
similar set-theoretic constructs, and I'm trying to figure out how one can
do this best with Objective-C.

Functional languages make this very easy. For example, with Q, you can
write...

> any (<0) [5,6,9,-3]
true

> all (<>-3) [5,6,9,-3]
false

The predicate(s) ("<0", "<>-3") are nicely applied to each of the members,
and as the quantifiers are [most probably] defined with a "reduce"
function
as...

any 	= reduce (or) false;
all 	= reduce (and) true;

...you get the result with very elegant code.

(NB: "Elegant" stands NOT for "fa****onably smart-dressed" but for
"ingenuously simple and effective." <End of insulting fellow coders'
intellect.>)

However, the tricky parts here are

- the curried syntax of the predicate(s);
- the type-generality of their application domain

...neither of which are sup****ted by Objective-C. (Ok, maybe "id" can be
used for the second but that's not a type derived from say a protocol like
-- to use a Java/Eiffel analogy -- "Comparable"; it's probably a "(void
*)"
or something. <End of Objective-C-ignorant remark.>)

I'm a novice to Objective-C, so I first tried this with integers as
follows.

I used a function pointer called "Predicate" to define the simple
relations of equal, less than, greater than, etc.

// "Predicate.h"

typedef BOOL (*Predicate)(int lhs, int rhs);

BOOL eq (int lhs, int rhs)  { return (lhs == rhs); }
BOOL lt (int lhs, int rhs)  { return (lhs <  rhs); }
BOOL gt (int lhs, int rhs)  { return (lhs >  rhs); }
BOOL le (int lhs, int rhs)  { return (lhs <= rhs); }
BOOL ge (int lhs, int rhs)  { return (lhs >= rhs); }
BOOL ne (int lhs, int rhs)  { return (lhs != rhs); }


// These macros are only for convenience, to save the
// client from having to use the address-of op '&'.

#define equalTo             &eq
#define lessThan            &lt
#define greaterThan         &gt
#define lessThanEqualTo     &le
#define greaterThanEqualTo  &ge
#define notEqualTo          &ne


Then I used a category named "Quantifying" on the NSSet type (since I
expect these to be used primarily on sets) (the implementations are just
the first trials and some are naive in algorithm):

// "Quantifying.h"

#im****t <Foundation/Foundation.h>
#im****t "Predicate.h"

@[EMAIL PROTECTED]
 NSSet (Quantifying);
-(BOOL) any: (Predicate) pred : (int) rhs;
-(BOOL) all: (Predicate) pred : (int) rhs;
-(BOOL) none: (Predicate) pred : (int) rhs;
-(BOOL) most: (Predicate) pred : (int) rhs;
-(BOOL) few: (Predicate) pred : (int) rhs;
@[EMAIL PROTECTED]
 NSSet (Quantifying);

// Could be implemented with binary search to speed up
-(BOOL) any: (Predicate) pred : (int) rhs
{
    int i = [self count]-1;
    NSEnumerator *ns = [self objectEnumerator];

    while ((i >= 0) && ! pred([[ns nextObject] intValue], rhs))
        i--;

    return (i > 0);
}

-(BOOL) all: (Predicate) pred : (int) rhs
{
    int i = [self count]-1;
    NSEnumerator *ns = [self objectEnumerator];

    while ((i >= 0) && pred([[ns nextObject] intValue], rhs))
        i--;

    return (i < 0);
}

-(BOOL) none: (Predicate) pred : (int) rhs
{
    int i = [self count]-1;
    NSEnumerator *ns = [self objectEnumerator];

    while ((i >= 0) && ! pred([[ns nextObject] intValue], rhs))
        i--;

    return (i < 0);
}

// Could exit once it determines 1 item more than half
// of the set fulfills the predicate
-(BOOL) most: (Predicate) pred : (int) rhs
{
    int i = [self count]-1;
    int q = i/2, r = i%2, e = 0;

    NSEnumerator *ns = [self objectEnumerator];

    while (i >= 0) {
        if (! pred([[ns nextObject] intValue], rhs))
            e++;
        i--;
    }

    return (e < q+r);
}

// Likewise, could exit once it determines more than
// half of the items fail to fulfill the predicate
-(BOOL) few: (Predicate) pred : (int) rhs
{
    int i = [self count]-1;
    int q = i/2, r = i%2, e = 0;

    NSEnumerator *ns = [self objectEnumerator];

    while (i >= 0) {
        if (! pred([[ns nextObject] intValue], rhs))
            e++;
        i--;
    }

    return (e > q+r);
}

@[EMAIL PROTECTED]
 may ask "what exactly are the 'none', 'most', and 'few' dudes doing
there?" but never mind that. They are just for convenience -- I can
imagine problems where they could come in handy (with which you're free to
disagree, but that's a different topic :)).

And then a very simple workout:

// "main.m"

#im****t <Foundation/Foundation.h>
#im****t "Quantifying.h"

#define _I(v)   [NSNumber numberWithInt: v]


int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    NSSet *ns = [NSSet setWithObjects: _I(5), _I(6), _I(9), _I(-3), nil];

    printf("ns = { 5, 6, 9, -3 } :\n" \
        "  any  <   0 = %c\n" \
        "  all  != -3 = %c\n" \
        "  none == -4 = %c\n" \
        "  most >   0 = %c\n" \
        "  few  >=  9 = %c\n\n",
        [ns any:  lessThan            :  0] ? 'Y' : 'N',
        [ns all:  notEqualTo          : -3] ? 'Y' : 'N',
        [ns none: equalTo             : -4] ? 'Y' : 'N',
        [ns most: greaterThan         :  0] ? 'Y' : 'N',
        [ns few:  greaterThanEqualTo  :  9] ? 'Y' : 'N'
        );

    [pool release];

    return 0;
}


(NB: This was compiled on a Windows MinGW environment using the GNUstep
implementation of the Foundation cl*****.)

Here's the output (the compile file is "qntf"):

$ qntf
ns = { 5, 6, 9, -3 } :
  any  <   0 = Y
  all  != -3 = N
  none == -4 = Y
  most >   0 = Y
  few  >=  9 = Y

--

Now, my question(s):

- Do you know a more concise and/or elegant way of doing this?
- How would you code this so that I could send not only integers but any
kind of data (chars, strings, complex numbers) to it?

When you're replying, please make sure you...

- do NOT provide the full text of the solution you suggest (I'd like to
solve this myself);
- do NOT reply with "you dufus, module/type X of library A already
provides this";
- if possible, rather than suggesting something yourself, direct me to a
resource that may inspire that idea;
- preferably only discuss, or hint at, the characteristic principles of
Objective-C coding that I should ponder on when I'm trying to find the
solution.

Thanks for reading this long-winded message (my server doesn't allow me to
attach files, so I had to include the code in the message), and thanks in
advance for your reply.


Cheers
-- K


--
Message posted using
http://www.talkaboutprogramming.com/group/comp.lang.objective-c/
More information at http://www.talkaboutprogramming.com/faq.html
 




 5 Posts in Topic:
Quantifiers
"Xcriber51" <  2007-12-12 04:30:57 
Re: Quantifiers
cb@[EMAIL PROTECTED] (Ch  2007-12-12 13:14:25 
Re: Quantifiers
"Xcriber51" <  2007-12-12 09:15:16 
Re: Quantifiers
Michael Ash <mike@[EMA  2007-12-12 11:13:46 
Re: Quantifiers
hns <hns@[EMAIL PROTEC  2007-12-13 03:19:40 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Tue Jul 22 22:45:26 CDT 2008.