<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>emre şahin's digital garden 🍃 - NLP</title>
    <link>https://emresahin.net/categories/nlp/</link>
    <description>Posts in the NLP category</description>
    <language>en</language>
    <managingEditor>contact@emresahin.net (Emre Şahin)</managingEditor>
    <lastBuildDate>Tue, 15 Sep 2026 19:46:32 +0000</lastBuildDate>
    <atom:link href="https://emresahin.net/categories/nlp/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>Progress on Ottoman Translation - Week 6, 2018</title>
      <published>2018-02-05T07:23:43+00:00</published>
      <updated>2018-02-05T07:23:43+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Mon, 05 Feb 2018 07:23:43 +0000</pubDate>
      <link>https://emresahin.net/dervaze-progress-2018-6-14084-62774/</link>
      <guid isPermaLink="true">https://emresahin.net/dervaze-progress-2018-6-14084-62774/</guid>
      <description>Some of the upcoming posts will serve as a TODO list for the coming months, outlining my plans for Dervaze and its mobile versions. As a solo developer, I’ll share my experiences with this problem here to help those interested. The technology for Ottoman OCR was mostly ready before my family obli...</description>
      <category>NLP</category>
      <category>History</category>
      <category>Ottoman Turkish</category>
      <category>OCR</category>
      <category>C</category>
      <category>Dervaze</category>
      <category>Linguistics</category>
      <content:encoded><![CDATA[<p>Some of the upcoming posts will serve as a TODO list for the coming months, outlining my plans for <a href="http://dervaze.com">Dervaze</a> and its mobile versions. As a solo developer, I’ll share my experiences with this problem here to help those interested.</p>
<p>The technology for Ottoman OCR was mostly ready before my family obligations interrupted the project. I need to re-evaluate what is currently available, but a more pressing problem for me is the <em>speed</em> of translation; currently, it is so slow that it’s barely usable.</p>
<p>I have written the dictionary as a C library without any database dependencies and integrated it into the Android version. I’m currently updating the search functionality in the mobile app to use this library instead of a web service. It will be orders of magnitude faster than the current version because it’s offline and uses a <a href="https://en.wikipedia.org/wiki/Trie">trie</a> to store the words—making it both small and fast.</p>
<p>In my experience, having a single data structure with dedicated functions for transforming and indexing is much simpler than managing multiple data structures. In my case, the core structure is:</p>
<pre><code class="language-c">typedef struct _dervaze_lexical_item {
  int index;
  bstr latin_search_key;
  bstr latin;
  bstr visenc_search_key;
  bstr visenc_dotless_search_key;
  bstr visenc;
  bstr annotation;
  bstr meaning;
  bstr abjad;
  lexical_role role;
  int last_vowel;
  int props;
} dervaze_lexical_item;
</code></pre>
<p><code>visenc</code> is our abbreviation for <em>visual encoding</em>, which is used to represent Arabic/Ottoman/Farsi words using basic ASCII letters. It is documented on its <a href="https://emresahin.net/visual-encoding-for-ottoman/">own page</a>.</p>
<p><code>index</code> is a unique identifier assigned to each word. Search keys for Latin, Visenc, and <em>Dotless Visenc</em> (e.g., searching for ﺥ using letters like ح, چ, or ج) are used to locate these lexical items via the tries mentioned earlier.</p>
<p>I’m intentionally avoiding UTF-8 or other Unicode encodings because terminal output is often not well-suited for displaying Arabic text correctly.</p>
<p>When I began writing this software, one of my goals was to enable searching for words by their traditional numeric values (Abjad). These are often used in classical Ottoman poetry to encode a date within a verse. For example, the letter Alif corresponds to 1, Ba (ب) to 2, and so on. To search for words by these numerals—for instance, typing 246 to find words with that total value—we store the value here as well.</p>
<p>The <code>lexical_role</code> is used during translation; currently, we use two roles to distinguish between noun and verb suffixes in Turkish.</p>
<p><code>last_vowel</code>, as the name implies, represents the last vowel of the word. Since vowel harmony in Turkish is not always reflected in Ottoman spelling, we check the last vowel when converting an Ottoman word to its Latin Turkish equivalent to ensure the correct suffix is added (e.g., <em>gemiler</em> instead of <em>gemilar</em>).</p>
<p><code>props</code> is a bit field used to represent various properties of the lexical item, such as:</p>
<pre><code class="language-c">#define HAS_FINAL_VOWEL 0x01
#define HAS_SINGLE_VOWEL 0x02
#define IS_LAST_VOWEL_HARD 0x04
#define IS_FINAL_CONSONANT_HARD 0x08
#define HAS_CONSONANT_SOFTENING 0x10
</code></pre>
<p>These properties are particularly important when converting Ottoman text to modern Turkish.</p>
<p>The current version of the translation engine is written in Python, but I plan to rewrite it in C this week. As this is the third rewrite, I don’t expect it to pose a major algorithmic challenge, although debugging the C version may be more demanding.</p>]]></content:encoded>
    </item>
    <item>
      <title>A Regular Conversion Algorithm Between Turkish and Ottoman</title>
      <published>2012-09-24T14:00:00+00:00</published>
      <updated>2012-09-24T14:00:00+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Mon, 24 Sep 2012 14:00:00 +0000</pubDate>
      <link>https://emresahin.net/12125-3-3162/</link>
      <guid isPermaLink="true">https://emresahin.net/12125-3-3162/</guid>
      <description>Modern Turkish spells all words of Turkish, Arabic, or Farsi origin according to their pronunciation. When it comes to converting from one system to another, this creates a problem that can be addressed with the aid of regular expressions. For example, in Ottoman, a word is spelled as mnwr (mim-n...</description>
      <category>Dervaze</category>
      <category>Linguistics</category>
      <category>NLP</category>
      <category>Turkish</category>
      <category>Ottoman</category>
      <category>transliteration</category>
      <category>regular expressions</category>
      <category>dictionary search</category>
      <category>handwriting recognition</category>
      <category>spelling conversion</category>
      <content:encoded><![CDATA[<p>Modern Turkish spells all words of Turkish, Arabic, or Farsi origin according to
their pronunciation. When it comes to converting from one system to another,
this creates a problem that can be addressed with the aid of regular
expressions.</p>
<p>For example, in Ottoman, a word is spelled as <em>mnwr</em> (mim-nun-vav-ra), following the Arabic
orthography, but in Modern Turkish, the spelling reflects the pronunciation as <em>münevver</em>.
Since a one-to-one mapping is not possible between these two writing systems, a set of
<em>possible Ottoman spellings</em> must be produced using a regular expression.</p>
<p>When the parser sees <em>münevver</em>, it should convert this to a pattern like
<code>mv?nh?(a1)?ww?h?r</code>. This pattern produces a set of strings, where <code>mvnha1vvhr</code>
might be the longest and <code>mnwr</code> the shortest. By performing a dictionary search,
the system can verify that there is a word in Ottoman spelled as <em>mnwr</em>, thus
selecting it as the correct spelling.</p>
<p>The dictionary in our study consists of word labels. The system will look up a set
of handwritten word images after this label lookup and search for these
images in the document. It can also <em>create</em> a set of candidate images from the
regular expression by rendering each candidate spelling.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
