In [4]:
import nengo.spa as spa

D = 128
vocab = spa.Vocabulary(D)

class SigmoidRule(object):
    def __init__(self, pre, post, threshold=0.5, gain=10):
        self.threshold = threshold
        self.gain = gain
        self.pre = vocab.parse(pre).v
        self.post = vocab.parse(post).v
    def apply(self, state):
        x = np.dot(state, self.pre)
        if x < 0:
            x = 0
        v = x * 2
        #v = (x -self.threshold) * 1
        #v = np.arctan((x-self.threshold)*self.gain)*2/np.pi
        return v * self.post
    
class PairRule(object):
    def __init__(self, pre1, pre2, post, threshold=0.5, gain=10):
        self.threshold = threshold
        self.gain = gain
        self.pre1 = vocab.parse(pre1).v
        self.pre2 = vocab.parse(pre2).v
        self.post = vocab.parse(post).v
    def apply(self, state):
        x = np.dot(state, self.pre1) * np.dot(state, self.pre2)
        if x < 0:
            x = 0
        v = x * 2
        #v = (x -self.threshold) * 1
        #v = np.arctan((x-self.threshold)*self.gain)*2/np.pi
        return v * self.post
    

    
nouns = ['DOG', 'CAT', 'N0', 'N1'][:2]
verbs = ['CHASE', 'V0', 'V1'][:1]

rules = []

for noun in nouns:
    rules.append(SigmoidRule(noun, 'N_'+noun))
    rules.append(SigmoidRule('N_'+noun, '-1*'+noun))
    
    rules.append(SigmoidRule('N_'+noun, 'NP_'+noun))
    rules.append(SigmoidRule('NP_'+noun, '-1*N_'+noun))
for verb in verbs:
    rules.append(SigmoidRule(verb, 'V_'+verb))
    rules.append(SigmoidRule('V_'+verb, '-1*'+verb))
    
    for noun in nouns:
        rules.append(PairRule('V_'+verb, 'N_'+noun, '3*VP_'+verb+'_'+noun+'-2*NP_'+noun))

In [5]:
state = vocab.parse('0').v
tau = 0.01

T = 100

stims = 'DOG CHASE CAT 0'.split()
state_gain = 0.01
data = []
for stim in stims:
    for t in range(T):
        state += vocab.parse(stim).v * tau
        
        delta = state * 0
        for r in rules:
            delta += r.apply(state)
        state += delta * tau + (state_gain * state)
        
        norm = np.linalg.norm(state) / 2
        if norm > 1:
            state = state / norm
        
        data.append(state.copy())
data = np.array(data)

In [6]:
figure(figsize=(12,6))
lines = plot(vocab.dot(data.T).T, linewidth=4)
legend(lines, vocab.keys, loc='best')
title(vocab.text(state))
show()



In [151]:


In [ ]: