Risk flags
Accounts flagged from the signals against them, the flag stored bare and with its evidence: a withdrawn signal leaves the bare flag standing, and the evidence store recomputes just the flags that rested on it.
Every screen below was recorded under CPython. When this page was built, the EML interpreter replayed each session from the same input and printed the same bytes.
About
Accounts flagged from the signals against them, the flag stored two ways: as a bare yes or no, and with the evidence it rests on.
main.eml- the menu, the accounts with their signals and both stored flags, withdrawing a signal, adding one, the checks, and the nightly recomputeflags.eml- the accounts and their signals, the rule, the evidence a flag rests on, both stores built from the signals, and finding and removing a signal
How each part works:
- The rule: two or more signals against an account, or any one of severity 3. Five accounts start with seven signals - a chargeback on a-1, two small signals on a-2, a report and a new device on a-4 - and a-1, a-2 and a-4 are flagged.
- As in the corpus case
flag-outlives-its-evidence, a flag is computed from what the system knew and stored. Withdraw the chargeback on a-1 and the bare flag stays: nothing records that it came from that signal, so nothing knows to clear it. The flag kept with its evidence rested on that signal, so it is recomputed, and clears. - Withdrawing only ever makes a flag stale; a new signal recomputes its account in both stores, so neither ever misses a flag. The checks compare both stores with the rule on the signals on file, split by direction.
- The nightly recompute rights the bare store, a day late and only by recomputing every flag; the evidence store recomputes just the flags that rested on what was withdrawn.
What is checked: menu choices 1 to 6; a signal on file to withdraw; an account from 1 to 5 and a severity from 1 to 3 for a new signal. An empty answer cancels.
Sessions: sessions/basic.in gives: - the accounts and the checks; s-1 and s-3 withdrawn; the accounts and the checks again; - a severity-3 signal added on a-3; the accounts, the nightly recompute and the checks.
sessions/bad-input.in gives: - menu choices 0 and x; - withdrawing: a cancel, s-99, then s-1 twice; - adding: a cancel and 6 for the account, then a-2 with a cancel, 4 and x for the severity; a signal on a-5; - the nightly recompute twice, and the checks.
Built on the verified corpus case flag-outlives-its-evidence (a stored flag with no link back to the evidence it was derived from, re-derived and compared by direction).
Recorded sessions
What the screen shows while someone uses the program. Each typed line appears after its prompt, the way a terminal shows it.
bad-input
interpreter: byte-equal== Risk flags ==
Accounts flagged from the signals against them: a bare flag, and a flag that keeps its evidence.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 0
Pick a number from 1 to 6.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> x
Pick a number from 1 to 6.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 2
signal to withdraw (e.g. s-1)>
Cancelled.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 2
signal to withdraw (e.g. s-1)> s-99
There is no signal s-99 on file.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 2
signal to withdraw (e.g. s-1)> s-1
Signal s-1 (chargeback on a-1) withdrawn.
flag only: a-1 stays flagged; nothing records that the flag came from s-1.
with its evidence: a-1's flag rested on s-1; recomputed, it clears.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 2
signal to withdraw (e.g. s-1)> s-1
There is no signal s-1 on file.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 3
account (1 to 5)>
Cancelled.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 3
account (1 to 5)> 6
Type an account from 1 to 5.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 3
account (1 to 5)> 2
severity (1 to 3)>
Cancelled.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 3
account (1 to 5)> 2
severity (1 to 3)> 4
Type a severity from 1 to 3.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 3
account (1 to 5)> 2
severity (1 to 3)> x
Type a severity from 1 to 3.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 3
account (1 to 5)> 5
severity (1 to 3)> 1
Signal s-8 of severity 1 added on a-5; both stores recompute a-5: flagged.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 5
The nightly job recomputes all 5 flags from the signals on file; 1 changes.
It clears what a withdrawal left behind, a day late, and only because it recomputes every flag; the evidence store recomputed only the flags that rested on what was withdrawn.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 5
The nightly job recomputes all 5 flags from the signals on file; none changes.
Nothing had gone stale since the last recompute.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 4
Each stored flag against the flag the rule gives on the signals on file now:
flag only: should have cleared none; should have been raised none
flag with its evidence: should have cleared none; should have been raised none
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 6
Bye.
What was typed (30 lines)
0
x
2
2
s-99
2
s-1
2
s-1
3
3
6
3
2
3
2
4
3
2
x
3
5
1
5
5
4
6
basic
interpreter: byte-equal== Risk flags ==
Accounts flagged from the signals against them: a bare flag, and a flag that keeps its evidence.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 1
account signals now flag only flag with its evidence
a-1 s-1:3 flagged flagged flagged (s-1)
a-2 s-2:1, s-3:1 flagged flagged flagged (s-2, s-3)
a-3 s-4:2 - - -
a-4 s-5:1, s-6:2 flagged flagged flagged (s-5, s-6)
a-5 s-7:1 - - -
signal:severity; the rule: two or more signals, or any one of severity 3
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 4
Each stored flag against the flag the rule gives on the signals on file now:
flag only: should have cleared none; should have been raised none
flag with its evidence: should have cleared none; should have been raised none
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 2
signal to withdraw (e.g. s-1)> s-1
Signal s-1 (chargeback on a-1) withdrawn.
flag only: a-1 stays flagged; nothing records that the flag came from s-1.
with its evidence: a-1's flag rested on s-1; recomputed, it clears.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 2
signal to withdraw (e.g. s-1)> s-3
Signal s-3 (new device on a-2) withdrawn.
flag only: a-2 stays flagged; nothing records that the flag came from s-3.
with its evidence: a-2's flag rested on s-3; recomputed, it clears.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 1
account signals now flag only flag with its evidence
a-1 none - flagged -
a-2 s-2:1 - flagged -
a-3 s-4:2 - - -
a-4 s-5:1, s-6:2 flagged flagged flagged (s-5, s-6)
a-5 s-7:1 - - -
signal:severity; the rule: two or more signals, or any one of severity 3
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 4
Each stored flag against the flag the rule gives on the signals on file now:
flag only: should have cleared a-1, a-2; should have been raised none
flag with its evidence: should have cleared none; should have been raised none
A withdrawn signal leaves the bare flag standing: the answer survived, and nothing says what it was the answer to.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 3
account (1 to 5)> 3
severity (1 to 3)> 3
Signal s-8 of severity 3 added on a-3; both stores recompute a-3: flagged.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 1
account signals now flag only flag with its evidence
a-1 none - flagged -
a-2 s-2:1 - flagged -
a-3 s-4:2, s-8:3 flagged flagged flagged (s-4, s-8)
a-4 s-5:1, s-6:2 flagged flagged flagged (s-5, s-6)
a-5 s-7:1 - - -
signal:severity; the rule: two or more signals, or any one of severity 3
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 5
The nightly job recomputes all 5 flags from the signals on file; 2 change.
It clears what a withdrawal left behind, a day late, and only because it recomputes every flag; the evidence store recomputed only the flags that rested on what was withdrawn.
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 4
Each stored flag against the flag the rule gives on the signals on file now:
flag only: should have cleared none; should have been raised none
flag with its evidence: should have cleared none; should have been raised none
1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit
choice> 6
Bye.
What was typed (15 lines)
1
4
2
s-1
2
s-3
1
4
3
3
3
1
5
4
6
Modules
The program as written, entry module first. Each module transpiles to its own Python file, which is what eml project run executes.
main.eml(entry)
eml# P159 risk flags: the accounts with their signals and both stored flags,
# withdrawing a signal, adding one, the nightly recompute, and the checks
# against the flags re-derived now.
import flags
def plain(s):
0 => i
len(s) => j
while i < j and s[i] == " ":
i + 1 => i
while j > i and s[j - 1] == " ":
j - 1 => j
return s[i:j]
def pad(s, n):
s => out
while len(out) < n:
out + " " => out
return out
def yes(b):
if b:
return "flagged"
return "-"
def listed(xs):
"" => out
for x in xs:
if out == "":
x => out
else:
out + ", " + x => out
if out == "":
return "none"
return out
def show(signals, pl, pr):
(" " + pad("account", 9) + pad("signals", 22) + pad("now", 9) + pad("flag only", 11) + "flag with its evidence") ^0
for a in flags.accounts():
[] => ids
for s in flags.against(signals, a):
ids + [s[0] + ":" + str(s[2])] => ids
if len(pr[a]) > 0:
"flagged (" + listed(pr[a]) + ")" => ev
else:
"-" => ev
(" " + pad(a, 9) + pad(listed(ids), 22) + pad(yes(flags.derive(signals, a)), 9) + pad(yes(pl[a]), 11) + ev) ^0
" signal:severity; the rule: two or more signals, or any one of severity 3" ^0
def withdraw(signals, pl, pr):
plain(input("signal to withdraw (e.g. s-1)> ")) => id
if id == "":
"Cancelled." ^0
return [signals, pl, pr]
flags.find(signals, id) => k
if k < 0:
("There is no signal " + id + " on file.") ^0
return [signals, pl, pr]
signals[k] => s
flags.without(signals, id) => after
("Signal " + id + " (" + s[3] + " on " + s[1] + ") withdrawn.") ^0
if pl[s[1]]:
(" flag only: " + s[1] + " stays flagged; nothing records that the flag came from " + id + ".") ^0
else:
(" flag only: " + s[1] + " was not flagged, and nothing changes.") ^0
{} => npr
[] => touched
for a in flags.accounts():
False => rested
for e in pr[a]:
if e == id:
True => rested
if rested:
flags.evidence(after, a) => npr[a]
touched + [a] => touched
else:
pr[a] => npr[a]
if len(touched) == 0:
" with its evidence: no flag rested on it, and nothing is recomputed." ^0
for a in touched:
if len(npr[a]) == 0:
(" with its evidence: " + a + "'s flag rested on " + id + "; recomputed, it clears.") ^0
else:
(" with its evidence: " + a + "'s flag rested on " + id + "; recomputed, it stands on " + listed(npr[a]) + ".") ^0
return [after, pl, npr]
def add(signals, pl, pr, n):
plain(input("account (1 to 5)> ")) => t
if t == "":
"Cancelled." ^0
return [signals, pl, pr, n]
if t != "1" and t != "2" and t != "3" and t != "4" and t != "5":
"Type an account from 1 to 5." ^0
return [signals, pl, pr, n]
flags.accounts()[int(t) - 1] => a
plain(input("severity (1 to 3)> ")) => v
if v == "":
"Cancelled." ^0
return [signals, pl, pr, n]
if v != "1" and v != "2" and v != "3":
"Type a severity from 1 to 3." ^0
return [signals, pl, pr, n]
"s-" + str(n) => id
signals + [[id, a, int(v), "new signal"]] => after
{} => npl
{} => npr
for x in flags.accounts():
pl[x] => npl[x]
pr[x] => npr[x]
flags.derive(after, a) => npl[a]
flags.evidence(after, a) => npr[a]
("Signal " + id + " of severity " + v + " added on " + a + "; both stores recompute " + a + ": " + yes(npl[a]) + ".") ^0
return [after, npl, npr, n + 1]
def checks(signals, pl, pr):
[] => stale1
[] => missing1
[] => stale2
[] => missing2
for a in flags.accounts():
flags.derive(signals, a) => now
if pl[a] and not now:
stale1 + [a] => stale1
if not pl[a] and now:
missing1 + [a] => missing1
if len(pr[a]) > 0 and not now:
stale2 + [a] => stale2
if len(pr[a]) == 0 and now:
missing2 + [a] => missing2
"Each stored flag against the flag the rule gives on the signals on file now:" ^0
(" flag only: should have cleared " + listed(stale1) + "; should have been raised " + listed(missing1)) ^0
(" flag with its evidence: should have cleared " + listed(stale2) + "; should have been raised " + listed(missing2)) ^0
if len(stale1) > 0:
"A withdrawn signal leaves the bare flag standing: the answer survived, and nothing says what it was the answer to." ^0
def nightly(signals, pl):
flags.plain_store(signals) => npl
0 => changed
for a in flags.accounts():
if npl[a] != pl[a]:
changed + 1 => changed
if changed == 0:
"none changes" => said
elif changed == 1:
"1 changes" => said
else:
str(changed) + " change" => said
("The nightly job recomputes all " + str(len(flags.accounts())) + " flags from the signals on file; " + said + ".") ^0
if changed > 0:
"It clears what a withdrawal left behind, a day late, and only because it recomputes every flag; the evidence store recomputed only the flags that rested on what was withdrawn." ^0
else:
"Nothing had gone stale since the last recompute." ^0
return npl
flags.opening() => signals
flags.plain_store(signals) => pl
flags.proven_store(signals) => pr
8 => next_id
"== Risk flags ==" ^0
"Accounts flagged from the signals against them: a bare flag, and a flag that keeps its evidence." ^0
True => running
while running:
"" ^0
"1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit" ^0
plain(input("choice> ")) => choice
if choice == "1":
show(signals, pl, pr)
elif choice == "2":
withdraw(signals, pl, pr) => r
r[0] => signals
r[1] => pl
r[2] => pr
elif choice == "3":
add(signals, pl, pr, next_id) => r
r[0] => signals
r[1] => pl
r[2] => pr
r[3] => next_id
elif choice == "4":
checks(signals, pl, pr)
elif choice == "5":
nightly(signals, pl) => pl
elif choice == "6":
False => running
else:
"Pick a number from 1 to 6." ^0
"Bye." ^0
Python projection (main.py)
import flags
def plain(s):
i = 0
j = len(s)
while i < j and s[i] == " ":
i = i + 1
while j > i and s[j - 1] == " ":
j = j - 1
return s[i:j]
def pad(s, n):
out = s
while len(out) < n:
out = out + " "
return out
def yes(b):
if b:
return "flagged"
return "-"
def listed(xs):
out = ""
for x in xs:
if out == "":
out = x
else:
out = out + ", " + x
if out == "":
return "none"
return out
def show(signals, pl, pr):
print(" " + pad("account", 9) + pad("signals", 22) + pad("now", 9) + pad("flag only", 11) + "flag with its evidence")
for a in flags.accounts():
ids = []
for s in flags.against(signals, a):
ids = ids + [s[0] + ":" + str(s[2])]
if len(pr[a]) > 0:
ev = "flagged (" + listed(pr[a]) + ")"
else:
ev = "-"
print(" " + pad(a, 9) + pad(listed(ids), 22) + pad(yes(flags.derive(signals, a)), 9) + pad(yes(pl[a]), 11) + ev)
print(" signal:severity; the rule: two or more signals, or any one of severity 3")
def withdraw(signals, pl, pr):
id = plain(input("signal to withdraw (e.g. s-1)> "))
if id == "":
print("Cancelled.")
return [signals, pl, pr]
k = flags.find(signals, id)
if k < 0:
print("There is no signal " + id + " on file.")
return [signals, pl, pr]
s = signals[k]
after = flags.without(signals, id)
print("Signal " + id + " (" + s[3] + " on " + s[1] + ") withdrawn.")
if pl[s[1]]:
print(" flag only: " + s[1] + " stays flagged; nothing records that the flag came from " + id + ".")
else:
print(" flag only: " + s[1] + " was not flagged, and nothing changes.")
npr = {}
touched = []
for a in flags.accounts():
rested = False
for e in pr[a]:
if e == id:
rested = True
if rested:
npr[a] = flags.evidence(after, a)
touched = touched + [a]
else:
npr[a] = pr[a]
if len(touched) == 0:
print(" with its evidence: no flag rested on it, and nothing is recomputed.")
for a in touched:
if len(npr[a]) == 0:
print(" with its evidence: " + a + "'s flag rested on " + id + "; recomputed, it clears.")
else:
print(" with its evidence: " + a + "'s flag rested on " + id + "; recomputed, it stands on " + listed(npr[a]) + ".")
return [after, pl, npr]
def add(signals, pl, pr, n):
t = plain(input("account (1 to 5)> "))
if t == "":
print("Cancelled.")
return [signals, pl, pr, n]
if t != "1" and t != "2" and t != "3" and t != "4" and t != "5":
print("Type an account from 1 to 5.")
return [signals, pl, pr, n]
a = flags.accounts()[int(t) - 1]
v = plain(input("severity (1 to 3)> "))
if v == "":
print("Cancelled.")
return [signals, pl, pr, n]
if v != "1" and v != "2" and v != "3":
print("Type a severity from 1 to 3.")
return [signals, pl, pr, n]
id = "s-" + str(n)
after = signals + [[id, a, int(v), "new signal"]]
npl = {}
npr = {}
for x in flags.accounts():
npl[x] = pl[x]
npr[x] = pr[x]
npl[a] = flags.derive(after, a)
npr[a] = flags.evidence(after, a)
print("Signal " + id + " of severity " + v + " added on " + a + "; both stores recompute " + a + ": " + yes(npl[a]) + ".")
return [after, npl, npr, n + 1]
def checks(signals, pl, pr):
stale1 = []
missing1 = []
stale2 = []
missing2 = []
for a in flags.accounts():
now = flags.derive(signals, a)
if pl[a] and not now:
stale1 = stale1 + [a]
if not pl[a] and now:
missing1 = missing1 + [a]
if len(pr[a]) > 0 and not now:
stale2 = stale2 + [a]
if len(pr[a]) == 0 and now:
missing2 = missing2 + [a]
print("Each stored flag against the flag the rule gives on the signals on file now:")
print(" flag only: should have cleared " + listed(stale1) + "; should have been raised " + listed(missing1))
print(" flag with its evidence: should have cleared " + listed(stale2) + "; should have been raised " + listed(missing2))
if len(stale1) > 0:
print("A withdrawn signal leaves the bare flag standing: the answer survived, and nothing says what it was the answer to.")
def nightly(signals, pl):
npl = flags.plain_store(signals)
changed = 0
for a in flags.accounts():
if npl[a] != pl[a]:
changed = changed + 1
if changed == 0:
said = "none changes"
elif changed == 1:
said = "1 changes"
else:
said = str(changed) + " change"
print("The nightly job recomputes all " + str(len(flags.accounts())) + " flags from the signals on file; " + said + ".")
if changed > 0:
print("It clears what a withdrawal left behind, a day late, and only because it recomputes every flag; the evidence store recomputed only the flags that rested on what was withdrawn.")
else:
print("Nothing had gone stale since the last recompute.")
return npl
signals = flags.opening()
pl = flags.plain_store(signals)
pr = flags.proven_store(signals)
next_id = 8
print("== Risk flags ==")
print("Accounts flagged from the signals against them: a bare flag, and a flag that keeps its evidence.")
running = True
while running:
print("")
print("1) accounts 2) withdraw a signal 3) add a signal 4) checks 5) the nightly recompute 6) quit")
choice = plain(input("choice> "))
if choice == "1":
show(signals, pl, pr)
elif choice == "2":
r = withdraw(signals, pl, pr)
signals = r[0]
pl = r[1]
pr = r[2]
elif choice == "3":
r = add(signals, pl, pr, next_id)
signals = r[0]
pl = r[1]
pr = r[2]
next_id = r[3]
elif choice == "4":
checks(signals, pl, pr)
elif choice == "5":
pl = nightly(signals, pl)
elif choice == "6":
running = False
else:
print("Pick a number from 1 to 6.")
print("Bye.")
flags.eml
eml# P159 risk flags - accounts flagged from the signals against them, the flag
# stored two ways. As in the corpus case flag-outlives-its-evidence, a flag
# is computed once from what the system knew and stored as a yes or no; the
# signals it came from can be withdrawn - a chargeback reversed, a report
# retracted - and with no record of which signals a flag came from, nothing
# knows to clear it. The second store keeps each flag's evidence beside it,
# so a withdrawn signal reaches exactly the flags that rested on it. A
# signal is [id, account, severity, what]; the rule: two or more signals,
# or any one of severity 3.
def accounts():
return ["a-1", "a-2", "a-3", "a-4", "a-5"]
def opening():
return [["s-1", "a-1", 3, "chargeback"], ["s-2", "a-2", 1, "address change"], ["s-3", "a-2", 1, "new device"], ["s-4", "a-3", 2, "velocity"], ["s-5", "a-4", 1, "new device"], ["s-6", "a-4", 2, "report"], ["s-7", "a-5", 1, "address change"]]
def against(signals, account):
[] => out
for s in signals:
if s[1] == account:
out + [s] => out
return out
def derive(signals, account):
# the rule, as it lives in the code
against(signals, account) => mine
if len(mine) >= 2:
return True
for s in mine:
if s[2] >= 3:
return True
return False
def evidence(signals, account):
# the ids a flag rests on: the account's signals when the rule raises it
[] => ids
if derive(signals, account):
for s in against(signals, account):
ids + [s[0]] => ids
return ids
def plain_store(signals):
# account -> flag, computed from the signals as they are now
{} => st
for a in accounts():
derive(signals, a) => st[a]
return st
def proven_store(signals):
# account -> the evidence ids its flag rests on ([] for no flag)
{} => st
for a in accounts():
evidence(signals, a) => st[a]
return st
def find(signals, id):
0 => i
for s in signals:
if s[0] == id:
return i
i + 1 => i
return 0 - 1
def without(signals, id):
[] => out
for s in signals:
if s[0] != id:
out + [s] => out
return out
Python projection (flags.py)
def accounts():
return ["a-1", "a-2", "a-3", "a-4", "a-5"]
def opening():
return [["s-1", "a-1", 3, "chargeback"], ["s-2", "a-2", 1, "address change"], ["s-3", "a-2", 1, "new device"], ["s-4", "a-3", 2, "velocity"], ["s-5", "a-4", 1, "new device"], ["s-6", "a-4", 2, "report"], ["s-7", "a-5", 1, "address change"]]
def against(signals, account):
out = []
for s in signals:
if s[1] == account:
out = out + [s]
return out
def derive(signals, account):
mine = against(signals, account)
if len(mine) >= 2:
return True
for s in mine:
if s[2] >= 3:
return True
return False
def evidence(signals, account):
ids = []
if derive(signals, account):
for s in against(signals, account):
ids = ids + [s[0]]
return ids
def plain_store(signals):
st = {}
for a in accounts():
st[a] = derive(signals, a)
return st
def proven_store(signals):
st = {}
for a in accounts():
st[a] = evidence(signals, a)
return st
def find(signals, id):
i = 0
for s in signals:
if s[0] == id:
return i
i = i + 1
return 0 - 1
def without(signals, id):
out = []
for s in signals:
if s[0] != id:
out = out + [s]
return out