<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Posts on Tal Globus</title>
        <link>https://talglobus.com/post/</link>
        <description>Recent content in Posts on Tal Globus</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <lastBuildDate>Mon, 09 Mar 2026 15:10:49 -0700</lastBuildDate><atom:link href="https://talglobus.com/post/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Expect It to Fail</title>
        <link>https://talglobus.com/p/expect-it-to-fail/</link>
        <pubDate>Thu, 29 Jan 2026 00:02:56 -0800</pubDate>
        
        <guid>https://talglobus.com/p/expect-it-to-fail/</guid>
        <description>&lt;p&gt;What does the worst possible intern look like? You give them a task, they run off, and return hours later with something entirely wrong. You nudge them on why it&amp;rsquo;s wrong, send them off again, and they return with something wrong in a different way. After enough rounds of correction, they finally produce what you wanted — with dramatically more time spent correcting them than you&amp;rsquo;d have spent doing it yourself.&lt;/p&gt;
&lt;p&gt;What about the best possible intern? You give them a task, and they return hours later with exactly what you wanted.&lt;/p&gt;
&lt;p&gt;The detail the interns don&amp;rsquo;t generally share: both followed the same process, both failed a few times. The second one just didn&amp;rsquo;t show you the failures.&lt;/p&gt;
&lt;p&gt;Most output we encounter in the world is like this. Behind every witty text you receive is a notes app full of discarded drafts. Behind every finished movie scene are dozens of takes with mumbled lines and poor timing. We&amp;rsquo;ve come to expect polished output precisely because the iteration that produced it stays hidden.&lt;/p&gt;
&lt;p&gt;But AI tools don&amp;rsquo;t work this way, at least not yet.&lt;/p&gt;
&lt;p&gt;When working with AI, it&amp;rsquo;s common for the tool to misunderstand your intent or fail at the task multiple times, with you nudging it to continue or try differently until it succeeds. This is a natural workflow when working with AI, but it&amp;rsquo;s deeply unnatural when working with people, because it&amp;rsquo;s the workflow of the worst possible intern.&lt;/p&gt;
&lt;p&gt;The result is a gap between the opinions of new and experienced AI users. New users give the tool a task, watch it fail, and conclude that AI is incapable of real work. This would be reasonable behavior when evaluating a human expert (which incidentally is how these tools are often marketed) but it misses that AI tools are not yet capable of hiding their attempts from you. Experienced users ask the AI to keep trying, describing a feeling of &amp;ldquo;nudging&amp;rdquo; or &amp;ldquo;prodding&amp;rdquo; the AI past its failures until it completes the task. The end result is the same as the movie scene; you&amp;rsquo;re just forced to endure all the bad takes along the way.&lt;/p&gt;
&lt;p&gt;This will partially resolve with time. AI products are already growing more deliberate about obscuring failures from users. Spend a few minutes asking ChatGPT to do complex research and read through its reasoning summaries, a large portion will consist of the model struggling with paywalls, random errors, its own moderation system, and so on. Some improvement, however, requires better contextual understanding on the part of the AI. Often the intern doesn&amp;rsquo;t fail because they can&amp;rsquo;t complete the task, but because they fail to grasp the request and the context required to interpret it. I&amp;rsquo;m optimistic about AI memory systems for exactly this reason.&lt;/p&gt;
&lt;p&gt;But a subtler dynamic is also at play. If you expect the AI to make mistakes, you&amp;rsquo;ll want to observe what it does, and you&amp;rsquo;ll be disappointed by the failures that even a successful outcome required. If you trust the AI enough not to watch, you won&amp;rsquo;t witness those failures.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; This creates a cold start problem: early, skeptical users see AI as far less reliable than users willing to let it work unsupervised. Trust begets more trust; distrust, more evidence for distrust.&lt;/p&gt;
&lt;p&gt;For now, perhaps the best advice for early adopters is this: judge AI not by the first things it does, but by the last.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;AI tools are still fairly spiky in the shape of their capabilities, with expert-level performance in certain types of tasks and monkey-like performance in others. To learn which is which, it&amp;rsquo;s often helpful to spend your first few weeks or months helicopter parenting your AI to develop an understanding of when you can walk away. As this isn&amp;rsquo;t good for building trust, becoming AI-proficient requires some combination of tolerance for failure and an unusally strong long-game mentality&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>Doing Something That’s Never Been Done Before</title>
        <link>https://talglobus.com/p/doing-something-thats-never-been-done-before/</link>
        <pubDate>Fri, 14 Nov 2025 02:03:22 -0800</pubDate>
        
        <guid>https://talglobus.com/p/doing-something-thats-never-been-done-before/</guid>
        <description>&lt;p&gt;I’ve found recently that I’ve been a bit hesitant to take on new projects, especially of the interesting variety, largely out of a fear that I’m doing something unoriginal. As anyone who has spent any substantial amount of time in the markets will tell you, being second to an idea isn’t necessarily terrible, but being 50th generally is, and I’d really rather avoid being 50th whenever possible. How do you guarantee, or at least maximize the odds, that whatever you’re doing, you’re the first?&lt;/p&gt;
&lt;p&gt;It seems there are actually a few good rules of thumb to this.&lt;/p&gt;
&lt;p&gt;First and foremost, people have lives. They only have so much time they can give a project, and the more time a project takes up, the more likely they’ll either decide not to take it on, or that they’ll run out of time and not come back to it later.&lt;/p&gt;
&lt;p&gt;The same goes for difficulty. While I wouldn’t say that people, by their nature, are lazy, I would say that evolution has favored this behavioral pattern where people tend to be less likely to do things that are more difficult, or involve a greater number of steps. As a result, the greater the degree of difficulty an endeavor requires, or the greater the number of steps, the less likely that someone has done it, or that they’ve finished after starting.&lt;/p&gt;
&lt;p&gt;Next, obscurity. I don’t think it should come as much of a surprise that the more obscure the thing that you’re thinking of doing, the lower the likelihood that someone has stumbled on it and done it.&lt;/p&gt;
&lt;p&gt;Finally, there seems to be this fourth factor combining obscurity and the number of steps in cases of progressive dependency, where later steps require previous steps to be completed to even be discovered. Say one in 10 people in your industry will stumble on whatever idea you happen to have first. Then maybe one in 10 people who complete the step following the first idea will discover the second idea, and then one in 10 of those who complete the second will also discover the third. It stands to reason that the more steps your project requires, the less likely it is that someone else will have stumbled on all of them.&lt;/p&gt;
&lt;p&gt;So if you want to truly do something that no one has done before, do something obscure, do something time-consuming, do something difficult, and do something that has unknowns you’ll only resolve once you complete the first bits. The more of these your project involves, the lower the number of people who will have done it. Enough, and it’s probably fairly likely you’ll be the first.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>A Follow-up to US Government Math</title>
        <link>https://talglobus.com/p/a-follow-up-to-us-government-math/</link>
        <pubDate>Mon, 07 Jul 2025 07:03:16 -0700</pubDate>
        
        <guid>https://talglobus.com/p/a-follow-up-to-us-government-math/</guid>
        <description>&lt;p&gt;I wanted to give a bit more information on how I wrote &lt;a class=&#34;link&#34; href=&#34;https://talglobus.com/p/us-government-math/&#34; &gt;that piece&lt;/a&gt;. I wrote it in a very different way from how I usually write, and I want to try out this new method to see how it works. I’m sharing my process for anyone interested in writing, or just curious about how I’ll probably be doing this going forward.&lt;/p&gt;
