chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-users] actors, roles and meta-observers


From: chi
Subject: [Chicken-users] actors, roles and meta-observers
Date: Sat, 06 Jun 2015 18:55:28 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0

I've been trying to learn about reputation management (no, not the marketing
department) and I'm not sure how to handle observers when looking up someone
with a good reputation.

My idea of it so far is that there are actors and roles, and each actor
categorizes other actors by role, and by how well they're expected to play that
role. You find out someone's a good dentist for instance, so you'll strongly
praise their ability in the "dentist" role. Dentist, plumber, non-shitposter,
those sort of roles.

But if I don't know of any good dentists (I don't) maybe I know someone who
does? If I can find someone who's already been to a dentist and found they're
good (or terrible), then I don't have to risk more of my teeth to charlatans and
racketeers in order to find out who's a good dentist. So if I check my list of
good dentists and find it lacking, I need to check my list of good
dentist-finders to see if anyone in there can help me. And that could extend
recursively to dentist-finder-finders but of course you'd have to multiply the
trust value to attenuate it, since you can't trust a friend of a friend as much
as you can a friend.

The latter really is hard to twist my head around, because when I tried
programming it, I ended up needing to magically backtrack to before a success
state. This is what I ended up with, pretty much...

(use (prefix-in nwdb: nwdb)) ;; assume this can do anything

(define (lookup me role threshold yay boo)
  (let loop ((actors (nwdb:list `(,me ,role))))
    (match actors ;; some deconstructing pattern matching thing
           (null? (boo))
           ((actor weight) . rest)
           (if (>= weight threshold)
               (yay actor weight)
               (loop rest))))
   (let loop (actors (nwdb:list `(,me (observing ,role))))
     (match actors
            (null? (boo))
            (((actor weight) . rest)
             (if (>= weight threshold)
                 (lookup actor role
                         threshold
                         (lambda (actor sub-weight)
                           (if (> (* weight sub-weight) threshold)
                               (yay actor (* weight sub-weight))
                               (keep-looping-even-though-you-cant)))
                         ;; ugh...
                         boo)
                 (loop rest))))))

(lookup me 'dentist 0.5
        (lambda (actor weight)
          (make-appointment actor))
        (lambda ()
          (error "Couldn't find a good dentist. Insert pick randomly algorithm
here.")))


The first loop is straightforward, checking a list of actor/weight pairs trying
to find a good role player. The second one I'm trying to find a good observer
role player, but when I do I then need to recurse on their own lookup function
for a good dentist. If I can find a dentist they recommend that's above the
threshold after being multiplied by their own weight I'm good. But the lookup
function stops after the first good match, which is the first dentist that the
other guy recommends is good. That dentist is above his threshold, but multiply
their weight by my weight of this dentist-finder person and it might not be high
enough.

But if that product is not high enough, the other guy could still recommend
other dentists /even more/. So like for instance if my threshold is 0.5, and my
weight for an (observer dentist) is 0.8, they could find a dentist that they
think is 0.5 likely to be good, and that's the one that gets passed back. But
though 0.5 is past my threshold of 0.5, 0.8 * 0.5 is 0.4, which is below my
threshold. The next dentist on (observer dentist)'s list could be highly
recommended at 0.9, which would result in a strength of 0.72, well above my
threshold of 0.5, but I'll never see it, since the first dentist was the success
state and it stops looping after that.

So, there's four ways I can think of to fix (aka overcomplicate) this. First is
to just pass the loop to the success procedure, along the lines of (yay actor
weight loop). Then, if it's not yay after all, they can call loop to continue to
the next actor. Actually it'd have to be (yay actor weight (lambda () (loop
rest)). I worry that this might be a bad idea, since if I'm not reaching a
success state after all, shouldn't I anticipate that beforehand instead of
backtracking?

Second is to use continuations, just assuming that yay never returns except when
it's actually a failure, like
(begin
  (when (> weight threshold)
    (yay actor weight))
  (loop rest))

I'm less than confident about that because it puts an onus on (yay) to not
return unless it wants to continue paging through all the actors, and it might
hang around wasting memory just in case I want to continue looping on the rest.
But on the other hand it is a lot less open ended than passing loop as an
argument, which I've found is an easy to misplace loops that really should have
been looped over.

Third is to have an intermediate (check-if-yay) function. I don't know if that'd
introduce more complexity since it can't just check if the weight is beyond the
threshold, but also has to check if it's beyond some nebulous threshold-checking
function passed as an argument. Plus for many cases, such as when I'm looking
for the first dentist on my good list, I don't care about anything besides
whether they're past the threshold. It's only when I have to start multiplying
weights that I end up wanting to backtrack and keep looping.

Fourth is to divide the threshold by the observer actor's weight, which would do
the algebraic equivalent of multiply the actor's actors' weights by the actor's
weight.

(lookup actor role
            (/ threshold weight)
            (lambda (actor sub-weight)
               (yay actor (* weight sub-weight)))
            boo)

No observers or any other roles are going to have a zero weight, because that
would require full interconnection of all nodes which would be hugely wasteful
for a large amount of actors/roles. I think it'd work okay, but I can't help but
think there might be another reason I'm backtracking, and I'd get tripped up by
that later when I try to have it so (yay) means (yay).



reply via email to

[Prev in Thread] Current Thread [Next in Thread]