Share
Explore

Negation Game Next Steps

Alright! In previous episodes we made great progress on performing inference using the negation game. Today we're going to extend that progress. There are a lot of things that we could explore here, and I'm not sure where to start. But I think i'll just chip away at it this afternoon and we'll see what we've found on the other side. Here are some of the things that seem quite fun to work on: 1. naming points 2. search over belief sets 3. epistemic leverage
Each of these is perfectly fascinating. And I can't wait to write about them and find what the next best allocation of my time should be. Today is Saturday Aug 12, 2023, and it's already 1pm (I slept in) so I don't have forever to search, I have to pick something and go. I am a bit sad, if I'm being honest. I leave on Monday and I haven't yet gotten to go out and enjoy the Colorado Mountains, and this might be the most beautiful summer I've ever seen, it's so green. and yet I've spent all of it in coffe shops working on this. But that's ok. There's a season for everything and I'm in this season. After all, the only reason I'm pining for the alternative is because I've experienced the alternative. I know what it's like to wander in the mountains because I've gotten to be there. And one day I will pine for the opportunity to sit in coffee shops working on whatever I like with a huge sense of impending opportunity. I am where I am. Let's go.
In addition to this list of goodies, there are more things I'd like to explore as possibilities. 1. better graph layout 2. writing all of this in python directly instead of a dsl 3. proving the relationship between this and probability theory 4. doing machine learning with this structure 5. performance improvements to the algorithm
But all of that will have to wait. First, let me tell you about these fun things:

Naming points