&lt;p&gt;I started, as many of these posts do, by talking to myself and realizing within a minute or so that I had a pretty good argument and wanted to get it down somewhere. Usually I would sit down and type out my argument, but I’ve found that typing tends to lead to a very different process from speaking. I do my best discovery by speaking out loud—ideally, though not necessarily, while alone.&lt;/p&gt;
&lt;p&gt;So I started a recording and just kept talking. I spoke for roughly half an hour, thinking through my arguments, pausing when I needed to, and restarting twice. I ended up with a recording of everything I’d said and added notes like “maybe cut that sentence” or “make sure this fact is correct” where appropriate.&lt;/p&gt;
&lt;p&gt;Then I fed the recording to a transcription tool and copied the transcript into &lt;a class=&#34;link&#34; href=&#34;https://platform.openai.com/docs/models/o3-pro&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI’s o3-pro&lt;/a&gt; with the following prompt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Take this poor-quality transcript of a first draft of a speech, complete with stutters, restarts, and repetitions, and turn it into a single, well-drafted, cohesive version of the same. Don&amp;rsquo;t change the structure, wording, or argument unless absolutely necessary, though it would help if you could point out areas to tighten or clean up. Check the numbers and make sure they&amp;rsquo;re correct, adding footnotes with the math where possible. My source for the spending data was &lt;a class=&#34;link&#34; href=&#34;https://www.visualcapitalist.com/breaking-down-the-u-s-governments-2024-fiscal-year/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.visualcapitalist.com/breaking-down-the-u-s-governments-2024-fiscal-year/&lt;/a&gt; and my source for the wealth tax impact was &lt;a class=&#34;link&#34; href=&#34;https://www.vox.com/policy-and-politics/2019/2/12/18211833/wealth-tax-calculator-warren-sanders&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.vox.com/policy-and-politics/2019/2/12/18211833/wealth-tax-calculator-warren-sanders&lt;/a&gt; and I calculated the effect of the 10% additional income tax on the top 1% as 3.3 million (number of 1% in US by overall population, assuming that&amp;rsquo;s the denominator in the 800k cutoff) * $800,000 (the approximate income cutoff to be a one percenter, though I asked AI instead of having a solid source for that). Check my facts, and make sure I didn&amp;rsquo;t say anything wrong. Critique my arguments, and suggest improvements or additional points where necessary. Finally, feel free to add anything else to the markup you think would be helpful.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the transcript I&amp;rsquo;ve got:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Pasted transcript here)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The draft I got back laid out my argument much closer to how I wanted it but still needed some improvements for transparency. I revised it—mostly addressing the points o3-pro flagged—then published the final version here.&lt;/p&gt;
&lt;p&gt;The whole process took about 45 minutes for recording and transcription, five minutes for the AI pass, and another one to two hours of editing, some with AI, some without (the entire next paragraph, for example, I added manually as part of my final edit). I’m happy with where the piece ended up: it sticks to my original message far more closely than my old manual method, and o3-pro really is a fantastic writing partner.&lt;/p&gt;
&lt;p&gt;The biggest issue I spotted is o3-pro really likes to paraphrase. I’d guess this is by design, as you don’t want to use it to write or edit a piece, only to find it plagiarized an existing source verbatim. I switched to o3 after a while, particularly after the original source analysis and error correction was done. O3 is better at not paraphrasing, but still often cut out substantive sections, or suggested edits as a series of bullet points specifying changes rather than rewriting the entire piece with edits each time around. I’d imagine both of these flaws is due to a desire on OpenAI’s part to minimize excessive token use in their fixed-cost ChatGPT product. It’s fairly straightforward to train a large language model to be more concise, and it’s certainly more cost-effective.&lt;/p&gt;
&lt;p&gt;I’ve read the piece end to end a few times and can’t spot a section that doesn’t sound like me. I’ll probably stick with this approach going forward, partly because I’m much more fluent aloud than at the keyboard. If you’re curious: yes, this follow-up was produced in the same way, though with a lot less editing. Below is the completely unedited transcript from this very piece for reference.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;unedited-transcript-verbatim&#34;&gt;&lt;strong&gt;Unedited transcript (verbatim)&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;A follow up to US government math. So I wanted to give a bit more info on how I wrote that piece. I wrote it in a very different way from how I usually write. I want to try out this new method see how it works. So I share my process for anyone else who&amp;rsquo;s interested in writing or just curious about how I&amp;rsquo;m probably going to be doing this going forward, I started as many of these speeches do, by talking to myself and realizing within a minute or so that I had a pretty good argument and I wanted to get it down somewhere. Now this is usually where I would sit down and actually try to type out my argument, but I&amp;rsquo;ve always found that typing tends to lead a very different lead to a very different process in speaking. And I do my best discovery by speaking out loud, ideally, but not necessarily, while alone, actually, maybe cut that section. Yeah, maybe cut that section. So at this point, I started a recording, and just kept talking. I spoke for roughly half an hour, thinking through my different arguments, pausing where I wanted to pause and restarting twice, and ended up with a recording of everything that I had said and I would put in before, and ending up with recording, I would put it in one more like comma and then the words and adding notes like maybe cut that sentence or make sure this fact is correct, where appropriate. All right, back to the end of the piece. Then I fed this transcript, sorry. Then I fed this recording to a transcription tool, and copy and pasted the transcript into open AI&amp;rsquo;s 03 Pro, along with the following prompt, take this poor quality transcript of a first draft of a speech, complete with stutters, restarts and repetitions, and turn it into a single, well drafted, cohesive version of the same. Don&amp;rsquo;t change the structure, wording or argument unless absolutely necessary. Though, it would help if you could point out areas to tighten or clean up, check the numbers and make sure they&amp;rsquo;re correct, adding footnotes, footnotes with the math, where possible. My source for the spending data was link, and my source for the wealth tax impact was link, and I calculated the effect of the top 10% income tax, additional income tax in the top 1% as 3.3 million in parentheses, number of 1% in us by overall population, assuming that&amp;rsquo;s the denominator in the 800k cut off. End, parentheses, times 800,000 in parentheses, the approximate income cut off to be a one percenter, though I asked AI instead of having a solid source for that. End, parentheses, check my facts and make sure I didn&amp;rsquo;t say anything wrong, critique my arguments and suggest improvements or additional points where necessary. Finally, feel free to add anything else to the markup you think would be helpful. Here&amp;rsquo;s the transcript I got, and then I pasted the transcript. What I ended up with was my argument laid out in a structure much closer to how I wanted it to be, but still in need of some improvements for transparency. I&amp;rsquo;ll include the output of this first draft below, or maybe I would just say here&amp;rsquo;s the output of this first draft. At this point, I underwent revisions, mostly addressing the points that 03 pro had found, making them stronger where possible. I and correcting the argument to be the strongest version of itself. Finally, I added this to my personal website and hit Upload. The recording and transcription process to produce the original draft took around 45 minutes feeding it to 03 pro took another five and then I spent another hour or two on editing. I&amp;rsquo;m pretty happy with where this piece ended up, and I think it&amp;rsquo;s a much stronger version of where it originally was. And further, I find that this way of writing posts tends to stick to my original message far more closely than my previous way of writing it out manually. Not to mention that when you tell 03 pro not to correct your points or change your wording, it actually tends to lessen. I&amp;rsquo;ve read this entire piece end to end a few times at this point, and I really can identify any areas that aren&amp;rsquo;t the way that I would have said it you I&amp;rsquo;m probably going to stick with this way of writing going forward, if only because I&amp;rsquo;m so much more fluent and fluid while speaking out loud than while typing. If you&amp;rsquo;re curious, yes, this follow up was produced in much the same way I though, with a lot less editing, here&amp;rsquo;s the original transcript of the follow up that Is this very piece you&amp;rsquo;re Reading. If you&amp;rsquo;re curious.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&#34;editors-note&#34;&gt;Editor’s Note:&lt;/h3&gt;
&lt;p&gt;I was quite surprised reading the final draft above to find just how bad the transcription was. There were some major transcription mistakes (swapping “can” for “can’t”, missing words, truncated sentences, and several more), and yet the AI barely noticed. Truly amazing.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>US Government Math</title>
        <link>https://talglobus.com/p/us-government-math/</link>
        <pubDate>Mon, 07 Jul 2025 05:21:41 -0700</pubDate>
        
        <guid>https://talglobus.com/p/us-government-math/</guid>
        <description>&lt;p&gt;The US national debt is not a hard problem to explain. It’s actually a fairly easy problem to explain, but it’s going to take some tough solutions. The cause is that we’re spending a very large amount of money on exactly four things. Almost everything else in the budget doesn’t really matter.&lt;/p&gt;
