<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Andrew Trettel&#x27;s website</title>
    <link rel="self" type="application/atom+xml" href="https://www.andrewtrettel.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://www.andrewtrettel.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-04-12T00:00:00+00:00</updated>
    <id>https://www.andrewtrettel.com/atom.xml</id>
    <entry xml:lang="en">
        <title>Wosp: advanced full-text search on the command line</title>
        <published>2025-11-04T00:00:00+00:00</published>
        <updated>2025-11-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrew Trettel
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.andrewtrettel.com/blog/wosp/"/>
        <id>https://www.andrewtrettel.com/blog/wosp/</id>
        
        <content type="html" xml:base="https://www.andrewtrettel.com/blog/wosp/">&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Wosp is a command-line program that performs full-text search on text
documents.  Wosp stands for &lt;em&gt;word-oriented search&lt;&#x2F;em&gt; and &lt;em&gt;print&lt;&#x2F;em&gt;.  It is designed
for advanced searchers.  It works differently than line-oriented search tools
like grep, so it can search for matches spanning multiple lines.  Wosp supports
an expressive query language that contains both Boolean and proximity
operators.  It also supports nested queries, truncation, wildcard characters,
and fuzzy searching.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;git-repository&quot;&gt;Git repository&lt;&#x2F;h2&gt;
&lt;p&gt;The source code is available on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atrettel&#x2F;wosp&quot;&gt;GitHub&lt;&#x2F;a&gt;.  I
have licensed the project under the GPL version 3.  The README file in the
repository covers the build and installation instructions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivations-and-requirements&quot;&gt;Motivations and requirements&lt;&#x2F;h2&gt;
&lt;p&gt;I am a scientist and a researcher.  As part of my research, I often search for
obscure information and hard-to-define concepts.  Some of my searches occur
locally.  Over the years, I have accumulated a substantial amount of documents
that are unavailable online, so I also depend on being able to search for
information locally.&lt;&#x2F;p&gt;
&lt;p&gt;Search engines often appear magical.  Searchers, like wizards, summon the
relevant information with the right incantation (well, query).  Of course,
search is not magic, but the seemingly miraculous nature of search makes it
difficult at times to grasp what went wrong when a searcher cannot find
something.  Should I narrow this search more?  Did I use the wrong term?  How
does a search engine work anyway?&lt;&#x2F;p&gt;
&lt;p&gt;In the last few years, people have often discussed how &quot;search is broken&quot; in
some way.  This statement usually applies to online search engines, especially
Google.  Several factors have contributed to the drop in search quality:
&lt;a href=&quot;https:&#x2F;&#x2F;www.404media.co&#x2F;google-search-really-has-gotten-worse-researchers-find&#x2F;&quot;&gt;extensive search engine
optimization&lt;&#x2F;a&gt;,
&lt;a href=&quot;https:&#x2F;&#x2F;www.wheresyoured.at&#x2F;the-men-who-killed-google&#x2F;&quot;&gt;alleged attempts by Google to increase advertising
revenue&lt;&#x2F;a&gt;, or the recent
introduction of AI overviews hindering deeper searching.  Searching on Google
now feels adversarial at times, like you have to trick the system to get good
results.&lt;&#x2F;p&gt;
&lt;p&gt;The common issue in all three of these factors is that searchers have little
control over the results Google returns.  That realization made me wonder if I
can create some search tool that puts me and other searchers firmly in control
of our own searches.&lt;&#x2F;p&gt;
&lt;p&gt;Searchers need repeatable tools that work reliably and do not degrade over time
as external incentives change.  Ideally, these tools should work locally to
search private information.  Search tools should also be easy to understand, so
that searchers can &quot;look under the hood&quot; and improve the tools as needed.  That
removes the magical feeling, but it was never magic to begin with.  Searchers
do not have to accept broken products that operate like magical and untouchable
black boxes.&lt;&#x2F;p&gt;
&lt;p&gt;Initially, I did not want to create another program, so I searched for
something.  I found several interesting programs but concluded that no existing
program satisfies my requirements.&lt;&#x2F;p&gt;
&lt;p&gt;I need a search program with the following features:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Command-line operation.&lt;&#x2F;em&gt;  The program must work according to the &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Unix_philosophy&quot;&gt;Unix
philosophy&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Simple and clear program architecture.&lt;&#x2F;em&gt;  The program must have a
well-defined scope to avoid feature creep.  I want a simple and clear program
architecture that follows guidelines like the &lt;a href=&quot;https:&#x2F;&#x2F;suckless.org&#x2F;philosophy&#x2F;&quot;&gt;Suckless
philosophy&lt;&#x2F;a&gt; among others.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Boolean and proximity operators.&lt;&#x2F;em&gt;  The program must have sentence and
paragraph proximity operators.  IBM and Data Central (now LexisNexis)
independently invented &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Proximity_search_(text)&quot;&gt;proximity
search&lt;&#x2F;a&gt; in the 1960s
(&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.7551&#x2F;mitpress&#x2F;3543.001.0001&quot;&gt;Bourne 2003&lt;&#x2F;a&gt;).  Proximity
search ensures that a document discusses two concepts in the same context,
which matters when searching especially long documents.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Wildcard search.&lt;&#x2F;em&gt;  &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Wildcard_character&quot;&gt;Wildcard
search&lt;&#x2F;a&gt; enables searching
for a variety of terms compactly.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Fuzzy search.&lt;&#x2F;em&gt;  &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Approximate_string_matching&quot;&gt;Fuzzy
search&lt;&#x2F;a&gt; helps
search poorly OCRed documents and locates relevant documents even if they
have typos.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Nested queries.&lt;&#x2F;em&gt;  Support for nested queries means that the query language
should allow for the arbitrary combination of all operations.  For example,
some programs only allow proximity search for words and not for phrases or
groups of words.  Nested queries make the query language &lt;em&gt;expressive&lt;&#x2F;em&gt; by
enabling searchers to search for more precise concepts.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;No stored index required.&lt;&#x2F;em&gt;  The program must not require a stored index, so
it can be run on any arbitrary collection of documents.  I need to use the
program on any bit of text rather than on a limited library of documents.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I have considered various local search tools, but none met all of these
requirements.  &lt;a href=&quot;https:&#x2F;&#x2F;www.tgries.de&#x2F;agrep&#x2F;&quot;&gt;agrep&lt;&#x2F;a&gt;,
&lt;a href=&quot;https:&#x2F;&#x2F;pdfgrep.org&#x2F;&quot;&gt;pdfgrep&lt;&#x2F;a&gt;,
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BurntSushi&#x2F;ripgrep&quot;&gt;ripgrep&lt;&#x2F;a&gt;,
&lt;a href=&quot;https:&#x2F;&#x2F;geoff.greer.fm&#x2F;ag&#x2F;&quot;&gt;ag&lt;&#x2F;a&gt;, and &lt;a href=&quot;https:&#x2F;&#x2F;ugrep.com&#x2F;&quot;&gt;ugrep&lt;&#x2F;a&gt; all follow
the basic model provided by &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Grep&quot;&gt;grep&lt;&#x2F;a&gt; of
searching for regular expressions on the command line without any stored
indices.  &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zeux&#x2F;qgrep&quot;&gt;qgrep&lt;&#x2F;a&gt; adds stored indices to speed
up the search.  &lt;a href=&quot;https:&#x2F;&#x2F;beyondgrep.com&#x2F;&quot;&gt;ack&lt;&#x2F;a&gt; is similar to grep and includes
Boolean operations and line-based proximity search, which is too limited for my
purposes.  &lt;a href=&quot;https:&#x2F;&#x2F;www.recoll.org&#x2F;&quot;&gt;Recoll&lt;&#x2F;a&gt;,
&lt;a href=&quot;https:&#x2F;&#x2F;docs.aleph.occrp.org&#x2F;&quot;&gt;Aleph&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;opensemanticsearch.org&#x2F;&quot;&gt;Open Semantic
Search&lt;&#x2F;a&gt;, and
&lt;a href=&quot;https:&#x2F;&#x2F;docfetcher.sourceforge.io&#x2F;&quot;&gt;DocFetcher&lt;&#x2F;a&gt; operate using a graphical-user
interface and require stored indices.&lt;&#x2F;p&gt;
&lt;figure&gt;

&lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;www.andrewtrettel.com&amp;#x2F;wosp-program-features.svg&quot;&gt;

&lt;figcaption&gt;A Venn diagram comparing
the features of various search programs, including their support for fuzzy or
proximity search and their use of stored indices.&lt;&#x2F;figcaption&gt;

&lt;&#x2F;figure&gt;
&lt;p&gt;The above Venn diagram compares the features of these local search tools.  The
Venn diagram excludes several variants of grep due to them lacking fuzzy or
proximity search.  Aleph, DocFetcher, and Recoll are the most capable of these
local search tools, but all require a stored index and Aleph requires a
client-server architecture, making it better suited for organizations than
individuals.  Aleph and Recoll both have the weak form of proximity search that
disallows nested proximity operations (I cannot find much information about
DocFetcher&#x27;s proximity search).&lt;&#x2F;p&gt;
&lt;p&gt;Since no existing program met my requirements, I decided to write my own
full-text search program designed for advanced searchers.  The next section
goes into how to use Wosp.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-use-wosp&quot;&gt;How to use Wosp&lt;&#x2F;h2&gt;
&lt;p&gt;The basic format of a Wosp command is as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wosp &amp;quot;QUERY&amp;quot; file1.txt file2.txt ...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Queries are how searchers find information using Wosp&#x27;s query language.  The
query language is influenced by the &lt;a href=&quot;https:&#x2F;&#x2F;www.uspto.gov&#x2F;patents&#x2F;search&#x2F;patent-public-search&#x2F;operators&quot;&gt;query language used at the United States
Patent and Trademark
Office&lt;&#x2F;a&gt;.
The USPTO&#x27;s query language is an implementation of the query language used in
&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;BRS&#x2F;Search&quot;&gt;BRS&#x2F;Search&lt;&#x2F;a&gt;, which was a copy of the
query language used in &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;IBM_STAIRS&quot;&gt;IBM STAIRS&lt;&#x2F;a&gt;.
That said, Wosp&#x27;s query language includes many advanced features not found in
many other systems.&lt;&#x2F;p&gt;
&lt;p&gt;To search for a keyword in some documents, a searcher just needs to use the
word:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wosp &amp;quot;detective&amp;quot; A_Study_in_Scarlet.txt
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:816:am the only one in the world. I&amp;#39;m a consulting detective, if you can understand
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All of my examples come from the first Sherlock Holmes book, &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;A_Study_in_Scarlet&quot;&gt;A Study in
Scarlet&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The wildcard character is &lt;code&gt;?&lt;&#x2F;code&gt;.  That character matches any character in the
text.  Wosp also supports truncation using either the dollar sign &lt;code&gt;$&lt;&#x2F;code&gt; or the
number sign &lt;code&gt;#&lt;&#x2F;code&gt; followed optionally by a number for the maximum number of
characters to include.  Searchers should include the number or else performance
may suffer, though.  Wildcards and truncation allow for powerful queries that
can match many different words with one wildcard given:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wosp &amp;quot;#2m?n&amp;quot; A_Study_in_Scarlet.txt
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:286:free as an income of eleven shillings and sixpence a day will permit a man to
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;#2m?n&lt;&#x2F;code&gt; matches &quot;man&quot;, &quot;men&quot;, &quot;woman&quot;, &quot;women&quot;, and &quot;human&quot; all in a single
term.&lt;&#x2F;p&gt;
&lt;p&gt;Wosp supports different case sensitivity options and fuzzy search with a given
edit distance.  The edit distance is the number of errors that Wosp can
correct.  It widens the search for keywords and can find typos, but too much
edit distance may find too many results.&lt;&#x2F;p&gt;
&lt;p&gt;The default is case insensitive search with an edit distance of zero.
Searchers control the case sensitivity and edit distance using the search
option commands &lt;code&gt;ICASE&lt;&#x2F;code&gt; (insensitive case), &lt;code&gt;SCASE&lt;&#x2F;code&gt; (sensitive case), &lt;code&gt;LCASE&lt;&#x2F;code&gt;
(lowercase), &lt;code&gt;UCASE&lt;&#x2F;code&gt; (uppercase), and &lt;code&gt;TCASE&lt;&#x2F;code&gt; (title case or more specifically
start case, where the initial letter is capitalized).  These commands must
precede either a wildcard term or parentheses.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wosp &amp;quot;TCASE holmes&amp;quot; A_Study_in_Scarlet.txt
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:425:&amp;quot;Dr. Watson, Mr. Sherlock Holmes,&amp;quot; said Stamford, introducing us.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To specify the edit distance with one of these commands, add the edit distance
number to the end of the command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wosp &amp;quot;ICASE1 detective&amp;quot; A_Study_in_Scarlet.txt
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:878:months or so. It might be made a text-book for detectives to teach them what to
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case, Wosp returned the word &quot;detectives&quot; since it is one error from
&quot;detective&quot;.  A better way to include plurals is to use truncation like with
&lt;code&gt;detective#1&lt;&#x2F;code&gt;, since it is more explicit about where the extra character goes.&lt;&#x2F;p&gt;
&lt;p&gt;Wosp supports Boolean operations.  Boolean operations return all matches for
documents that meet certain conditions.  The four Boolean operators are &lt;code&gt;OR&lt;&#x2F;code&gt;,
&lt;code&gt;AND&lt;&#x2F;code&gt;, &lt;code&gt;NOT&lt;&#x2F;code&gt;, and &lt;code&gt;XOR&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;OR&lt;&#x2F;code&gt; returns all matches for any term given in all documents.  Like all Boolean
operations, it takes two arguments.  Searchers can chain together multiple &lt;code&gt;OR&lt;&#x2F;code&gt;
statements to produce long lists of terms to search all at once.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wosp &amp;quot;detective#1 OR officer#1&amp;quot; A_Study_in_Scarlet.txt
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:260:however, with many other officers who were in the same situation as myself, and
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:816:am the only one in the world. I&amp;#39;m a consulting detective, if you can understand what that is. Here in London we have lots of Government detectives and lots of
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Searchers can string together many &lt;code&gt;OR&lt;&#x2F;code&gt; operations in a row.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wosp &amp;quot;detective#1 OR officer#1 OR police OR policem?n OR constable#1&amp;quot; A_Study_in_Scarlet.txt
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:260:however, with many other officers who were in the same situation as myself, and
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:487:might start a paper on those lines. Call it the Police News of the Past.&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;AND&lt;&#x2F;code&gt; returns results from files that contain both terms searched for.  It is
good for limiting the number of files to be searched.  &lt;code&gt;NOT&lt;&#x2F;code&gt; returns results
from files that contain the first term but not the second.  &lt;code&gt;XOR&lt;&#x2F;code&gt; works
similarly to &lt;code&gt;OR&lt;&#x2F;code&gt; but only returns documents with one of the terms given in the
sequence of &lt;code&gt;XOR&lt;&#x2F;code&gt; operations.&lt;&#x2F;p&gt;
&lt;p&gt;Wosp supports &lt;code&gt;OR&lt;&#x2F;code&gt; as the default operator.  Default operators are a feature of
some previous search systems, but I personally do not use them since I prefer
explicit queries.  Due to its support for default operators, Wosp treats
queries like &lt;code&gt;(first second third)&lt;&#x2F;code&gt; as &lt;code&gt;(first OR second OR third)&lt;&#x2F;code&gt;.  It does
not raise an error for a missing operator.  It is possible to change the
default operator but that requires re-compiling Wosp at the moment.&lt;&#x2F;p&gt;
&lt;p&gt;Wosp supports using parentheses to nest operations.  Parentheses are on the
highest precedence level, so they are evaluated first, just like in arithmetic
operations.  Parentheses allow for searchers to create expressive and precise
queries that join many different ideas into a single query.  This feature saves
advanced searchers time by preventing the needless repetition of many nearly
identical queries.&lt;&#x2F;p&gt;
&lt;p&gt;Wosp supports many different proximity operations.  &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Proximity_search_(text)&quot;&gt;Proximity
search&lt;&#x2F;a&gt; is a search
technique that allows searchers to find terms that are close to each other in
the text.  Closeness typically implies that the terms are related, so proximity
search ensures that searchers find relevant terms in the same context rather
than in different parts of a long document.  In that sense, proximity search
works like a more limiting form of the Boolean &lt;code&gt;AND&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The most basic form of proximity search is phrase search in quotes, which is
typically the only form of proximity search most search engines support today.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wosp &amp;quot;&amp;#39;police constable&amp;#39;&amp;quot; A_Study_in_Scarlet.txt
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:1070:and against this wall was leaning a stalwart police constable, surrounded by a
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This query is the same as &lt;code&gt;police ADJ constable&lt;&#x2F;code&gt;.  &lt;code&gt;ADJ&lt;&#x2F;code&gt; is the adjacency
operator.  It finds neighboring words in the order given.  One advantage of
using &lt;code&gt;ADJ&lt;&#x2F;code&gt; over quotes is that queries can support Boolean operations as
needed.  For example, using parentheses to group terms, a searcher can search
for &lt;code&gt;police ADJ (constable#1 OR officer#1 OR detective#1 OR m?n)&lt;&#x2F;code&gt; to broaden
their search without having to type &lt;code&gt;police&lt;&#x2F;code&gt; multiple times.&lt;&#x2F;p&gt;
&lt;p&gt;The other proximity operators do not have a given order like &lt;code&gt;ADJ&lt;&#x2F;code&gt;.  Instead,
they search in both directions within a given series of language elements.
&lt;code&gt;NEAR&lt;&#x2F;code&gt; searches neighboring words, &lt;code&gt;AMONG&lt;&#x2F;code&gt; searches in the same clause, &lt;code&gt;WITH&lt;&#x2F;code&gt;
searches in the same sentence, &lt;code&gt;ALONG&lt;&#x2F;code&gt; searches in the same line, and &lt;code&gt;SAME&lt;&#x2F;code&gt;
searches in the same paragraph.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wosp &amp;quot;detective#1 WITH (case#1 OR evidence)&amp;quot; A_Study_in_Scarlet.txt
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:1360:thing which may help you in the case,&amp;quot; he continued, turning to the two detectives. &amp;quot;There has been murder done, and the murderer was a man. He was
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:2217:&amp;quot;When Mrs. Charpentier paused,&amp;quot; the detective continued, &amp;quot; I saw that the whole case hung upon one point. Fixing her with my eye in a way which I always found
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Like the search option operators, all proximity operators support added numbers
at the end, and those numbers specify how many neighboring language elements to
search.  The default is one language element.  The following example searches
for several terms to within 5 words of each other:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wosp &amp;quot;(private OR police OR government) NEAR5 (constable#1 OR officer#1 OR detective#1)&amp;quot; A_Study_in_Scarlet.txt
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:817:what that is. Here in London we have lots of Government detectives and lots of private ones. When these fellows are at fault they come to me, and I manage to
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:1070:and against this wall was leaning a stalwart police constable, surrounded by a
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:2006:&amp;quot;It&amp;#39;s the Baker Street division of the detective police force,&amp;quot; said my
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Some systems support proximity search, but only between neighboring words.  In
these systems, it is impossible to nest proximity searches using parentheses.
Wosp allows nested proximity search without limitation.&lt;&#x2F;p&gt;
&lt;p&gt;For example, searchers can search for proximity matches in proximity to other
terms or other proximity matches.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wosp &amp;quot;night#1 WITH (bod#3 NEAR4 victim#1)&amp;quot; A_Study_in_Scarlet.txt
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A_Study_in_Scarlet.txt:2264:killed him without leaving any mark. The night was so wet that no one was about, so Charpentier dragged the body of his victim into the empty house. As
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Wosp&#x27;s query language is designed to be expressive like this.  It is designed
for advanced users who want power and precision.&lt;&#x2F;p&gt;
&lt;p&gt;Wosp also supports negated proximity operators (&lt;code&gt;NOT WITH&lt;&#x2F;code&gt;, etc.).  These are
useful on occasion but I often avoid them unless I have a compelling reason to
use them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-wosp-works-inverted-indices-technical-discussion&quot;&gt;How Wosp works: inverted indices (technical discussion)&lt;&#x2F;h2&gt;
&lt;p&gt;On a high level, Wosp performs the following steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Read all documents into doubly-linked lists where each list element is a
word.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Inverted_index&quot;&gt;full inverted
index&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Lex a query, parse it using a &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Recursive_descent_parser&quot;&gt;recursive descent
parser&lt;&#x2F;a&gt;, and evaluate
it using the full inverted index.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Output the results of the query.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The first step is the easiest to understand.  All words in the doubly-linked
list then have known neighbors and positions in each document, as depicted
below.&lt;&#x2F;p&gt;
&lt;figure&gt;

&lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;www.andrewtrettel.com&amp;#x2F;wosp-document.svg&quot;&gt;

&lt;figcaption&gt;A document represented as a
doubly-linked list of words with given positions.&lt;&#x2F;figcaption&gt;

&lt;&#x2F;figure&gt;
&lt;p&gt;The second step requires more explanation.  An inverted index is an index for
every word used in a series of documents, akin to the index in the back of
books.  Given a particular word, the index allows searchers to find every
instance of that word.  Once a searcher has built an inverted index, it is
trivial to find any given word.  The index especially speeds up queries that
require finding many different words, since it stores all possible word
locations.  With an inverted index, the rest of the program only needs to
perform various operations on any searched terms.  Wosp performs these
operations using an interpreter that turns search queries into a list of
operations to perform in a tree of operations that ends with wildcard searches,
which just look up terms in the inverted index.  The search option commands
modify how wildcard search occurs.&lt;&#x2F;p&gt;
&lt;p&gt;The doubly-list list of all words means that every word has a specified
position in each document.  Building the inverted index then is just a matter
of going through each document again and noting the location of each word.
Wosp does this using a trie data structure, as depicted below.&lt;&#x2F;p&gt;
&lt;figure&gt;

&lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;www.andrewtrettel.com&amp;#x2F;wosp-inverted-index.svg&quot;&gt;

&lt;figcaption&gt;An inverted index going
from a given word to all of its positions in a document.&lt;&#x2F;figcaption&gt;

&lt;&#x2F;figure&gt;
&lt;p&gt;A trie is a special type of tree data structure where each node contains a
letter of a word and all edges lead to the next possible letter.  For example,
the word &quot;works&quot; starts at &quot;w&quot;, continues does the edge for &quot;o&quot;, then &quot;r&quot;, then
takes the edge &quot;k&quot; instead of &quot;d&quot;, then &quot;s&quot;, and then finally arrives at a list
of all positions of all words &quot;works&quot; in all documents.  Wosp does not
implement these positions as integers but instead as pointers, but the same
principle applies.&lt;&#x2F;p&gt;
&lt;p&gt;There are certainly more efficient ways to create an inverted index, but I
stuck with a trie due to its simplicity.&lt;&#x2F;p&gt;
&lt;p&gt;Wosp does not support &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Stop_word&quot;&gt;stop words&lt;&#x2F;a&gt;, so
all words are indexed (including extremely common words).  I made this decision
to keep Wosp lean.&lt;&#x2F;p&gt;
&lt;p&gt;Indexed search is entirely different than the sequential search methods used by
programs like grep.  On a high level, grep looks for a pattern in each line of
text in sequence (I realize that &lt;a href=&quot;https:&#x2F;&#x2F;lists.freebsd.org&#x2F;pipermail&#x2F;freebsd-current&#x2F;2010-August&#x2F;019310.html&quot;&gt;some
implementations&lt;&#x2F;a&gt;
do not implement this idea literally).  Sequential search does not require an
overarching data structure for organizing that search.  Both approaches have
their advantages and disadvantages.  The primary advantage of sequential search
methods is speed, since it may be possible to read each document once and
return results while reading the document.  &lt;a href=&quot;https:&#x2F;&#x2F;search.worldcat.org&#x2F;title&#x2F;40602840&quot;&gt;It is possible to implement
proximity search&lt;&#x2F;a&gt; using sequential
search methods, but it is easier to implement nested proximity search using an
indexed search method.  This observation is easy to see once you realize that
nested queries may require multiple passes over the same document anyway, which
defeats the purpose of a sequential search algorithm.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-wosp-works-query-language-technical-discussion&quot;&gt;How Wosp works: query language (technical discussion)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;zing.z3950.org&#x2F;cql&#x2F;intro.html&quot;&gt;Previous work&lt;&#x2F;a&gt; has divided query
languages into two classes: languages that are powerful for advanced searchers
but difficult for most searchers, and languages that are weak for advanced
searchers but easy for most searchers.  I designed Wosp for advanced users who
know what they want to search.  To that end, Wosp queries do exactly what the
user requests --- no more and no less.  Wosp does not engage in any &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Query_expansion&quot;&gt;query
expansion&lt;&#x2F;a&gt;, so it does not find
any plurals or synonyms, does not perform any stemming (unless explicitly
requested using trailing truncation), and does not correct any spelling errors
(unless explicitly requested using a higher edit distance).  This design choice
keeps Wosp lean and grants searchers more power.&lt;&#x2F;p&gt;
&lt;p&gt;I developed the query language&#x27;s order of operations (precedence) slowly.  I
initially intended to follow previous efforts like BRS&#x2F;Search and IBM STAIRS,
but despite extensive searching on my part, I never found any formal
documentation for the order of operations for the query language of those
programs.  I did find three references that provided incomplete information
about the order of operations of these systems, but the information was
contradictory.  For example, The USPTO&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;www.uspto.gov&#x2F;patents&#x2F;search&#x2F;patent-public-search&#x2F;operators&quot;&gt;Patent Public
Search&lt;&#x2F;a&gt;
notes that the the precedence of proximity operators goes from the largest
language elements (lowest precedence) to the smallest language elements
(highest precedence), but it does not comment on the precedence of any Boolean
operators.  I found two other third-party documents that list the order of
operations for IBM STAIRS (&lt;a href=&quot;https:&#x2F;&#x2F;inis.iaea.org&#x2F;records&#x2F;v6s7h-h4r67&quot;&gt;Gagjokov et al.
1976&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;search.worldcat.org&#x2F;title&#x2F;8034654&quot;&gt;Salton and McGill
1983&lt;&#x2F;a&gt;), but their reported Boolean
operator precedence contradicts each other.&lt;&#x2F;p&gt;
&lt;p&gt;In the end, I implemented the same order of operations for the Boolean
operators as for &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Logical_connective&quot;&gt;logical
connectives&lt;&#x2F;a&gt; in mathematics.
I credit my mother for recommending this.  This choice means that Wosp may not
behave the same as previous systems, but users at least know &lt;em&gt;how it does
behave&lt;&#x2F;em&gt; given its explicit order of operations.&lt;&#x2F;p&gt;
&lt;p&gt;The operator precedence levels are given below.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Atoms: wildcards, parentheses (nested queries).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Search options: &lt;code&gt;ICASE&lt;&#x2F;code&gt;, &lt;code&gt;LCASE&lt;&#x2F;code&gt;, &lt;code&gt;SCASE&lt;&#x2F;code&gt;, &lt;code&gt;TCASE&lt;&#x2F;code&gt;, &lt;code&gt;UCASE&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Adjacency operations: &lt;code&gt;ADJ&lt;&#x2F;code&gt;, &lt;code&gt;NOT ADJ&lt;&#x2F;code&gt;, phrases (quotes).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Word proximity operations: &lt;code&gt;NEAR&lt;&#x2F;code&gt;, &lt;code&gt;NOT NEAR&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Clause proximity operations: &lt;code&gt;AMONG&lt;&#x2F;code&gt;, &lt;code&gt;NOT AMONG&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Sentence proximity operations: &lt;code&gt;WITH&lt;&#x2F;code&gt;, &lt;code&gt;NOT WITH&lt;&#x2F;code&gt;, &lt;code&gt;ALONG&lt;&#x2F;code&gt;, &lt;code&gt;NOT ALONG&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Paragraph proximity operations: &lt;code&gt;SAME&lt;&#x2F;code&gt;, &lt;code&gt;NOT SAME&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Boolean negation: &lt;code&gt;NOT&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Boolean conjunction: &lt;code&gt;AND&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Boolean disjunction: &lt;code&gt;OR&lt;&#x2F;code&gt;, &lt;code&gt;XOR&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;future-work&quot;&gt;Future work&lt;&#x2F;h2&gt;
&lt;p&gt;As much as I want to keep Wosp clean and minimal in its implementation, there
are still many features that I want to include.&lt;&#x2F;p&gt;
&lt;p&gt;The most immediate features that I want to add:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Different character encodings.&lt;&#x2F;em&gt; Wosp currently only supports ASCII well.
Searchers can search for words with international characters, and use them
with Boolean and proximity operations, but wildcards do not work properly
with international characters.  Eventually Wosp needs to support
international characters properly from the ground up.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Command-line options.&lt;&#x2F;em&gt;  I have endeavored to put as many of the options into
the query language itself rather than into command line arguments, but it
should also be possible to control several options at the command line too.
I have preferred extending the query language because this provides much more
expressiveness overall, since command line options may be limited to global
options.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Highlighted keywords.&lt;&#x2F;em&gt; At the moment, Wosp does not highlight keywords, but
it should.  The match data structures already contain all of the information
for highlighting.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Input options.&lt;&#x2F;em&gt; Wosp must include options for how to split words and treat
punctuation.  At the moment, Wosp defines words as anything between
whitespace, but some systems support additional ways to define word
boundaries.  For example, I should add an option to determine whether
hyphenated words count as one word or two.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Output options.&lt;&#x2F;em&gt; I have included some additional output options already, but
these are hardcoded and require re-compilation to enable at the moment.  That
is obviously quite limiting.  At the moment, Wosp does not support ranking
the results in any form at all.  It should be possible to specify how to rank
the results, especially since this grants the user far more control than what
many web search engines grant at the moment.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Other features that I may add eventually:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Additional operations.&lt;&#x2F;em&gt;  I have some ideas for additional operations, but I
am wary of adding any that do not have a particular use case.  Wosp already
supports page numbers but lacks any operator for page-based proximity search.
This would be trivial to add if needed.  I have considered &lt;code&gt;UPON&lt;&#x2F;code&gt; as the
syntax for this.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Field support.&lt;&#x2F;em&gt; Fields are information like titles, abstracts, the list of
authors, and other information about a document.  Wosp already divides each
document up into individual fields, but it lacks any facility to select
individual fields.  At the moment, the only field loaded is the text itself.
One issue is that text files typically do not have any additional fields
(other than the filename, file extension, and other file properties), but PDF
files or Markdown files might have some, though I am debating whether direct
support for PDF files is in the scope of the program or not.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Interactive REPL.&lt;&#x2F;em&gt; Given all of the overhead involved in loading documents,
I would appreciate the ability to perform multiple searches without having to
re-create the inverted index, especially to refine the results.  A
&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Read%E2%80%93eval%E2%80%93print_loop&quot;&gt;REPL&lt;&#x2F;a&gt;
allows that.  A REPL should also introduce the ability to modify previous
searches using variables, like what the USPTO&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;www.uspto.gov&#x2F;patents&#x2F;search&#x2F;patent-public-search&quot;&gt;Patent Public
Search&lt;&#x2F;a&gt; allows
with &lt;a href=&quot;https:&#x2F;&#x2F;www.uspto.gov&#x2F;sites&#x2F;default&#x2F;files&#x2F;documents&#x2F;Advanced-search-overview-QRG-Patent-Public-Search.pdf&quot;&gt;L
numbers&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;discussion-elsewhere&quot;&gt;Discussion elsewhere&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=45823214&quot;&gt;Show HN&lt;&#x2F;a&gt; thread.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;commandline&#x2F;comments&#x2F;1p3z2w6&#x2F;built_on_my_own_advanced_fulltext_search_tool&#x2F;&quot;&gt;Reddit
thread&lt;&#x2F;a&gt;
on &lt;code&gt;r&#x2F;commandline&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Research</title>
        <published>2025-04-09T00:00:00+00:00</published>
        <updated>2026-02-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrew Trettel
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.andrewtrettel.com/research/"/>
        <id>https://www.andrewtrettel.com/research/</id>
        
        <content type="html" xml:base="https://www.andrewtrettel.com/research/">&lt;h2 id=&quot;links&quot;&gt;Links&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;scholar.google.com&#x2F;citations?user=gmJ8SqMAAAAJ&quot;&gt;Google Scholar&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;orcid.org&#x2F;0000-0002-6671-2524&quot;&gt;ORCiD&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;peer-reviewed-journal-articles&quot;&gt;Peer-reviewed journal articles&lt;&#x2F;h2&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;
&lt;p&gt;Andrew Trettel (2026).  &quot;Interface-fitted coordinate systems for
two-dimensional imploding shell problems&quot;.  In preparation for submission to a
peer-reviewed journal.  LA-UR-25-29021.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Andrew Trettel and Johan Larsson (2016).  &lt;a href=&quot;https:&#x2F;&#x2F;pubs.aip.org&#x2F;aip&#x2F;pof&#x2F;article&#x2F;28&#x2F;2&#x2F;026102&#x2F;932613&#x2F;Mean-velocity-scaling-for-compressible-wall&quot;&gt;&quot;Mean velocity scaling for
compressible wall turbulence with heat
transfer&quot;&lt;&#x2F;a&gt;.
Physics of Fluids 28.2, DOI:
&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1063&#x2F;1.4942022&quot;&gt;10.1063&#x2F;1.4942022&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Ponnuthurai Gokulakrishnan, Richard Joklik, Darin Viehe, Andrew Trettel,
Esteban Gonzalez-Juez, and Michael Klassen (2014).  &lt;a href=&quot;https:&#x2F;&#x2F;asmedigitalcollection.asme.org&#x2F;gasturbinespower&#x2F;article-abstract&#x2F;136&#x2F;1&#x2F;011503&#x2F;373687&#x2F;Optimization-of-Reduced-Kinetic-Models-for?redirectedFrom=fulltext&quot;&gt;&quot;Optimization of Reduced
Kinetic Models for Reactive Flow
Simulations&quot;&lt;&#x2F;a&gt;.
Journal of Engineering for Gas Turbines and Power 136.1. ISSN: 0742-4795. DOI:
&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1115&#x2F;1.4025265&quot;&gt;10.1115&#x2F;1.4025265&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;patents&quot;&gt;Patents&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Ponnuthurai Gokulakrishnan, Darin Viehe, Andrew Trettel, and Michael S.
Klassen (2024). Computationally Efficient Reduced Kinetics Methodologies For
Jet Fuels. English. &lt;a href=&quot;https:&#x2F;&#x2F;patents.google.com&#x2F;patent&#x2F;US11914930B1&quot;&gt;US 11914930
B1&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;other-publications&quot;&gt;Other publications&lt;&#x2F;h2&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;
&lt;p&gt;Andrew Trettel (June 2019). &lt;a href=&quot;https:&#x2F;&#x2F;escholarship.org&#x2F;uc&#x2F;item&#x2F;9n57p4cv&quot;&gt;&quot;Transformations for variable-property
turbulent boundary layers&quot;&lt;&#x2F;a&gt;.
PhD dissertation. University of California, Los Angeles.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Samet Demircan and Andrew Trettel (2016).  &lt;a href=&quot;https:&#x2F;&#x2F;www.osti.gov&#x2F;biblio&#x2F;1327993-final-reports-from-los-alamos-national-laboratory-computational-physics-student-summer-workshop&quot;&gt;&quot;Direct Numerical Simulations of
Multi-Species Variable-Density
Turbulence&quot;&lt;&#x2F;a&gt;.
Variable-Density Turbulence”. 2016 Final Reports from the Los Alamos National
Laboratory Computational Physics Student Summer Workshop. Los Alamos National
Laboratory, pp. 125–132.  LA-UR-16-27258.
&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.2172&#x2F;1327993&quot;&gt;10.2172&#x2F;1327993&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Andrew Trettel (May 2015).  &lt;a href=&quot;http:&#x2F;&#x2F;hdl.handle.net&#x2F;1903&#x2F;16797&quot;&gt;&quot;Velocity transformation for compressible wall
turbulence with heat transfer&quot;&lt;&#x2F;a&gt; MS thesis.
University of Maryland, College Park. DOI:
&lt;a href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.13016&#x2F;M2F33V&quot;&gt;10.13016&#x2F;M2F33V&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Welcome to my website</title>
        <published>2024-09-07T00:00:00+00:00</published>
        <updated>2024-09-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrew Trettel
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.andrewtrettel.com/blog/welcome/"/>
        <id>https://www.andrewtrettel.com/blog/welcome/</id>
        
        <content type="html" xml:base="https://www.andrewtrettel.com/blog/welcome/">&lt;p&gt;I created a website when I was in high school, but abandoned it after a few
years.  In the intervening years, I realized that I need some presence on the
Internet, especially to serve as a place to contact me or find out about work
that I have done.  I do not use social media in general, so this website is a
better place to access information about me or work that I have done.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;blog&quot;&gt;Blog&lt;&#x2F;h2&gt;
&lt;p&gt;Previously I would have balked at the idea of writing a blog.  I did not think
that I had anything to write that somebody else did not already write better.
Nowadays, I realize that there are many subjects that I can cover that others
have overlooked or did not know about.  I intend to cover various overlooked
subjects or anything I think that I can provide new insight into on my own
schedule when time permits.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;website-design&quot;&gt;Website design&lt;&#x2F;h2&gt;
&lt;p&gt;All design is about tradeoffs.  I wanted a website that I did not need to spend
much time maintaining, focused on the content, but nonetheless is visually
distinctive.  In &quot;good, fast, cheap, pick two&quot;, I picked &quot;good&quot; and &quot;cheap&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;I tried out &lt;a href=&quot;https:&#x2F;&#x2F;www.getzola.org&#x2F;&quot;&gt;Zola&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;gohugo.io&#x2F;&quot;&gt;Hugo&lt;&#x2F;a&gt; as
static site generators.  Both compile to a single binary, which was my only
requirement.  In the end, I used Zola because it seems to have a more gradual
learning curve.  It actually took me a surprising amount of time to compile
both since I had to manually install Rust and Go compilers due to both Zola and
Hugo requiring quite recent versions of Rust and Go respectively.&lt;&#x2F;p&gt;
&lt;p&gt;I created my own theme in Zola since I wanted a visually distinctive website.
That said, I adopted a minimalist process to save time and reduce the work I
need to maintain the site.  I consider minimalism to be a process rather than
an outcome.  My goal was to reduce the number of design choices that I need to
make while still achieving my design goals.  Unlike other minimalist websites,
I wanted some visual elements beyond text and whitespace to create a visually
distinct website, so I included a few photos that I took over the years for
additional distinction.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Contact</title>
        <published>2024-08-10T00:00:00+00:00</published>
        <updated>2026-04-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrew Trettel
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.andrewtrettel.com/contact/"/>
        <id>https://www.andrewtrettel.com/contact/</id>
        
        <content type="html" xml:base="https://www.andrewtrettel.com/contact/">&lt;p&gt;See the image above for how to contact me.  This image may change from time to
time.&lt;&#x2F;p&gt;
&lt;p&gt;I am on the web in a few other places too:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;andrewtrettel.com&quot;&gt;Bluesky&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atrettel&quot;&gt;GitHub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;user?id=atrettel&quot;&gt;Hacker News&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;archive.org&#x2F;details&#x2F;@atrettel&quot;&gt;Internet Archive&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;user&#x2F;AndrewTrettel&#x2F;&quot;&gt;Reddit&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;stackexchange.com&#x2F;users&#x2F;23003958&#x2F;andrew-trettel&quot;&gt;StackExchange&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;x.com&#x2F;AndrewTrettel&quot;&gt;Twitter&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
</feed>