I made a video explaining how to encode the simple logic puzzle into the negation game. But I learned that it's pretty annoying to use with the current ergonomics. Specifically, the problem I ran into is that if I have some graph like ``` point 1 point 1
point 1 link 2 0 ```
But then I add a new point to the top ``` point 1 point 1 point 1
point 1 link 2 0 ```
Well now my link action means something different. It's very annoying. Ah but it occurs to me that I can solve this quite easily. Remember, this structure is supposed to be append only, which means that I need to add these new points to the end. Ahh. Ok this makes more sense. So then this implies what? I guess nothing needs to change per se, but there is another annoyance. Whenever I create a point it's hard to reference it. I'd love to be able to give points names and then negate them that way. I imagine I can, right? I could write a python level language that implemented point link and intrust, those are then added to the dsl. Yeah that makes sense. I think ideally you wouldn't have a dsl in the middle at all. You'd create a ast out of the python language and then that could be used to create everything: the invalidation matrix, the graphs, and you could enter it from the dsl or the python api. Yeah, that's the way. But that's potentially a lot of work.
Huh actually it might not be that hard. It might just be about building up the tokens instead of building the deltas. Interesting. Ok that's something we could do today.
But is this valuable? What are we trying to do? There are two things to aim for: 1. a better call with Lauren than we would have had otherwise 2. an overall advance in understanding the algorithm
Ok, with that in mind, what will this allow us to do? It might help in the call with Lauren tomorrow and it might help us run experiments we otherwise wouldn't have run.
There's one final thing which I want to be careful not to neglect answering. There's a sense in which a bundle of points represents something. The hyperedge of points that encode the idea that Marv can only sit in one place. This is somehow reminiscent of what we've been calling a 'template' or 'prototype', but it applies more broadly, somewhat like a function. I'd enjoy experimenting with implementing this python api in such a way that it's capable of representing those things.
Ok, that's thing 1 and it's already almost 2pm haha. next

Search over belief sets

Here's something remarkable. We can put into any negation game a valuation and we can then get out a score should be maximized. Ah wait that gives me an even better idea. Right now we have this as our internal consistency score: ```python credence(endowment, invalidations).sum() / endowment.sum() ``` This score we want to maximize. In principle once we put in epistemic leverage it can even go beyond 1, which is interesting. But I think there could be another way to score this which could just be a number that we minimize. I guess what we want is we want to use the minimum amount of endowment in order to get the biggest possible score. Well the measure of the size of the score that's left over is: ```python endowment.sum() - credence(endowment, invalidations).sum() ``` If this is 0 then one of two things is true. Either our endowment is 0, or we've recovered all of the endowment value from the credence. It's unlikely our endowment will be 0 because that takes into account both the intrustments and the valuation. If someone has their entire valuation set to 0 then they're not going to be able to receive payment and there's not going to be any governance they can do. That's the nihilist position, it literally doesn't work.
Now that we have an objective function for the system, we can in theory perform search over it. This can mean a couple of things. It could mean we break out an evolutionary or stochastic gradient descent algorithm to search for loss minimizing valuations. This is a cool idea in and of itself and it's something I want to try.
Something to think about if that's the strategy we pursue is that there should probably be some sort of feedback mechanism that says whether or not it's working. I suppose that's what we generally do with intrustments and valuations? What's the difference? Well, an intrustment is how one player communicates with another player that they think it's necessary to believe something and that the other person should also believe it. It's permissible because the intrustment can be ignored either by: 1. distrusting the point itself (through lowered valuation or negation) 2. distrusting the relevance of the point 3. lowering the valuation of the coins that make up the intrustment
Meanwhile valuations are a different, less global kind of connectivity. We have a choice here as we do this analysis. Either we can think about this in terms of the relationship between the Negation Game and Index Wallets, or we can just think in the Negation Game. I'm partial to both, and I don't know how to proceed. If we just think about the Negation Game then we get rid of one dynamic, which basically says that there will be extra-systemic effects where propinquitous people will have similar valuations. But we can think about that as merely defining "namespaces" for the valuation game. Certainly these will be leaky namespaces, but you get the idea. So that is nice, at first approximation we can factor that dynamic out. But Ok, not going to solve this now. What is my next move?
I have one final piece of ambiguity to resolve. There's a choice to make about the dynamcis of intrustments. Right now, intrustments are free because you have infinite points to spend. This is good because in the end state we want them to be free (if your community has propinquity). The way we achieve that is when you intrust you get back ownership of the thing you intrusted in proportional to the amount you intrusted. This makes it "free", modulo any disagreement with your community and the possibility that a future you will slash your stake.
When that happens, inevitably we will have to put in protections against repeated intrustments. I.e. there's a point that I intrust in, get back the intrustment coin and reintrust using that. This would permit infinite leverage, which isn't ok. How do we avoid this?
Uh oh, just realized I don't have my charger on me... computer is going to die soon. only 13% left. damn. Closed everything, brightness down but we'll see how long I can last.
How do we avoid this? We have to prevent infinite leverage by making it so that points value their own tokens at 0. So if you try to make an intrustment using the tokens of that point it will make you pay much more for it. Huh, but then this means that when the system quiries the value of each point I guess it asks the point how much it has received in intrustment? Yikes this is going to require more thought, probably as I walk home after my computer dies. It's useful thing to notice though because I've been trying to figure out how the governance works for groups and this is a nice constraint, constraints are wonderful.
Next what do we do? Well, given all that complexity clearly it will be sufficient challenge to try to understand the Negation Game on its own. That means we try to search for valuations that satisfy some set of intrustments.
As a bonus, it would also be cool to allow some system to also add new nodes and links to the graph as it saw fit in order to try to find better solutions to the problem. That's underspecified though because we know how to trivially add new nodes so as to minimize loss, you just negate the linking points. But, then again, if the linking points have high intrustment maybe it's not... huh ok I see this could be fun. It's a bit of a learning paradigm, where everything is put into a single large vector instead of a matrix of weights and a matrix of biases.
It's now 3pm and I have 11%. So, what do I need to do? Probably best to come up with more logic puzzles, encode the right answers as intrustments, and then find which algorithm does the best job searching for a solution to the constraint. We'll just assume that there is some function that has already turned the intrustments into a total value intrusted according to each points valuation or whatnot.
Ok next.

Epistemic Leverage

Finally, it would be fun to think about and work on epistemic leverage.
The primary concern that someone like Lauren tomorrow will have is that this seems to be the type of system where the richest person wins. We want to talk about how we have built in mechanisms to prevent plutocracy. Those include the wealth equalizing dynamics of index wallets, and epistemic leverage. But there's a problem, I don't know how epistemic leverage works. ha.
There's a short list of the parts of epistemic leverage that are difficult for me. 1. is it optional, like a praxis? if so, how to make it optional? 2. is it a primitive does it merely build on the mechanisms of the negation game? 3. how does it work haha
let's start with the basic idea. The basic idea of epistemic leverage is that there's a type of signal to propogate "upward" in the system and that's a signal of surprise. Of course, we could merely measure a group's existing average beliefs, but that's not great because average beliefs move slowly and instead we want to sample from optimal sensors. But what counts as an optimal sensor? Who should we listen to? One answer to this is that we should listen to people who make statements about how they could find out that they're wrong, and we believe that they'll change their mind if one of those things becomes true. This is the classic formulation of a "precarious" belief. In fact, we don't care so much about the person (thankfully, reputation is a dangerous business) but rather we care about the belief itself and its context. In summary: give more influence to people that make precarious statements. It's precarious iff: 1. they believe it enough to stake 2. it's thought to be false 3. it's thought that if it turns out to be false they'll slash their stake
If this criteria is met then this is surprising information, and it should be able to propogate upward, influencing other points and options.
In the past we've come up with two implementaitons that fit this definition, although there could be more. 1. you give soemone double influence on their point if they're willing to intrust in the relevance of a negating point, but also you give the negating point double influence too (at least until they slash their stake) 2. you make a market which bets on the likelihood that the person will slash their stake. This encodes P(false, honest), which meets our criteria. Then this can become a gradient of leverage. If it's high then it propogates more negation upward, if it's low it barely propogates.
8%
The issue here is that this is an important thing to get right and there are multiple ways it could go, in fact, that's exactly the intuition that sits behind the idea of making this optional. If it's useful then it can be accepted as a praxis, if not it can be abandoned. But then you might worry that there will be too much force of wealth in the lower layers for this sort of thing to ever get traction if it were sufficiently adopted in the early days. 7% The counterargument there is that if it's useful for inference to incorporate surprise (which it has to be, right?) then this will emerge naturally because the surprise sensitive groups will outperform the insensitive ones. Furthermore, the emphasis on precarity is a me thing, not a universal thing. It should be possible for people to implement value sets that I might not like. The goal is not to create Connor's system, but rather anyone's system, where Connor is one of the possible anyones.
Ok, great. That settles it for me.
7%
Let's make it optional. This is a great route to go becasue we don't have to answer #3, how does it work, because we'll do that together. But how do we make it optional?
I have a sense that our work on naming points, especially the idea of generic functions for linking points will be pretty useful. 6% tend to check after I've sat for a while. Well, all that these preprocessers have to do is implement an algorithm that can be run on the graph. As a result they should return some new, what? Probably they should not change the invalidation graph? Why? Should they be able to change the intrustments? or just the endorsement? Well, they need not change the graph itself, as creating linking points is free. And they should be able to do anything they want by changing the final endowment. Intrustments are only needed for communicating between praxis contexts. I suppose even that the function that interprets the value of the intrustments in points could itself be a preprocessor. Huh. That would allow me to do a lot of can kicking. 6% Ok so a preprocessor accepts a system state and returns an endowment. The endowment then gets shoved into the negation game and out pops the result. Cool.
This implies then that the mechanism for selecting which preprocessor to use must happen before running the negation game, because if it happened after we would have some strange paradox of needing to know the preprocessor to use in order to figure out which preprocessor to use.
This means that the information for which preprocessor to use should be (at 5%) determined by the raw intrustment or valuation information itself. Or potentially the endowment information. Huh this one has me stumped. Ok well for me the way this will work is... I'll set a
Oh shit. It occurrs to me 4% that if we do the P(false, honest) implementation then we'll be permitting people to slash their stake. But I thought we had previously convinced ourselves that that needed to be avoided. Well, there are two possibilities: either on slashing it disappears, or on slashing it goes to the negating points somehow. I think that the former is almost entirely game proof. The second one might have some games depending on implementation. Ok, so I guess it is the case that someone has the ability to slash their own tokens. Interesting. They could avoid doing that if they thought in the future it was going to go up in value. Nah, I don't think you can slash. You protect yourself against the risk of negatively valued tokens by decreasing yoru valuation yourself. 3% huh. wow.
Well, we've already decided that there can only be one preprocessor, so we don't have to do any blending of outputs or weird stuff like that. So I guess whatever is the highest valued preprocessor for you should be the one used at the time of execution. Interesting.
This leaves a bunch open but given my limited time I want to explore only one thing which is quite far away from this in the space of execution order but closely related in some way. If in my communiter I'm a dissenter and I think that X should happen while the rest of the community thinks Y should happen, what do we do about this? Huh, well let's say Y means fine someone and X means don't fine them. Then if I believe X I should get the people fined by Y as my customers, and I don't worry too much about the fine in their account because it gets treated as valueless by me. In this story violence is still a risk, it's not like we've obviated it. But. That extremely strong incentive for concilience should save us. Unity will strictly dominate dischord.
I'm worried. If you make something optional like the principle of precarity then I think much more harm can be done with this system. Then again, that's just my prior. I think this. Should I be able to impose my will on everyone else?

Summary

We've gone thorugh it! it's 3:57. I have 1% left. I know what to do next.
Ok, I'm now home. That was a great session I'm glad we ran out of batteries haha. I have 2.5 hours now to figure out the next step. What's there to do?
Well, I get the sense that Epistemic Leverage is not something that we're going to implement right now. So much ambiguity it opens up. So what do we do instead?
We either do search or we name points. what will give us something interesting to show tomorrow?
I think it would actually be quite fun to work on the famous einstein problem using this. We'll try both things: 1. we'll try to create a python api to encode ideas in this 2. we'll then perform some search to find the "right" belief
Lots to think about here but I actually think that the constraints of the search might be informative to briefly consider as we start out. We're going to be able to perform gradient descent on end points but not on linking points. The problem with linking points is that they have a non-differentiable impact on the other points, if the linking point is ≤0 then it doesn't let any negation pass, if it's >0 it does. So you have all these boundary conditions to consider, and that's without even considering the complexity of a linking point that works for the first couple iterations of the negation and then gets killed and stops working. To me, this implies that there should be two steps to the process: 1. find the lowest loss valuation for the end points, masking out the linking points, using stochastic gradient descent 2. create a poplation of identical graphs and add negating points and change the valuation of linking points randomly, then repeat step one and kill off the bottom 75% of graphs
the random additions and linkages can actually be a selection from the library of useful moves that we make in step 1. In fact, this is an argument that those moves should themselves be something that can be discovered in the course of the search. This has something to do with prototypes / general functions. Ok, so this question should guide our initial work. We know at least one thing: it's possible to create a simple prototype which takes an existing point and replaces one of its arguments. E.g. if I have the point, "The Dalai Lama is a trustworthy leader." you can imagine that many of the invalidating points (and double invalidating points, etc) that apply to the Dalai Lama would apply more generally to any leader, e.g. "$variable is a trustworthy leader." which would then bring with it all of its sub points. Ofc, as you got further from the top you'd tend to find that they don't apply anymore, and they're in the details, but that ends up being a fairly simple criteria for search. E.g. you manually build out the template, or you could just take the alpha-beta pairs up to some depth like 3. Here by alpha beta pairs I'm referring to the primary point "variable is good" and its negation "variable is not good". By the time you get to an ab depth of 3 I'll bet you're pretty deep into the weeds. What would be cool then is to have a language in which points could refer to other points. It's hard to do this with negating points, because they are used for negation. You wouldn't want to point a point at another point using a linking point for that to simultaneously mean "this isn't true" as well as "this is a useful template" would you?
Hmm, well just to red team for a second, it would seem like if you're pointing at something as untrue, it must matter. In other words, it's important that you're pointing. So maybe you could argue that it really is useful... but I mean, no, that's so strange. How would you grab an entire tree of arguments, how would you know which ones to include and exclude, if there was a sub-tree that delicately mattered how would you replicate it? No, that's not what we want.
What we want is node that also has replication links to other nodes. And if that node is non-zero, or perhaps based on its valuation, you randomly pick it from the population to be applied somewhere in the stack. And this should be enough to get us started because now what we want to pay attention to as we get to work is what kinds of transformations we tend to abstract when we create this new higher level language. Let us begin.
Step 1 here is going to be to just get this up and running by appending deltas. The language can actually be really simple. We'll start off a state with something like: ```python state = State() ``` Then we'll probably add a point, hmm I want something monadic. Maybe we don't use state? maybe we use point(state, arg...) and it returns... what? the new point and the state? ok why do we want to get the point back? We want to be able to do things like link(flat_earth, round_earth, arg...) but then we'll have to return both the state and the point. I guess we don't have to return the state. but what's going to be more common state.point(arg).link(other_point) where we're linking the new point no the other point, or state.point().point() where we create multiple points? Clearly the former. What about state.link(point, other_point).link() ah yeah. I like that. Ok, so clearly we define state and then modify state in place. That means that state should probably have a fork method.
What do we do about the fact that we need want to chain these but they'll be returning a tuple? I think I have an idea
Ok, here’s the finalized python api
class State():
def __init__(s):
s.deltas = ""
s.pointcount = 0
def point(s, amount=1):
s.deltas += f"point {amount}\n"
point = Point(s, s.pointcount)
s.pointcount += 1
return point
def link(s, source, target):
"""
Link source point to target point
"""
s.deltas += f"link {source} {target}\n"
point = Point(s, s.pointcount)
s.pointcount += 1
return point

def intrust(s, point, amount):
s.deltas += f"intrust {point} {amount}\n"
return point
def negate(s, point, amount = 1):
return s.point(amount).link(point)
def fork(s):
return copy.copy(s)
def graph(s):
graph(*build(s.deltas))
def credence(s, *kwargs):
return credence(*build(s.deltas), *kwargs)
def __repr__(s):
return s.deltas
class Point():
def __init__(s, state, index):
s.state = state
s.index = index
def point(s, amount):
return s.state.point(amount)
def link(s, target):
return s.state.link(s, target)
def intrust(s, amount):
return s.state.intrust(s, amount)
def negate(s, amount = 1):
s.state.negate(s, amount)
def __repr__(s):
return str(s.index)

The usage is gorgeous
state = State()
point1 = state.point()
state2 = state.fork()
point2 = state2.point().link(point1).intrust(100)
seventeen = point2.negate(17)

state.graph()
state2.credence()

Note, if you want to use this yourself, you’ll need this code for the build, credence, and graph functions which you can find here:
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.