&lt;h2 id=&#34;one-health-care&#34;&gt;One, health care&lt;/h2&gt;
&lt;p&gt;It used to be that if you were poor and got sick, you died, and people didn’t really care about the poor. Same goes for the elderly. When you get old, your body gets weak and you start having kinds of health problems you didn’t know were possible. Over the past few decades medicine has gotten dramatically more expensive, and in those same decades we’ve dramatically expanded the amount of health care we’re providing to the poorest and the oldest among us, to the poorest via Medicaid and to the oldest via Medicare. The problem is that in 2024 this cost roughly $1.8 trillion (Medicaid $912 B + Medicare $874 B)&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. I’m not saying we shouldn’t pay for this — we almost definitely should — but if you try to cut health care for the people who need it most, they tend not to like it.&lt;/p&gt;
&lt;h2 id=&#34;two-social-security&#34;&gt;Two, Social Security&lt;/h2&gt;
&lt;p&gt;Fifty years ago retirees were the single poorest demographic in the United States&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. There was an internal conflict in the mind of nearly every would-be retiree: With age, the body starts making living and working more difficult, but without the money to retire, at some point one would have to decide they can’t work anymore, and then try their best to live a healthy and hopefully happy life. We had let our elderly down. In the same way that Medicare fixed health care for the elderly, Social Security fixed poverty in the elderly by guaranteeing income in retirement.&lt;/p&gt;
&lt;p&gt;Now the problem is threefold:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;People live a lot longer than they used to; if you retire and die three years later you don’t need much Social Security, but if you retire and die twenty years later we have to support you for a quarter of your life.&lt;/li&gt;
&lt;li&gt;We’re not putting enough money into the system to match what we pull out.&lt;/li&gt;
&lt;li&gt;Roughly 73 million Baby Boomers (born 1946-1964) — the largest population boom in American history — are retiring, moving from peak productivity to drawing benefits&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If we had accounted for this in advance, maybe we would have raised the amount of money you have to put into Social Security over time. As you can imagine, this is not a politically popular decision, and so we haven’t really done it. We never made it so that what you pull out is tied to what you put in; those are two entirely disconnected numbers in the law. Because of this, Social Security is, by most estimates, going to go insolvent in about eight years&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;, and then no more Social Security money, or more likely we’re going to need to print a lot more money. Social Security still costs about $1.46 trillion&lt;sup id=&#34;fnref1:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h2 id=&#34;three-interest&#34;&gt;Three, interest&lt;/h2&gt;
&lt;p&gt;When you borrow money you have to pay it back, plus a little prize for the lender. Interest payments have been rising because the debt itself is rising and because we borrowed a lot during historically low rates. We originally had near-zero interest rates to help us recover from the Great Recession, slashed them back to near zero during the pandemic, and only now, while fighting the inflation that cheap borrowing helped create, have we raised them, at the cost of making all the borrowing we still have to do much more expensive. In 2024 we spent almost $882 billion on interest&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;, and as we push borrowing well past $30 trillion that number will climb every year, squeezing the economy as it does. This is what happened to Japan.&lt;/p&gt;
&lt;p&gt;Back in the ’90s everyone thought Japan would lead the world economy. People were afraid of Japan’s economy the way they’re afraid of China’s now. Then it just stopped. Japan basically froze and has been frozen since the ’90s or early 2000s, largely because it borrowed huge amounts and now pours a huge share of its economy into paying interest. We are not Japan, and I don’t want us to become Japan.&lt;/p&gt;
&lt;h2 id=&#34;four-defense&#34;&gt;Four, defense&lt;/h2&gt;
&lt;p&gt;Defense is hard to buy efficiently because there’s no competition. If General Mills triples the price of cereal you can buy Kellogg’s, but you can’t buy generic bombers. When the one company that makes the war-plane says it costs more, do you say, “That’s okay, we’ll just lose the next war”? No — you bite the bullet and spend it.&lt;/p&gt;
&lt;p&gt;We just dropped 14 GBU-57 bunker-buster bombs on Iran’s nuclear program&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;. Developing the GBU-57 cost between $400 million and $500 million, and each bomb costs about $16 million&lt;sup id=&#34;fnref1:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;. A hundred of these bombs would cost us $1.6 billion&lt;sup id=&#34;fnref2:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;. Spending on groceries has declined dramatically over the past fifty years as a percentage of the average household’s spending, but do you know what hasn’t declined? The cost of defense. Continuing to buy bombs and war-planes is costing us roughly $874 billion a year&lt;sup id=&#34;fnref2:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h2 id=&#34;theres-the-rub&#34;&gt;There’s the rub&lt;/h2&gt;
&lt;p&gt;Health care, Social Security, interest, and defense together account for about 74 percent of the budget&lt;sup id=&#34;fnref3:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and if we eliminated every other program tomorrow we’d still be borrowing money just to pay for these four things.&lt;/p&gt;
&lt;p&gt;These four things are basically untouchable. You can’t cut health care for the poor or the elderly; you can’t cut Social Security because retirees are now a large, wealthy, and powerful voting bloc; you can’t stop paying interest without triggering financial Armageddon; and you can’t gut defense without risking military Armageddon.&lt;/p&gt;
&lt;p&gt;The theory behind Doge was that we spend a substantial amount of the government money we spend on fraud. In truth, more than three-quarters of the dollars we spend are spent on things that are basically politically impossible to remove and logistically very difficult to reduce. Of Medicaid, Medicare, Social Security, interest, and defense, half of these if cut would earn you the fury of the elderly and the poor, both very substantial populations in the United States today, and the other two if cut would see the US face a collapse of the financial system or war.&lt;/p&gt;
&lt;p&gt;If you want to understand how the Maslow’s hierarchy of American federal funding works, look no further than the fact that health care gets almost a trillion dollars a year, while transportation gets about $88 billion&lt;sup id=&#34;fnref4:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; and education gets only about $305 billion&lt;sup id=&#34;fnref5:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. You can live without transportation, but you can’t live without chemo, so of course the government spends a lot more on chemo.&lt;/p&gt;
&lt;h2 id=&#34;bonus-taxes&#34;&gt;Bonus, taxes&lt;/h2&gt;
&lt;p&gt;There’s an age-old idea that if only you properly taxed the wealthy, or immigrants, or big corporations, or whomever your least-favorite group is, then all these problems would go away. We’re currently borrowing about $1.833 trillion a year&lt;sup id=&#34;fnref6:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. Let’s see what a few of the most extreme tax increase proposals in recent memory would do to the deficit.&lt;/p&gt;
&lt;p&gt;Suppose you added a new income-tax bracket for the 1 percent, ten percentage points higher than the current one. The top 1 percent starts around $682,577 in income&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; and earns about 26 percent of all income&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;. This 10% jump would be a dramatic increase over the lower brackets, as the current jump to the highest bracket is 2% for taxpayers with incomes above $626,350 individual / $751,600 for married couples filing jointly, and then 3% for the next jump down. That surcharge would raise roughly $390 billion&lt;sup id=&#34;fnref1:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;, about one-fifth of the deficit.&lt;/p&gt;
&lt;p&gt;Try a wealth tax instead. Senator Bernie Sanders’s plan to tax wealth over $21 million at 1 percent would raise about $260 billion a year&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;. Senator Elizabeth Warren’s 2-to-3 percent wealth tax on fortunes over $50 million would raise around $230 billion a year&lt;sup id=&#34;fnref1:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;. Helpful, but still nowhere near the deficit.&lt;/p&gt;
&lt;p&gt;Perhaps increase corporate taxes by 50%. This would be as radical as any of the proposals above, and would be a fairly pronounced squeeze on small businesses, but with corporate income tax providing $494 billion in 2024, would yield an additional $247 billion&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;. Exclude every firm with less than $2.5 billion in assets, and you’re getting an additional $163.5 billion (50% of $327 billion)&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;None of these policies alone comes close to closing the deficit. Fixing the US national debt will, by necessity, squeeze at least one very large group of Americans — the old via Social Security and Medicare, the poor via Medicaid, or everyone via higher taxes.&lt;/p&gt;
&lt;p&gt;It turns out the math isn’t mathing because it’s really inconvenient math.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;U.S. Treasury, &lt;em&gt;Combined Statement of Receipts, Outlays, and Balances&lt;/em&gt;, FY 2024 outlay tables. &lt;a class=&#34;link&#34; href=&#34;https://www.fiscal.treasury.gov/files/reports-statements/combined-statement/cs2024/outlay.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.fiscal.treasury.gov/files/reports-statements/combined-statement/cs2024/outlay.pdf&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref2:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref3:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref4:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref5:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref6:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;U.S. Census Bureau, &lt;em&gt;Historical Poverty Tables: People and Families, Table 7 — Poverty of People, by Age&lt;/em&gt; (1973–1975 columns). &lt;a class=&#34;link&#34; href=&#34;https://www.census.gov/data/tables/time-series/demo/income-poverty/historical-poverty-people.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.census.gov/data/tables/time-series/demo/income-poverty/historical-poverty-people.html&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;U.S. Census Bureau, “The Baby Boom Cohort in the United States: 2020 to 2060” (P25-1149). &lt;a class=&#34;link&#34; href=&#34;https://www.census.gov/content/dam/Census/library/publications/2019/demo/p25-1149.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.census.gov/content/dam/Census/library/publications/2019/demo/p25-1149.pdf&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Social Security Administration, “Social Security Board of Trustees: Projection for Combined Trust Funds One Year Sooner Than Last Year” (press release, 2024). &lt;a class=&#34;link&#34; href=&#34;https://blog.ssa.gov/social-security-board-of-trustees-projection-for-combined-trust-funds-one-year-sooner-than-last-year/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://blog.ssa.gov/social-security-board-of-trustees-projection-for-combined-trust-funds-one-year-sooner-than-last-year/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;U.S. Treasury, &lt;em&gt;Combined Statement of Receipts, Outlays, and Balances&lt;/em&gt;, FY 2024—net-interest table. &lt;a class=&#34;link&#34; href=&#34;https://www.fiscal.treasury.gov/files/reports-statements/combined-statement/cs2024/outlay.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.fiscal.treasury.gov/files/reports-statements/combined-statement/cs2024/outlay.pdf&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;U.S. Department of Defense, “Historically Successful Strike on Iranian Nuclear Site Was 15 Years in the Making,” 24 Jun 2025. &lt;a class=&#34;link&#34; href=&#34;https://www.defense.gov/News/News-Stories/Article/Article/4227082/historically-successful-strike-on-iranian-nuclear-site-was-15-years-in-the-maki/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.defense.gov/News/News-Stories/Article/Article/4227082/historically-successful-strike-on-iranian-nuclear-site-was-15-years-in-the-maki/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref2:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;Investopedia, “How Much Income Puts You in the Top 1 %?” (IRS SOI 2021 threshold). &lt;a class=&#34;link&#34; href=&#34;https://www.investopedia.com/personal-finance/how-much-income-puts-you-top-1-5-10/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.investopedia.com/personal-finance/how-much-income-puts-you-top-1-5-10/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;Tax Foundation, “Latest Federal Income Tax Data, 2024.” &lt;a class=&#34;link&#34; href=&#34;https://taxfoundation.org/data/all/federal/latest-federal-income-tax-data-2024/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://taxfoundation.org/data/all/federal/latest-federal-income-tax-data-2024/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;Tax Foundation, “Details and Analysis of Senator Sanders’s Wealth-Tax Plan,” 2020 dynamic score. &lt;a class=&#34;link&#34; href=&#34;https://taxfoundation.org/sanders-wealth-tax-analysis/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://taxfoundation.org/sanders-wealth-tax-analysis/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;U.S. Treasury, &lt;em&gt;Combined Statement of Receipts, Outlays, and Balances&lt;/em&gt;, FY 2024 receipts tables. &lt;a class=&#34;link&#34; href=&#34;https://www.fiscal.treasury.gov/files/reports-statements/combined-statement/cs2024/receipts.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.fiscal.treasury.gov/files/reports-statements/combined-statement/cs2024/receipts.pdf&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;Internal Revenue Service, Statistics of Income Division, &lt;em&gt;Corporation Income Tax Returns, 2021: Table 8—Income Tax After Credits, by Size of Total Assets&lt;/em&gt;. &lt;a class=&#34;link&#34; href=&#34;https://www.irs.gov/pub/irs-soi/21coccr.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.irs.gov/pub/irs-soi/21coccr.pdf&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>AI and the Inversion of Control</title>
        <link>https://talglobus.com/p/ai-and-the-inversion-of-control/</link>
        <pubDate>Sat, 21 Jun 2025 19:17:16 -0700</pubDate>
        
        <guid>https://talglobus.com/p/ai-and-the-inversion-of-control/</guid>
        <description>&lt;p&gt;Since SaaS&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; became a business model in the [mid 2000’s], the primary way by which companies integrate third party tools into their software has been via API. This is such a common and boring fact that most software people don’t give it much thought. Whether connecting a database, an analytics service, or sending notifications to a user’s phone, the languages is essentially the same: send an API request to a server somewhere, providing it whatever information it needs, and then process whatever you back in response.&lt;/p&gt;
&lt;p&gt;The reason this is such an obvious and unavoidable interface is that databases, analytics services, and software to send notifications to a user’s phone are all &lt;em&gt;tools&lt;/em&gt;. The buyer’s software chooses when to use them, and the software they bought patiently waits to be called. There is a second option, &lt;em&gt;webhooks&lt;/em&gt;, used when you want your software to respond to external events. But despite the existence of a pattern for the software you buy to call &lt;em&gt;your&lt;/em&gt; software via webhook, the use case is almost always &lt;em&gt;NOT&lt;/em&gt; some tool messaging you and asking you to do something. As a rule, webhooks are used to inform your software that something has happened, and then it’s up to your software to decide what to do about it.&lt;/p&gt;
&lt;p&gt;I write this in mid 2025, and we’re now beginning to see the emergence of a new class of software you can buy to integrate with your software, &lt;em&gt;agents&lt;/em&gt;. Why does this matter? Because in order for an agent to be useful, it &lt;em&gt;really&lt;/em&gt; helps if the &lt;em&gt;agent&lt;/em&gt; can choose what it wants to do. What happens when an agent you pay for wants to check if a user received an email, or perhaps to send one from your service? What happens when a customer service agent you buy needs to exchange a user’s purchase for the next size up, or help them reset their password? When the agent wants to take an action that depends on your software, there are two ways of fulfilling its request:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;delegate access to the underlying resource (e.g. email sending as your company) to the agent, or&lt;/li&gt;
&lt;li&gt;create a way for the &lt;em&gt;agent&lt;/em&gt; to ask &lt;em&gt;your&lt;/em&gt; software to do something&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the former case, you might predict proxies to all the tools a company uses — or perhaps even the tools themselves — offering advanced authentication and authorization capabilities might become commonplace. This would necessitate the creation of software that doesn’t currently exist to enable this behavior.&lt;/p&gt;
&lt;p&gt;In the latter case, this sounds a lot like a world where companies are going to be spending engineer hours building APIs into their software for the agents they buy to use, which sounds to me like it would scale terribly. One might imagine they’d address this by having coding agents write the endpoints instead of engineers, but that implies companies will need to tolerate dramatic increases in tech debt to support the needs of an ever increasing number of agents. I would predict there will need to be software to enable this too.&lt;/p&gt;
&lt;p&gt;The implications of this are potentially the introduction of new channels for communication between buyers and sellers of SaaS. REST&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; APIs to tell your purchased software what to do, webhooks for your purchased software to tell you about things that happen in the world so you can react to them, and &lt;em&gt;something&lt;/em&gt; new for agents to instruct your software to take action on their behalf.&lt;/p&gt;
&lt;p&gt;I’m excited to learn what that thing will be.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;SaaS, or &lt;em&gt;Software as a Service&lt;/em&gt;, refers to the practice of buying software from a vendor who exists solely or primarily to sell this software to you, which you then either use via some web interface or app, or connect to your own software to use as described here&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Yes, REST has lost much of its meaning over the past decade or two. I’m referring to it (as most do these days) to describe the pattern of sending requests to software which does some work for you and then responds with a result&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>Categories</title>
        <link>https://talglobus.com/p/categories/</link>
        <pubDate>Fri, 03 Jan 2025 18:33:57 -0800</pubDate>
        
        <guid>https://talglobus.com/p/categories/</guid>
        <description>&lt;p&gt;Every few months, an article appears in some news source or another announcing the discovery of a new species. Sometimes the specimen discovered is something never before seen, but seemingly far more often, the announcement is something a bit more subtle. Members of one species were found to actually be something new. The operative word here is “found” and the reason why is the reason I’m writing this post.&lt;/p&gt;
&lt;p&gt;Species don’t exist in the sense you likely think they do. We’re taught from learning basic animals in our earliest years of schooling to memorizing facts in high school or college biology courses that the organisms of the world are divided into categories, each of which is subdivided into further categories, further and further, until you end up at the species level.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; The fundamental dogma here is that things of the same species are alike and things of different species are different.&lt;/p&gt;
&lt;p&gt;What defines a species, you ask? Well it depends on who you’re talking to and when. In 1942 Ernst Mayr introduced the “biological species concept” centered around the idea that organisms of the same species can mate and produce viable young, and organisms of different species cannot. But of course, coywolves are hybrids of the coyote (&lt;em&gt;Canis latrans&lt;/em&gt;) and wolf (&lt;em&gt;Canis lupus&lt;/em&gt;), and &lt;a class=&#34;link&#34; href=&#34;https://www.crucians.org/html/crucian_hybrids.php#:~:text=However%2C%20it%27s%20probable%20that%20many,to%20a%20crucian%27s%2032%20%2D%2034.&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;various crucian hybrids exist&lt;/a&gt; between types of carp (&lt;em&gt;Cyprinus carpio&lt;/em&gt; for the common carp) and goldfish (&lt;em&gt;Carassius auratus&lt;/em&gt;). Before Mayr the common consensus of species concept was morphological — species share common physical traits. In recent decades the common consensus has shifted toward the genetic — species share genetic traits. But how many traits? How close is close enough to be a species; how far is far enough not to be? &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Species_Problem&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;This is a problem&lt;/a&gt; going back to the earliest conception of species.&lt;/p&gt;
&lt;p&gt;Planets work the same way. I learned in school that Pluto was a planet. My younger siblings learned that it was not. Many were disappointed when on August 24, 2006, Pluto was demoted from “planet” to “dwarf planet”. Did Pluto change between its discovery and original designation of the “planet” label in 1930 and its demotion in 2006? Not in any meaningful way; change on the planetary scale (or perhaps the dwarf-planetary scale) occurs in timescales of millions of years. So why was it demoted?&lt;/p&gt;
&lt;p&gt;To astronomers, a planet is something special. A planet isn’t just any celestial body orbiting a star — we’ve got plenty of those we label asteroids or comets — planets are the ones that feel substantially different from the others. They’re not part of a group; they’re unique. As the advancement of telescopes enabled the discovery of more and more objects with orbits and characteristics similar to those of Pluto, we stopped seeing Pluto as special.&lt;/p&gt;
&lt;p&gt;Why does Pluto get to be a planet when Quaoar, Makemake, Haumea, and finally Eris don’t? If those four do, what about Sedna? What about the rest of the celestial bodies orbiting in the Kuiper belt? Where do we draw the line? Neptune is special, it’s far larger than any celestial objects in the area. It’s also a gas giant, composed chiefly of gas held together by gravity while the others are far icier. Uranus is special for similar reasons. Jupiter is so massive its gravity may be a major reason Earth hasn’t been hit by deadly asteroids much in the past few billion years. Saturn even has rings! So Pluto isn’t &lt;em&gt;special&lt;/em&gt; enough to be a planet.&lt;/p&gt;
&lt;p&gt;But this feels so arbitrary! You’ll remember I mentioned asteroids and comets as designations for celestial bodies that aren’t special enough to be planets. But Pluto, too close to the public’s hearts to be demoted all the way to &lt;em&gt;asteroid&lt;/em&gt;, was given the new designation of “dwarf planet,” a category created just for Pluto. And that’s after the discovery of 2060 Chiron and subsequent uncertainty about whether it’s more asteroid or comet led to the introduction of the new designation of “centaur” in 1977 for Chiron-like bodies. Why Centaur? Because in Greek mythology Chiron was the &amp;ldquo;wisest and justest of all the centaurs”&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;The gap between the way most people view terms like “species” and “planet” is a misinterpretation between essentialism and nominalism. It’s the direction the arrow of causality points. An essentialist understanding of species would dictate “there’s a natural thing we call a species, and we’re just figuring out which one each organism is.” Meanwhile, a nominalist might say “we want to understand the world, and making convenient categories is an easy way to do so.” While most might think we live in a world defined as in the first case, very few natural categories exist; almost all are manmade.&lt;/p&gt;
&lt;p&gt;Look around you. How many categories for things that weren’t created with their categories predefined feel essentialist to you? A Mazda Miata is a Miata because it was created from a master specification detailing how Miatas are made. A starfish is a starfish because someone long ago spotted one and proclaimed “Look! It’s not a star-shaped rock, it’s more like a fish!” and there are plenty of animals that are by definition starfish that you might think don’t deserve the distinction&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;There’s one final piece of this puzzle, which takes us all the way to the incentive system in academia. Categories are deeply interwoven with research and scientists, and research and science tends to be done in academic settings. The types of categories with the greatest essentialist-nominalist conflict tend to be those in the scientific literature, and incentives in many academic fields push strongly in the direction of creating new categories.&lt;/p&gt;
&lt;p&gt;Academia doesn’t run on dollars — if you think you’re underpaid, ask a doctoral student how hard they work and how much money they make — it runs on reputation. Careers in research make or break on the quantity and quality of one’s discoveries. Quantity is quantity, and quality is determined by how prestigious the publication where the work is published and how many heads it turns. “Discovering” a new species or a new planet is a great foundation for a promising career in the sciences; discovering many is even better. Making a change to the basic facts of the universe every child learns alongside their ABCs lands your name in the history books.&lt;/p&gt;
&lt;p&gt;So how in academia do you change an established fact in the literature? How do you demote Pluto as a planet? You make an argument. You provide evidence. You get your argument published somewhere prestigious. You talk to researchers. You push and push until your position is accepted, because if you think getting your viewpoint accepted by the masses is good for your career, what do you think happens if your arguments are broadly rejected? Researchers are people, the academic institutions are run by people, and changing the very facts underlying our world comes down to making a convincing case.&lt;/p&gt;
&lt;p&gt;Most of the categories we view as natural are created. Often the problem is the instinct to categorize itself. Almost every property of a celestial body is continuous, not discrete. Is it icy? A little. Is it large? Very. Without discrete distinctions to form the boundaries of our categories, the types of categorization we favor are often inconsistent with the reality of the situations we seek to categorize. If you choose to divide celestial bodies into categories like planet, asteroid, comet, or indeed centaur, the categories will &lt;em&gt;by necessity&lt;/em&gt; be arbitrary. The Creator didn’t differentiate between a planet and a dwarf planet, and with at least hundreds of billions of each in our Milky Way Galaxy alone, the distinction will always be a line drawn in sand.&lt;/p&gt;
&lt;p&gt;Species are the same. Sometimes two members of two different species can be more similar physically or even genetically to each other than to other members of their own. Genetics (more accurately, genotype) is functionally continuous given how many hops there are between one species and another. Transitioning genetically from, say, a banana to a human would require somewhere on the order of billions of mutations. Can there ever be a non-arbitrary answer to where along that line you say it’s no longer a banana and starts being a human? Or does it become something else entirely in the interim, and where does that happen?&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;So we either accept that our categories are fundamentally flawed, not because we haven’t learned enough about the things they categorize, but because of fundamental limitations of the ability of those things to be categorized at all. Or we continue to be awed when we see announcements like &lt;a class=&#34;link&#34; href=&#34;https://arc.net/l/quote/kanglawz&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;“researchers discover that the white-eyed individuals of Borneo, in fact, represent an entirely new species”&lt;/a&gt;. The difference between the cream-vented bulbul (the original one, &lt;em&gt;Pycnonotus simplex&lt;/em&gt;) and the cream-eyed bulbul (the new one, &lt;em&gt;Pycnonotus pseudosimplex&lt;/em&gt;)? One has red eyes. Definitely a new species.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;You can keep going past species to subspecies and onward, but those are less relevant to this topic.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Here it is in the Iliad: &lt;a class=&#34;link&#34; href=&#34;https://arc.net/l/quote/kybvduah&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://arc.net/l/quote/kybvduah&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;A phylogenist would tell you starfish are actually asteroids, &lt;a class=&#34;link&#34; href=&#34;https://www.digitalatlasofancientlife.org/learn/echinodermata/asteroidea/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;because&amp;hellip;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;There’s an even better example I kept in footnotes for brevity: languages. You might’ve heard India has thousands of languages, and many Indians speak 3, 4, 5, even 6 of them. As often attributed to linguist Max Weinreich, &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/A_language_is_a_dialect_with_an_army_and_navy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;“a language is a dialect with an army and navy”&lt;/a&gt;. It’s politically convenient for India to slice the continuously-varying spectrum of language spoken by their population at certain points and give each segment a name even if the whole situation is better described as a &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Sprachbund&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;sprachbund&lt;/a&gt;, or language spectrum. It’s also politically convenient for China to call Mandarin, Cantonese, and Hokkien dialects of Chinese and not distinct languages despite speakers of the latter two needing to learn Mandarin in school in order to be able to understand it. In this case it’s not academic incentives at play, but political ones, with predictable results.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>Arguments About AI</title>
        <link>https://talglobus.com/p/arguments-about-ai/</link>
        <pubDate>Wed, 15 May 2024 07:45:04 -0400</pubDate>
        
        <guid>https://talglobus.com/p/arguments-about-ai/</guid>
        <description>&lt;h2 id=&#34;random-pertubations&#34;&gt;Random Pertubations&lt;/h2&gt;
&lt;p&gt;Imagine M&amp;amp;Ms divided into four groups by color on a sheet of graph paper. The brown M&amp;amp;Ms sit on the positive side of the Y axis, the reds sit on the negative side of the Y axis, the blues sit on the positive side of the X axis, the greens sit on the negative side of the X axis. All other colors are absent.&lt;/p&gt;
&lt;p&gt;This model represents any structured system. A human cell, a car engine, a software microservice. Pushing any of the M&amp;amp;Ms deeper into its own color group would increase the inherent structure, pushing any of the M&amp;amp;Ms further away from its color group would decrease it.&lt;/p&gt;
&lt;p&gt;Most of the things we humans call “the world” depend on a large degree of structure to function properly. The most amazing devices — microchips with billions of individual transistors per square inch for example — tend to rely on the largest degree of structure.&lt;/p&gt;
&lt;p&gt;If you were to randomly perturb an M&amp;amp;M, pushing it in any of the four possible directions on a 2D graph, one of those directions would push it deeper into its cluster, in the direction of increased structure, three would push it away from its cluster. Thus there is a 75% chance this maneuver would decrease the structure of the overall system.&lt;/p&gt;
&lt;p&gt;The number “4” comes from the dimensionality of the system. The number of dimensions times two, in this case for a two-dimensional graph. The real world is far higher-dimensional. As a very rough proxy, CLIP embeddings, representing all possible images, have 1024 dimensions. In such a space, one direction pushes deeper into the vector for a given M&amp;amp;M color, 1023 push away, for a 99.902% chance of a random pertubation decreasing the structure of the system.&lt;/p&gt;
&lt;p&gt;In our world, any powerful entity can push things around. When things are pushed, they are far more likely to be pushed in the direction of decreased structure than in the direction of increased structure. This is countered by the fact that the most important human decisions tend to be made with significant care, and &lt;a class=&#34;link&#34; href=&#34;https://talglobus.com/p/51-percent&#34; &gt;these decisions don’t all have to be right&lt;/a&gt;. The higher dimensional the system, the more carefully the direction must be chosen to maintain or increase structure, as the lower the number of options that increase structure. When structure decreases in our world, it tends not to go well.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Autocompleting Regular Expressions</title>
        <link>https://talglobus.com/p/autocompleting-regular-expressions/</link>
        <pubDate>Wed, 08 May 2024 20:59:59 -0700</pubDate>
        
        <guid>https://talglobus.com/p/autocompleting-regular-expressions/</guid>
        <description>&lt;p&gt;When designing forms to collect custom data types, you’ll sometimes have a regular expression for what you’re trying to collect, and for easy visual spacing you’d like to automatically inject separators into the form where appropriate, like this example for phone numbers:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;415&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{4}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;append_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;415-&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But how to implement &lt;code&gt;append_separators&lt;/code&gt;, without losing the regular expression as the single source of truth? There are existing implementations for phone numbers and credit cards, but for company TIN numbers? Social security numbers? More exotic inputs? The closest Python libraries I’ve found to solving this are Exrex and Greenery.&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/asciimoo/exrex&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Exrex&lt;/a&gt; allows for randomly sampling strings matching a given regular expression, hex color codes for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;exrex&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;getone&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;color_hex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;#(?:[0-9a-fA-F]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;){1,2}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;getone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color_hex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#1D7EBb&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/qntm/greenery&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Greenery&lt;/a&gt; allows for applying logical operations to regular expressions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;greenery&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;five_plus_chars&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.{5,}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;five_plus_chars&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color_hex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;#[0-9A-Fa-f]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{6}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Considering that Greenery works by converting regular expressions to finite state machines, computing the intersection of the two FSMs as a third FSM, and using the Brzozowski algebraic method (q.v.) to convert the third FSM back to a regular expression&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, re-implementing this to find where a separator can be appended would seem much higher lift than necessary to achieve the desired effect.&lt;/p&gt;
&lt;p&gt;But if you can randomly sample from strings satisfying a regular expression:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;     &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;237&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;178&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8887&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;264&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;194&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8260&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;945&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;873&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3099&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;515&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;809&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7348&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;112&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4732&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;936&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;552&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0686&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;422&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;686&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3399&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;313&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;372&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8544&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;309&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;291&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8909&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;159&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;619&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4738&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then you can see from the outputs which slots in the generated output are always the same. Would it be possible to solve this probabilistically?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Generate 1000 strings satisfying this regular expression&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Find all characters that appear at each index&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;option&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# Add a new set if we don&amp;#39;t yet have one for this index&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Print seen characters for each character position&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;char_set&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Character &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;char_set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Character&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Character&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Character&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Character&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Character&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Character&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Character&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Character&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Character&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Character&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Character&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let’s call a character position &lt;em&gt;unique&lt;/em&gt; if there is only one character allowed in that position.&lt;/p&gt;
&lt;p&gt;Given this is a probabilistic algorithm, let’s establish some bounds for error rates. Which error modes are possible? Type I error would be a character position &lt;em&gt;appearing&lt;/em&gt; to be unique, while actually having additional possibilities which didn’t appear due to random chance. Type II error can be safely disregarded, as there’s no circumstance in which a truly unique character position would have other characters appear in a string without violating the regular expression. No other error mode is possible, so long as the regex doesn’t allow for variable-length strings, which we’ll address shortly.&lt;/p&gt;
&lt;p&gt;The more characters are valid for a given character position, the less likely each is to appear, so the case making a false positive most likely is when there are the least number of possible characters for that position, specifically 2 characters, given 1 would make the character position truly unique.&lt;/p&gt;
&lt;p&gt;If we flip a digital coin 100 times, the probability of only seeing one of two possible faces across all 100 flips — assuming both characters are equally likely — is &lt;code&gt;1/2^100&lt;/code&gt;, or:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;0.000000000000000000000000000000789
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With the benchmark set thus at 7.9e-31, or one false positive in 1.3e30 flips, if the entire human population of the Earth were to flip coins once a second for 14 billion years, or the approximate current age of the universe,&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; we’d have 3.5e27 flips, or a 0.3% chance of a single false positive after 14 billion years.&lt;/p&gt;
&lt;p&gt;For some extra safety, we can flip 1000 times, for a false positive probability of &lt;code&gt;1/2^1000&lt;/code&gt;, or one false positive in 1e301 flips. At that point, the all-humans-every-second-since-the-big-bang flip count has no meaningful impact on the false positive probability, and an arbitrary precision calculator I used to test this just rounded it to 0.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;So for our complete algorithm:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;exrex&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;getone&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;SeparatorAppender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_index_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;append_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;to_append&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to_append&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;_index_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# Generate 1000 strings satisfying this regular expression&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;options&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# Find the allowed character set at each index&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;option&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;c1&#34;&gt;# Add a new set if we don&amp;#39;t yet have one for this index&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# Find the index-to-separator mapping whenever only one separator is allowed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;separators_by_index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;charset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;charset&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;charset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;separators_by_index&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{4}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;appender&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SeparatorAppender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;appender&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;415&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;415&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, handling regular expressions matching strings of varying length. For this, we can bring in Greenery, by simply merging the existing user input with the regular expression:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;re&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;415&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user_input_as_regex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;escape&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_input_as_regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;415-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{4}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you can’t definitively say whether a character position is unique until after the character preceeding it is entered, then the corresponding character can’t be appended anyway, so by accounting for the existing user input, we’ve gone as far as we can without inserting symbols between already enterred characters.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;re&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;exrex&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;getone&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;greenery&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;SeparatorAppender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;append_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_index_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;to_append&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to_append&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;_index_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# Combine the user input with the regex&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;user_input_as_regex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;escape&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user_input_as_regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# Generate 1000 strings satisfying this regular expression&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;options&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# Find the allowed character set at each index&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;option&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;option&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;c1&#34;&gt;# Add a new set if we don&amp;#39;t yet have one for this index&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# Find the index-to-separator mapping whenever only one separator is allowed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;separators_by_index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;charset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;charset&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seen_by_index&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;charset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;separators_by_index&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{4}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;appender&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SeparatorAppender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;appender&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;415&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mi&#34;&gt;415&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that we unfortunately lose the ability to pre-compute our index for the regular expression and so there is some relatively significant performance cost to this approach. How much?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{4}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;appender&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SeparatorAppender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;   
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timeit&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;appender&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;415&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mf&#34;&gt;65.9&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ms&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;±&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;3.78&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ms&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;per&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;loop&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;±&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dev&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;runs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;loops&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;each&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And for the version without crossing in the existing user input to handle variable length inputs:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{4}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;appender&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SeparatorAppender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timeit&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;appender&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;415&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mf&#34;&gt;75.9&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ns&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;±&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.721&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ns&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;per&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;loop&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;±&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dev&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;runs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;000&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;loops&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;each&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you try reducing the number of rounds on the original regular expression to 100, tolerating that 0.3% chance of a single false positive in 14 billion years with the entire human population of Earth flipping a coin per second:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{3}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{4}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;appender&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SeparatorAppender&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;phone_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timeit&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;appender&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append_separators&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;415&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mf&#34;&gt;47.9&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ms&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;±&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;2.67&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ms&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;per&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;loop&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;±&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dev&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;runs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;loops&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;each&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Probably better to keep it to fixed-length strings.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://arc.net/l/quote/bjxajbrm&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;This is actually an exact quote&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;I say current age because by the time you read this the universe may be significantly older&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Really, this should be a count of false advertising against the “arbitrary precision” calculator&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>Things I Would Pay For: Invariant Testing</title>
        <link>https://talglobus.com/p/things-i-would-pay-for-invariant-testing/</link>
        <pubDate>Tue, 23 Apr 2024 12:22:03 -0400</pubDate>
        
        <guid>https://talglobus.com/p/things-i-would-pay-for-invariant-testing/</guid>
        <description>&lt;p&gt;I’m starting a new series on things I will pre-commit to paying for if someone builds it, or points me to one that meets my stated needs.&lt;/p&gt;
&lt;p&gt;For the first run of the series, I spent several minutes looking through our API trying to guarantee there was no way a user could ever see data from a different organization, &lt;em&gt;except&lt;/em&gt; if the data has been shared publicly. There are a few common solutions for this, like single-tenant systems, one tenant per organization, where data is copied to a “public” system once shared publicly by the user, but this is one of several similar invariants I need to guarantee. You can’t use tenancy as a knowledge boundary for every possible invariant.&lt;/p&gt;
&lt;p&gt;You also can’t write tests asserting that something &lt;em&gt;isn’t&lt;/em&gt; possible, for the same reasons it’s always hard to prove a negative. Fuzzing is an option, but the strength of the proven invariants tends to depend upon the skill of the person writing the fuzz tests.&lt;/p&gt;
&lt;h2 id=&#34;the-build&#34;&gt;The Build&lt;/h2&gt;
&lt;p&gt;I’d love to have a symbolic execution tool where I could write out invariants and it would prove whether or not they’re true, ideally as part of our standard suite of tests. Add in some AI for natural language writing of invariants à la “thou shalt not allow users to access other users’ data unless its &lt;code&gt;visibility&lt;/code&gt; is set to &lt;code&gt;public&lt;/code&gt;” or “thou shalt not allow users to assign tasks to other users they are not set as an &lt;code&gt;owner&lt;/code&gt; for” and I could throw together a set of invariants in an hour or two covering all our basic security needs.&lt;/p&gt;
&lt;p&gt;Aircraft manufacturers and similarly risk-intolerant companies (with the possible exception of Boeing) tend to use verification tools like TLA+ to specify the behavior of their systems, and guarantee through mathematical proof that there are no combinations of conditions that can result in behavior outside of specified constraints. The rest of us don’t use these tools because they take too much effort to set up and use. Using language models to bridge that gap would be a great way of turning natural language into value, and I’d personally pay some small amount every month to be able to eliminate these risks.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>51 Percent</title>
        <link>https://talglobus.com/p/51-percent/</link>
        <pubDate>Thu, 21 Mar 2024 17:03:43 -0400</pubDate>
        
        <guid>https://talglobus.com/p/51-percent/</guid>
        <description>&lt;p&gt;I often wonder what things I’m wrong about. I sometimes notice wrong things said by friends and colleagues, and I’m sure I’m not alone in that regard. I’d have to imagine at least 10% of what’s in my head is wrong, and that’s likely an optimistic estimate, but after seeing a sufficiently large number of wrong things published in prestigious places in a given week, I’m apt to wonder how this can be. Over the past few millennia, mankind has invented science, turned rocks into refined metal, sand into semiconductors, created intelligence in those metals and semiconductors, and sent men to the moon. Yet so frequently we’re wrong, and at first it seems contradictory.&lt;/p&gt;
&lt;p&gt;Some of the smartest minds in physics spent the better part of fifty years studying string theory as a possible theory of everything, a single set of equations and principles that can predict with mathematical precision everything that does, did, and can ever happen in our universe. Only after decades of finding flaws, inventing complex rules to resolve those flaws, and finding more flaws in a loop did the house of cards crumble in the past few years. Many physicists bet their lives on it; many still do. How can so many brilliant people be led astray for so long?&lt;/p&gt;
&lt;p&gt;I think the problem is in the question. The more fact-minded among us have a particular dislike for wrong things, and subconsciously see a world where all the important decisions being made by all the right people means society can keep moving forward. First, this notion is probably elitist. But more importantly, it’s probably wrong.&lt;/p&gt;
&lt;p&gt;After spending a few hours watching a machine learning model train on a second monitor while doing my work for the umpteenth time, I realized my sense that the important things have to be right disagreed with the evidence presented by this intelligence being created before me. The model doesn’t take every step in the direction of self-improvement. If you were to watch it navigating a map in parameter space, many of its steps would be aimed in no particularly intelligent direction at all.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;It doesn’t need to be right.&lt;/em&gt; It only needs to be just slightly more right than it is wrong, and it’s mathematically guaranteed to eventually converge on the optimum. This isn’t a figure of speech, it’s mathematical certainty, far greater mathematical certainty than string theory will every be: &lt;em&gt;if your level of rightness is just slightly larger than your level of wrongness, you’re guaranteed to make progress.&lt;/em&gt; Society doesn’t need a world full of right people getting it right almost all the time; the mathematics of progress are fortunately far more forgiving. You don’t even need 51%. But of course, the more right you are, the faster you’ll converge.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Polyphyly and Other Cladistics</title>
        <link>https://talglobus.com/p/polyphyly-and-other-cladistics/</link>
        <pubDate>Fri, 12 Jan 2024 22:13:33 -0500</pubDate>
        
        <guid>https://talglobus.com/p/polyphyly-and-other-cladistics/</guid>
        <description>&lt;p&gt;For today’s episode of “Really Important Concepts That Don’t Have Names,” I’d like to briefly introduce two words shamelessly stolen from the esoteric biological field of taxonomy.&lt;/p&gt;
&lt;p&gt;Carl Linnaeus made his place in history through his system of organizing every material, living or dead, into species, branching from a taxonomic tree initially divided into the three classes of animal, plant, and mineral. Hardly the first to attempt such a thing — Aristotle’s system of classification had been used for about two millennia prior — Linnaean taxonomy would gradually incorporate discoveries from archaeological study of ancient species, study of newly discovered forms of ever smaller life, and eventually the discovery of Darwinian evolution.&lt;/p&gt;
&lt;p&gt;As naturalists, now referred to as biologists,&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; sought to construct ever more accurate trees of life, a subtle change took hold in methodology. No longer was the scientific establishment satisfied with groupings derived solely from similarity with little regard for evolutionary history. This prior way of thinking, then referred to as &lt;em&gt;phenetics&lt;/em&gt;, was gradually replaced by &lt;em&gt;cladistics&lt;/em&gt;, the practice of categorizing species by shared ancestry.&lt;/p&gt;
&lt;p&gt;But with genetic evidence and improvements in the ability to trace ancestral lineages of modern life, the field discovered a problem: sometimes, two species that appear to be very closely related are actually evolutionarily quite distant, and conversely, two species that appear to be quite different may actually be closely related.&lt;/p&gt;
&lt;p&gt;The result is a number of taxonomic reorderings that I’m sure Wikipedia will suffice to describe, and two marvelous terms for a situation frequently encountered but poorly described for lack of terminology:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Polyphyletic&lt;/em&gt;, when two or more things may appear to be closely related, but actually come from different branches of the tree of life. Typically used to describe situations where two species appear very similar but are actually not very closely related.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Paraphyletic&lt;/em&gt;, when two or more things may not appear to be closely related, but are actually quite closely related. Often used to describe situations where shared ancestry is responsible for an observed set of similar traits.&lt;/p&gt;
&lt;p&gt;For a bonus vocab word, because these terms are primarily applicable to scenarios where groups of things share certain traits, those traits shared can be referred to as &lt;em&gt;homoplasies&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;So next time you find yourself in the middle of a discussion demanding more nuanced terms to distinguish between things belonging to classes as a result of shared ancestry versus shared traits, there&amp;rsquo;s a word for that.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;A note for the taxonomists in the house&lt;/strong&gt;, or those who crave their particular flavor of pedantry: as you might imagine, the &lt;em&gt;degree&lt;/em&gt; of ancestral relation is of particular interest to those constructing trees of all life on the planet. Where does one draw the line between the &lt;em&gt;polyphyletic&lt;/em&gt; and the &lt;em&gt;paraphyletic&lt;/em&gt;? If a group of species includes &lt;em&gt;all&lt;/em&gt; descendants of a given ancestor, it’s said to be &lt;em&gt;monophyletic&lt;/em&gt; (which also happens to be the only one of these terms whose definition isn’t subject to debate). If it includes some but excludes others, it is said to be &lt;em&gt;paraphyletic&lt;/em&gt; with respect to the excluded others. If a group is defined by a set of shared characteristics but those characteristics are not the result of shared ancestry, it is said to be &lt;em&gt;polyphyletic&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Technically, the definition of paraphyletic I provided above also (incorrectly) includes monophyletic groupings, even though logically the two labels should be mutually exclusive. Given that the purpose of the vocab lesson is to introduce a concept that can be used to categorize ideas, and ideas, being not of a finite set, cannot be enumerated, monophylesis is practically a non-issue, and so I excluded the term above for simplicity. Feel free to contact me via &lt;a class=&#34;link&#34; href=&#34;linkedin.com/in/talglobus&#34; &gt;my LinkedIn&lt;/a&gt; for a duel.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;More accurately, naturalism split into biology and chemistry, the latter of which later split into chemistry and physics, likely with a number of additional fields I’m forgetting.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Putting footnotes on footnotes is a rather underappreciated capacity of modern site rendering engines. I’ve taken the liberty of doing so for a fun if brief tangent on &lt;em&gt;carcinization&lt;/em&gt; and horoscopes. You may have noticed the symbol for the horoscope &lt;em&gt;cancer&lt;/em&gt; is a crab, and &lt;em&gt;carcinoma&lt;/em&gt; is a type of cancer. As it happens, the word for cancer overlaps with the word for crab in a great many languages, with the most common explanations noting the hard surfaces and tight grip of tumors in the eyes of early surgeons, and the crab like appearance of the veins around a cancerous growth. Yet cancer again collides with crabs in the naming of &lt;em&gt;carcinoma&lt;/em&gt;, from the Greek &lt;em&gt;karkinos&lt;/em&gt; meaning crab or cancer, and &lt;em&gt;-oma&lt;/em&gt;, which likely began its life as a suffix in the word &lt;em&gt;carcinoma&lt;/em&gt;, but now means tumor or cancer. Two largely unrelated connections between crabs and cancer. Wild.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;The classic example of this — the exclusion of which may be the most common reason biology teachers are drawn and quartered in the modern day — is the rather absurd number of entirely unrelated species that look very much like crabs. The trend of evolving to be more like a crab is so common it’s even been given a name: &lt;em&gt;carcinization&lt;/em&gt;.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>Rules for Startups</title>
        <link>https://talglobus.com/p/rules-for-startups/</link>
        <pubDate>Mon, 13 Nov 2023 15:01:16 -0500</pubDate>
        
        <guid>https://talglobus.com/p/rules-for-startups/</guid>
        <description>&lt;h3 id=&#34;1-measure-your-progress-and-be-relentless-about-growing-it-over-time&#34;&gt;1. Measure your progress, and be relentless about growing it over time.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You should probably use week-over-week revenue growth rate as your metric for this&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-keep-the-customers-happy-whatever-it-takes&#34;&gt;2. Keep the customers happy, whatever it takes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If you can’t keep a given customer happy, maybe they shouldn’t be your customer&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;3-things-dont-change-unless-and-until-someone-changes-them&#34;&gt;3. Things don&amp;rsquo;t change unless and until someone changes them&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Either someone else changes something, or you do, or it stays the same&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;4-execution--directional-correctness--ideation&#34;&gt;4. Execution &amp;gt; Directional Correctness &amp;gt; Ideation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Thinking of good ideas is easy, understanding the nature of the problem is hard, but execution outreturns both&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://talglobus.com/p/51-percent/&#34; &gt;The 51% rule&lt;/a&gt; implies that directional correctness is steering, execution is gas, ideation is really just picking landmarks&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;5-ensuring-people-know-about-your-product-is-just-as-hard-as-building-a-good-product&#34;&gt;5. Ensuring people know about your product is just as hard as building a good product&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Product decisionmaking and marketing/sales decisionmaking deserve equal attention, but are rarely given it&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;6-if-time-is-the-most-precious-commodity-then-prioritization-is-the-most-important-skill&#34;&gt;6. If time is the most precious commodity, then prioritization is the most important skill&lt;/h3&gt;
&lt;h3 id=&#34;7-opportunities-come-in-unusual-packages-and-rarely-when-youre-looking-for-them&#34;&gt;7. Opportunities come in unusual packages, and rarely when you’re looking for them&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Generally the most important steps toward a goal seem entirely random in the moment&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;8-take-breaks-sometimes&#34;&gt;8. Take breaks sometimes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Get good at noticing when your productivity is slipping and why, and if you&amp;rsquo;re going to rest, do it properly&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;9-no-problem-is-below-you&#34;&gt;9. No problem is below you&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;By default, there is no one else to take on problems you don&amp;rsquo;t want to solve, including ordering pizza and carrying trash&lt;/li&gt;
&lt;li&gt;You can pay people to change this, but being able to delegate problems you don&amp;rsquo;t want to deal with comes with a price&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;10-let-others-name-things&#34;&gt;10. Let others name things&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Giving something its name is an unusually satisfying experience, but for most things it’s not actually that important&lt;/li&gt;
&lt;li&gt;If you let others name things, they’ll feel they played an important role in its creation, and a missed opportunity to give an employee or colleague that feeling is rarely worth the joy of naming it yourself&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>How Do LLMs Do?</title>
        <link>https://talglobus.com/p/how-do-llms-do/</link>
        <pubDate>Tue, 01 Aug 2023 19:08:00 -0500</pubDate>
        
        <guid>https://talglobus.com/p/how-do-llms-do/</guid>
        <description>&lt;p&gt;In conversations with founders, engineers, and enthusiasts of ChatGPT-enabled academic dishonesty, one point of confusion about LLMs that frequently surfaces is how, on a technical level, services that give LLMs access to information from databases, Wikipedia, or even the Weather Channel actually work. How do you take an AI-powered chatbot that takes in words and spits out words and give it access to the internet, databases, or anything else of personal or economic interest? Over the next few thousand words, let’s break this down. This post is intended to be accessible to a non-technical audience. We’ll be using the terms prompt&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, tokens&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, training&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, and fine-tuning&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;. If you&amp;rsquo;d like a definition for any of those, follow the little numbers.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;There are only two possible ways for an LLM to know anything:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It’s in the training data&lt;/li&gt;
&lt;li&gt;It’s in the prompt&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Alright, thanks for reading. See you next week.&lt;/p&gt;
&lt;h2 id=&#34;what&#34;&gt;What?&lt;/h2&gt;
&lt;p&gt;Every time any LLM-based product answers questions, or generates output using any information at all, the software behind the scenes is using one or both of the above two strategies to give the LLM access to that information. I’ll explain the most common techniques for both by way of a few scenarios, but first, an aside on how LLMs are trained that’ll be relevant later on.&lt;/p&gt;
&lt;h2 id=&#34;training&#34;&gt;Training&lt;/h2&gt;
&lt;p&gt;The most common way an LLM is trained involves four steps. A useful metaphor is that an LLM’s “brain” consists of a fixed structure, and a rather long collection of numbers (“parameters”) that slot into that structure as everything the brain knows and can do, almost like downloading your brain as a long list of numbers. These numbers are adjusted directly to &amp;ldquo;train&amp;rdquo; the brain. GPT-3.5-turbo, one of the two LLMs behind ChatGPT, is expected to have 154 billion adjustable parameters.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Take your text data, and generate pairs of prompts and desired responses from the LLM for each, like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;ne&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;What&amp;#39;s the square root of 4?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;The square root of 4 is 2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;ne&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Why can&amp;#39;t humans fly?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Human chest muscles are too small and weak relative...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;ne&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Great to meet you!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;It&amp;#39;s great to meet you too!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;ne&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Who are you&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;I&amp;#39;m ChatGPT, an AI chatbot built to help you with various...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Feed each input to the LLM, and measure how different the LLM’s output is from the desired output in the training data&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use math to figure out which parameters in the LLM’s “brain” are responsible for most of the difference between the desired output and the actual output of the LLM, and then add or subtract just a bit from each parameter to try to correct this error&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Repeat with more data&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the process of adjusting the LLM’s parameters to close the gap between the output it gives for a particular input and the desired output, the math behind LLM training ends up encoding a version of the patterns within the training data in its parameters. How facts translate into LLM parameters is poorly understood and an active area of study, but suffice it to say that your brain does something similar in encoding information within its equivalent to parameters.&lt;/p&gt;
&lt;h2 id=&#34;the-executor&#34;&gt;The Executor&lt;/h2&gt;
&lt;p&gt;The key to the whole system is a piece of software that interfaces between the natural language input and output of the
LLM and the rigid API&amp;rsquo;s of the software world. If there exists a way with code to turn on some lights, or fetch some data,
or to do anything else useful, the LLM can&amp;rsquo;t do it by itself. It needs a layer of software that can translate the LLM&amp;rsquo;s
output into a series of API calls, and translate the API&amp;rsquo;s response into a response the LLM can understand.&lt;/p&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;h3 id=&#34;chatgpt-when-is-william-shakespeares-birthday&#34;&gt;“ChatGPT, when is William Shakespeare’s birthday?”&lt;/h3&gt;
&lt;p&gt;This one is all “strategy 1” above. When OpenAI trained GPT-3.5-turbo and GPT-4 (the LLMs underlying the ChatGPT product), somewhere in all the training data was at least one reference to Shakespeare’s birthday. When the LLM was trained, at least one of the input-output pairs in the training data mentioned the date of his birth, and the resulting adjustments to the LLM’s parameters encoded this information within the LLM.&lt;/p&gt;
&lt;h3 id=&#34;siri-whats-johnny-appleseeds-phone-number&#34;&gt;“Siri, what’s Johnny Appleseed’s phone number?”&lt;/h3&gt;
&lt;p&gt;While Siri isn’t yet LLM based as of the time of this writing, it almost certain will be very soon. Here’s how it’ll answer the above question.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Behind the scenes)&lt;/em&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Who&lt;/th&gt;
&lt;th&gt;What do they say?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User&lt;/strong&gt; (to Siri)&lt;/td&gt;
&lt;td&gt;Siri, what’s Johnny Appleseed’s phone number?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hey LLM, a user asked the following question: &lt;br&gt;&lt;br&gt; “Siri, what’s Johnny Appleseed’s phone number?” &lt;br&gt;&lt;br&gt; You’ll likely need to use a tool to answer it, so here’s a list of tools I can use for you. If you want to use a tool, put the name of the tool in brackets (e.g. {Calculator}), otherwise simply respond with plain text to reply directly to the user. Do not use brackets anywhere else in your output: &lt;br&gt;&lt;br&gt; - Calculator &lt;br&gt; - Calendar &lt;br&gt; - Contacts &lt;br&gt; - Notes &lt;br&gt; - Weather &lt;br&gt; …&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{Contacts}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;I see you want to use contacts. You can take any of the following actions. To pick an action, put its name in brackets (e.g. {Add Contact}), otherwise simply respond with plain text to reply directly to the user. To go back, use the {Go Back} action. Do not use brackets anywhere else in your output: &lt;br&gt;&lt;br&gt; - Add Contact &lt;br&gt; - Edit Contact &lt;br&gt; - Delete Contact &lt;br&gt; - Retrieve Contact &lt;br&gt; … &lt;br&gt; - Go Back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{Retrieve Contact}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;To find a contact, put some search text in brackets (e.g. {Philip}), and I’ll give you a list of matching contacts to choose from. Otherwise simply respond with plain text to reply directly to the user. To go back, search for {Go Back}. Do not use brackets anywhere else in your output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{Johnny Appleseed}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Here are the matching contacts. To pick one, put its number in brackets. To get the next 10 contacts, respond with {Next}, otherwise simply respond with plain text to reply directly to the user. To go back, search for {Go Back}. Do not use brackets anywhere else in your output: &lt;br&gt;&lt;br&gt; 1. Tommy Baynard &lt;br&gt; 2. Bobby Parsnip &lt;br&gt; 3. Danny DeVito &lt;br&gt; 4. Sammy Solomon &lt;br&gt; 5. Ricky Pinkus &lt;br&gt; 6. Johnny Appleseed &lt;br&gt; 7. Joey Barbossa &lt;br&gt; 8. Billy Taylor &lt;br&gt; 9. Frankie Fortress &lt;br&gt; 10. Tommy Applefarmer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{Johnny Appleseed}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Invalid Input. &lt;br&gt;&lt;br&gt; Here are the matching contacts. To pick one, put its number in brackets. To get the next 10 contacts, respond with {Next}, otherwise simply respond with plain text to reply directly to the user. To go back, search for {Go Back}. Do not use brackets anywhere else in your output: &lt;br&gt;&lt;br&gt; 1. Tommy Baynard &lt;br&gt; 2. Bobby Parsnip &lt;br&gt; 3. Danny DeVito &lt;br&gt; 4. Sammy Solomon &lt;br&gt; 5. Ricky Pinkus &lt;br&gt; 6. Johnny Appleseed &lt;br&gt; 7. Joey Barbossa &lt;br&gt; 8. Billy Taylor &lt;br&gt; 9. Frankie Fortress &lt;br&gt; 10. Tommy Applefarmer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{6}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Here is the requested contact. To go back, respond with {Go Back}, otherwise simply respond with plain text to reply directly to the user. Do not use brackets anywhere else in your input: &lt;br&gt;&lt;br&gt; Name: Johnny Appleseed &lt;br&gt; Phone: (123) 456 7890 &lt;br&gt; Address: 1 Min Strot Lane, Arlington, GA 39813&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(123) 456 7890&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Just to confirm, you put the following in plain text: &lt;br&gt;&lt;br&gt; “(123) 456 7890” &lt;br&gt;&lt;br&gt; Are you sure you want to say this to the user? Say {Yes} or {No}, or respond with {Go Back} to go back. Otherwise, simply respond with plain text to reply directly to the user. Do not use brackets anywhere else in your input.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{Yes}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Siri&lt;/strong&gt; (to User)&lt;/td&gt;
&lt;td&gt;(123) 456 7890&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;You may notice the similarity between the above interaction and working through a phone tree. It turns out this is actually how we give access to tools: we have a software-defined phone tree (sometimes referred to as the &amp;ldquo;executor&amp;rdquo;), and the LLM takes the role of “user” talking to it. The software administering the phone tree, like real-world phone trees, just does dumb text matching. It checks at each step if the result from the LLM is in its list of available options, and has a number of hardcoded functions that actually do whatever the LLM asks for.&lt;/p&gt;
&lt;p&gt;The executor is ultimately responsible for interacting with the outside world on behalf of the LLM; and the LLM is responsible for choosing from the options provided at each step to produce the desired result. The biggest difference is, this entire process can take place in seconds or less, so to the user it can feel nearly instantaneous. LLM&amp;rsquo;s are also less likely than most humans to get frustrated by the process, and most are quite forgiving of being put on hold.&lt;/p&gt;
&lt;h3 id=&#34;tesla-turn-on-the-ac&#34;&gt;&amp;ldquo;Tesla, turn on the AC&amp;rdquo;&lt;/h3&gt;
&lt;p&gt;This is where we start to see the real power of LLMs put to work. The executor need not only read information, it can execute any function requested by the LLM, provided it has a function to run. The executor is responsible for taking the LLM&amp;rsquo;s output and translating it into a command that the AC can understand, and the LLM is responsible for choosing from the options provided at each step to produce the desired result.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Behind the scenes)&lt;/em&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Who&lt;/th&gt;
&lt;th&gt;What do they say?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User&lt;/strong&gt; (to Car)&lt;/td&gt;
&lt;td&gt;Tesla, turn on the AC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hey LLM, a user asked the following question: &lt;br&gt;&lt;br&gt; “Tesla, turn on the AC” &lt;br&gt;&lt;br&gt; Pick a subsystem or resource to respond to this command from the following list. To select a subsystem or resource, put its name in brackets (e.g. {Suspension Control}), otherwise simply respond with plain text to reply directly to the user. Do not use brackets anywhere else in your output: &lt;br&gt;&lt;br&gt; - Engine Control &lt;br&gt; - Transmission Control &lt;br&gt; - Brake/Traction System &lt;br&gt; - Suspension Control &lt;br&gt; - Telemetry &lt;br&gt; - Climate Control &lt;br&gt; - Infotainment System &lt;br&gt; - Cabin Controls &lt;br&gt; - Internet Search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{Climate Control}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;I see you want to use climate control. You can take any of the following actions. To pick an action, put its name in brackets (e.g. {Set Temperature}), otherwise simply respond with plain text to reply directly to the user. To go back, use the {Go Back} action. Do not use brackets anywhere else in your output: &lt;br&gt;&lt;br&gt; - Set Temperature &lt;br&gt; - Set Fan Speed &lt;br&gt; - Set Mode &lt;br&gt; - Set Airflow Direction &lt;br&gt; - Set Airflow Recirculation &lt;br&gt; - Set Airflow Defrost &lt;br&gt; - Set Airflow Rear Defrost &lt;br&gt; &amp;hellip; &lt;br&gt; - Go Back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{Set Mode}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;To set climate control mode, choose from the following options. To pick an option, put its name in brackets (e.g. {Fan Only}), otherwise simply respond with plain text to reply directly to the user. To go back, use the {Go Back} action. Do not use brackets anywhere else in your output: &lt;br&gt;&lt;br&gt; - Heating &lt;br&gt; - Cooling &lt;br&gt; - Fan Only &lt;br&gt; - Go Back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{Cooling}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Just to confirm, you would like to change the climate control mode from &amp;ldquo;Fan Only&amp;rdquo; to &amp;ldquo;Cooling&amp;rdquo;? Say {Yes} or {No}, or respond with {Go Back} to go back. Do not use brackets anywhere else in your input.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{Yes}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Car&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;AC Turns On&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Any action that can be expressed as a function can be executed by the executor, and the LLM can be trained to choose from a list of options provided by the executor to produce the desired result. This is the core of how LLMs can be used to control any system that can be controlled by a computer.&lt;/p&gt;
&lt;h2 id=&#34;caveats&#34;&gt;Caveats&lt;/h2&gt;
&lt;p&gt;As you can imagine, this is a slightly oversimplified depiction of things, but not by much. While human-facing phone trees tend to be optimized to minimize labor cost for customer service agents, and then perhaps frustration if the provider is feeling generous, LLM-facing phone trees are optimized around a different set of constraints, roughly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Minimizing risk of making a mistake that could upset a user or cost the company money or reputational damage&lt;/li&gt;
&lt;li&gt;Minimizing the compute cost for the LLM, which in turn means minimizing the amount of text input to and output from the LLM&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Less important but still relevant:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Minimizing the number of round trips between the LLM and the phone tree&lt;/li&gt;
&lt;li&gt;Maximizing the amount of useful data that can be acquired from this process&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nearly every element of this system can be optimized in myriad ways to meet these aims. There are papers describing innovations from replacing full-text responses to the phone tree (&lt;code&gt;{Retrieve Contact}&lt;/code&gt;) with random tokens (&lt;code&gt;{Q}&lt;/code&gt;) to save tokens and decrease bias&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;, to incorporating caching processes that allow for intelligently skipping steps that were recently performed and cached, like so:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Who&lt;/th&gt;
&lt;th&gt;What do they say?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User&lt;/strong&gt; (to Siri)&lt;/td&gt;
&lt;td&gt;Siri, what’s Johnny Appleseed’s phone number?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hey LLM, a user asked the following question: &lt;br&gt;&lt;br&gt; “Siri, what’s Johnny Appleseed’s phone number?” &lt;br&gt;&lt;br&gt; You’ll likely need to use a tool to answer it, so here’s a list of tools I can use for you. If you want to use a tool, put the name of the tool in brackets (e.g. {Calculator}), otherwise simply respond with plain text to reply directly to the user. Do not use brackets anywhere else in your output: &lt;br&gt;&lt;br&gt; - Calculator &lt;br&gt; - Calendar &lt;br&gt; - Contacts &lt;br&gt; - Notes &lt;br&gt; - Weather &lt;br&gt; …&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor Helper&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;By the way LLM, this sounds very similar to a previous user request, &amp;ldquo;Siri, can you get me Jimmy Robbins&amp;rsquo; number?&amp;rdquo;, resolved with the following steps: &lt;br&gt;&lt;br&gt; 1. Choose a tool → {Contacts} &lt;br&gt; 2. Choose an action → {Retrieve Contact} &lt;br&gt; 3. Provide argument for action → {Jimmy Robbins} &lt;br&gt; 4. Choose from results → {1} &lt;br&gt; 5. Output to User → (402) 322 2748 &lt;br&gt; 6. Confirm → {Yes} &lt;br&gt;&lt;br&gt; If you&amp;rsquo;d like to skip ahead to just after one of these steps, put the number of the step in brackets (e.g. {4} for &amp;ldquo;Choose from results&amp;rdquo;). Otherwise, continue following the instructions above.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{2}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;To find a contact, put some search text in brackets (e.g. {Philip}), and I’ll give you a list of matching contacts to choose from. Otherwise simply respond with plain text to reply directly to the user. To go back, search for {Go Back}. Do not use brackets anywhere else in your output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;{Johnny Appleseed}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;hellip;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The above is a relatively simple example of a caching process, but it’s not hard to imagine more sophisticated ones that can cleverly reuse previous lookups and produce intelligently rewritten full conversation histories from cached previous interactions. While it&amp;rsquo;s still early days for this type of tooling, this is a fairly active area of research, and we’re likely to see a lot of progress in the coming months and years.&lt;/p&gt;
&lt;h2 id=&#34;final-questions&#34;&gt;Final Questions&lt;/h2&gt;
&lt;h3 id=&#34;what-if-the-llm-makes-a-mistake&#34;&gt;What if the LLM makes a mistake?&lt;/h3&gt;
&lt;p&gt;That depends on whether the LLM feeds an invalid response to the phone tree (like replying &lt;code&gt;{Johnny Appleseed}&lt;/code&gt; for the contact above when the phone tree was looking for a number from 1 to 10), or a valid but incorrect response to the phone tree (like replying &lt;code&gt;{5}&lt;/code&gt; instead of &lt;code&gt;{6}&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;If the response is invalid, in the most basic case the phone tree simply asks again, but more advanced implementations can use the same types of tricks that human phone trees go through, like “Did you mean…” as we’ve already got software that does that.&lt;/p&gt;
&lt;p&gt;If the response is valid but incorrect, the best defense is ample access to “Go Back” and asking for confirmation before doing anything that could make a user unhappy, like deleting a contact or spitting out the wrong number. You can see this in the last few steps above.&lt;/p&gt;
&lt;h3 id=&#34;but-how-did-the-llm-know-the-answer-at-the-end&#34;&gt;But how did the LLM know the answer at the end?&lt;/h3&gt;
&lt;p&gt;When you feed text to an LLM, you don’t feed it just the most recent message, you feed it the entire conversation, or some version of it. The LLM has access to anything you include in the prompt, and its job is simply to generate the next message. So the LLM can see the answer just by looking at the rest of the conversation in its input.&lt;/p&gt;
&lt;h3 id=&#34;what-if-the-users-request-involves-multiple-steps&#34;&gt;What if the user’s request involves multiple steps?&lt;/h3&gt;
&lt;p&gt;In the simplest case, the LLM is clever enough to know to say “{Go Back}” a few times at the end to start over with a different tool, and as mentioned above, it can see everything prior in the conversation. As long as all the information it needs is somewhere in the conversation, the LLM has a good shot at finding it and using it correctly.&lt;/p&gt;
&lt;p&gt;In more complicated cases, the phone tree might first ask the LLM to construct a strategy, and then perform some degree of handholding to walk the LLM through the steps in its strategy. For situations that require even more demanding logical flows, a number of logical frameworks exist to allow the LLM itself to take control of the process of arriving at the desired result, rather than letting the phone tree dictate the flow. &lt;a class=&#34;link&#34; href=&#34;https://ofir.io/self-ask.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Self-Ask&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/pdf/2210.03629.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ReAct&lt;/a&gt; (not to be confused with the very popular frontend framework of the same name) are two well-known frameworks in this category.&lt;/p&gt;
&lt;p&gt;Here’s what a ReAct phone tree looks like, for the curious. Note how the Executor finishes its messages with an &lt;code&gt;Observation&lt;/code&gt; and the start of a &lt;code&gt;Thought&lt;/code&gt;, and the LLM picks up where it left off, completing the &lt;code&gt;Thought&lt;/code&gt; and then providing the next &lt;code&gt;Action&lt;/code&gt; to take.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Who&lt;/th&gt;
&lt;th&gt;What do they say&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User&lt;/strong&gt; (to LLM ReAct Agent)&lt;/td&gt;
&lt;td&gt;Who is the current president of France, and what is the last letter of his birth month?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ReAct Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Answer the following questions as best you can. You have access to the following tools:&lt;br&gt;&lt;br&gt;google_serper: A low-cost Google Search API.Useful for when you need to answer questions about current events.Input should be a search query.&lt;br&gt;Calculator: Useful for when you need to answer questions about math.&lt;br&gt;&lt;br&gt;Use the following format:&lt;br&gt;&lt;br&gt;Question: the input question you must answer&lt;br&gt;Thought: you should always think about what to do&lt;br&gt;Action: the action to take, should be one of [google_serper, Calculator]&lt;br&gt;Action Input: the input to the action&lt;br&gt;Observation: the result of the action&lt;br&gt;&amp;hellip; (this Thought/Action/Action Input/Observation can repeat N times)&lt;br&gt;Thought: I now know the final answer&lt;br&gt;Final Answer: the final answer to the original input question&lt;br&gt;&lt;br&gt;Begin!&lt;br&gt;&lt;br&gt;Question: Who is the current president of France, and what is the last letter of his birth month?&lt;br&gt;Thought:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;I need to look up the current president of France&lt;br&gt;Action: google_serper&lt;br&gt;Action Input: current president of France&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ReAct Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Observation: Emmanuel Macron&lt;br&gt;Thought:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;I need to determine the last letter of his birth month&lt;br&gt;Action: google_serper&lt;br&gt;Action Input: Emmanuel Macron birth month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ReAct Executor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Observation: December&lt;br&gt;Thought:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;I now know the final answer&lt;br&gt;Final Answer: Emmanuel Macron, December - r&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Result&lt;/strong&gt; (to User)&lt;/td&gt;
&lt;td&gt;Emmanuel Macron, December - r&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;what-about-openais-function-calling-api&#34;&gt;What about OpenAI&amp;rsquo;s Function Calling API?&lt;/h3&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://platform.openai.com/docs/guides/function-calling&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Function calling&lt;/a&gt; is a framework for reducing the amount of work needed to build the executor. It provides the LLM with a list of &amp;ldquo;functions&amp;rdquo;, or specific actions the LLM can take, and then has the LLM choose from that list and provide whatever inputs are necessary to run the function. It&amp;rsquo;s then up to the user to actually execute the function. It&amp;rsquo;s a relatively simple framework, telling the engineer that the LLM requested to use function &lt;code&gt;check_weather&lt;/code&gt; and leaving it to the engineer to identify and run the correct code to check the weather given the LLM&amp;rsquo;s inputs. There exist a number of alternative frameworks that provide more or less of the planning and execution sides of the executor, but they&amp;rsquo;re mostly just different flavors of phone tree.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;em&gt;Prompt&lt;/em&gt;: The text fed into an LLM as input&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;em&gt;Tokens&lt;/em&gt;: The smallest, most granular unit of text you can feed an LLM. For technical but mostly irrelevant reasons, LLMs generally enforce a limit to the number of characters you can feed them for a single request, measured in tokens. Each token corresponds to around 4 characters. For the curious, &lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;see here&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;em&gt;Training&lt;/em&gt;: The process of taking a LLM (or any machine learning model really) and adjusting its “brain” to push how it’ll respond to a given input in a desired direction&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;em&gt;Fine-tuning&lt;/em&gt;: Doing additional training on an already trained model&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;This is called &amp;ldquo;symbol tuning&amp;rdquo; and is described further in &lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2305.08298&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;this paper&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        
    </channel>
</rss>
