Friday, December 16, 2011

The relativity theory of superiority

Everybody knows that Hanuman is very humble and always considered him only a daasa of Rama. But how humble was he? Can his humbleness be mistaken for weakness or lack of confidence?

Valmiki establishes the character of Hanuman in such a way that whatever action he took, that was possibly indeed the only best course of action. Throughout the course of sundara kanda, Hanuman makes numerous instant decisions that lead the story from one thrilling frame to another. The whole sundara kanda, frame-to-frame, is about how to take right decisions at the right time.

One such scene is when Hanuman takes departure from Sita. A simplistic retell of the story is just that Hanuman gets the cUDAmaNi from Sita and promises her that he will be back with Rama to free her. But in the details, Valmiki establishes a very deep analysis of human emotions in sorrow. Every dialog of which is something we can relate to easily in our lives.

In foreign lands, especially in remote towns, desis easily get excited by seeing one of their own. One may be from a remote village in South and another from Punjab. But in a foreign town of ten desis, language, religion and other barriers are forgotten and everyone instantly feels 'bhai-bhai'. After a long time, Sita has finally met someone who is acquainted with her husband. She naturally pleads Hanuman to stay secretly nearby for one more day, for it will console her to have someone nearby in the dreaded ashoka vana. Inspite of knowing Hanuman's exploits, she then carefully places a doubt whether Sugriva and his army of monkeys are capable of crossing the ocean and taking on the might of Ravana.

A very tricky question indeed. He has just crossed the ocean after a long journey, seen how huge, glorious yet intimidating Lanka is. He knows Rama is superior, he believes in his own strength, but he does not know the full strength of Ravana and his company yet. There is no indication he had given thought about how other monkeys can cross the ocean. Hanuman cannot say something like 'Yeah ma'm, we will try our best'. He has to completely reassure Sita of the capabilities.

The sequence of arguments he puts forth is very logical. He first mentions the leader, Sugriva is completely committed to the cause (of freeing her). Then he mentions the number of monkeys in his army (thousands of crores of monkeys). That sheer number should give confidence to Sita. Then he mentions their overall qualities - power, perseverance and loyalty to Sugriva. He finally puts forward a statement thats unbelievably astonishing, that silences any doubt of not only Sita, but even the reader.

मत् विशिष्टाः च तुल्याः च सन्ति तत्र वनौसः ।
मत्तः प्रत्यवरः कश्चिन् न अस्ति सुग्रीव संनिधौ ||

mat vishiShTaaH ca tulyaaH ca santi tatra vanausaH |
mattaH pratyavaraH kashcin na asti sugrIva saMnidhau ||

अहम् तावत् इह प्राप्तः किम् पुनः ते महाबलाः ।
न हि प्रकृष्टाः प्रेष्यन्ते प्रेष्यन्ते हि इतरे जनाः ॥

aham taavat iha praaptaH kim punaH te mahaabalaaH |
na hi prakRuShTaaH preShyante preShyante hi itare janaaH ||

All other monkeys are either equal to me or above me in valor. There is no one inferior to me in Sugriva's army. If I could come here in one leap, what to say about others? Superiors are not sent for errands, only the inferiors are, isn't it?

Hanuman was hand picked for this task by none other than the great Jambavan, further entrusted personally by Rama, purely on the basis of his most superior ablities. Yet Hanuman turns it around completely the other way, quoting that only inferior people are sent for errands, which for a moment makes perfect sense to console Sita. He does not say he is the most inferior - that would have shown lack of confidence. He says there is no one else inferior than him. He is humble, yet there is absolutely no lack of confidence.

Simply put, there is no other statement that would have quelled the doubt of Sita, than how Hanuman put it.

Thursday, December 15, 2011

The power of dsl

When I started the samskritam-dsl project, one of my goals was to develop a domain-specific language that will allow to interact with the system using a natural syntax. Not just a programmer, but a samskritam pundit with a basic computer knowledge should be able to interact with the system. While that interaction is still a long way, I feel there are some foundations in place. The sandhi-s as described in ashtaadhyayI are very arithmetic like, yielding consistent results, so a program model should be able to simulate that.

For eg

assert 'a' + 'a' == 'A' //akaH savarNe dIrghaH sandhi


instead of

assert new Varna('a').add(new Varna('a').equals(new Varna('A')) == true


The former is obviously easier to understand as it follows mathematical conventions, instead of being bound by rigid programmatic syntaxes.

Static programming languages like Java just do not allow this kind of flexibility. But dynamic languages like Groovy/Ruby/Scala having special features for creating such constructs.

Let's go a step further than the above simple sandhi:

assert 'bhU' + 'sap' + 'tiG' == 'bhavati'  //bhU dhatu, kartari sap, prathama, parasmai-padam, eka vacanam, prathama purushaH


Is the above possible?

Before we answer that, does the above assert statement make sense at all? How do you know, or how do you make the computer know, that bhU is the dhaatu, sap is the vikaraNa pratyayaH, and tiG is the padam pratyayaH ? They are all straight strings and not objects. How do you tell the difference? Now lets say we rewrite the above assert slightly differently --

assert 'bhU'.dhatu + 'sap'.pratyaya + 'tiG'.pratyaya == 'bhavati'


Now, that reads better! A simple domain knowledge is now converted into a programmatic construct, yet it almost reads just like samskritam! As you read the sentence, it seems very natural. 

That, mon ami, er, mama mitrANi, is the power of dsl.

Here are the implementation details:

@Category(String)
class Samskritam {
  def getPratyaya() { return new Pratyaya(this) }
  def getDhatu() { return new Dhatu(this) }
  }
}

class Dhatu {
  def name
  
  Dhatu(String _name) { name = _name }
  
  @Override
  String plus(Pratyaya p) { name + ' ' + p.toString() }
  
  @Override
  String toString() { name }
}

class Pratyaya {
  String value
  String realValue
  
  Pratyaya(String _value) {
    value = _value
    realValue = value?.tasya_lopaH()
  }
  
  @Override
  String toString() { realValue }
}

So what sutram-s are involved here? Lets skim through the important ones -

bhU + shap -> p gets dropped due to halantyam; sh gets dropped due to lashaku ataddhite
bhU + a -> bhO + a; due to aad guNaH
bhO + a -> bhav; due to eco ayavaayaavaH
tiG -> the G gets dropped due to halantyam
bhav + a + ti -> bhavati
 
Here is the complete test case:

use (ch8.lang.Samskritam) {
  def a1 = 'bhU'.dhatu + 'shap'.pratyaya + 'tiG'.pratyaya
  def a2 = sandhi.apply(a1, sandhi.aad_guNaH)
  def padam = sandhi.apply(a2, sandhi.eco_ayavaayaavaH)
  assert padam == 'bhavati'
}
The sandhi methods aad_guNaH and eco_ayavaayaavaH also obediently follow Paninian technique of replace the varnas using respective rules. 

Once again, the full code is in github.com/vasya10/samskritam

Sunday, December 11, 2011

sthAne antaratamaH

A Functional Approach

It is very interesting to observe that Panini's approach to sandhi-s is thoroughly function oriented and very algebraic in execution. Sandhi-s in Samskritam are profound sophistications. We shall see how functional programming naturally fits into Panini's approach. Once again I'm not describing theories, but real testable executable code and assertable outputs.

For the samskritam-dsl project, I was trying to come up with a simplistic representation of sandhi-s. The famous iko yan aci sandhi belongs to the purva rupa sandhi (the first word gets modified) and Panini's general technique can be functionally written as:

f = sandhi(sthana, adesha, vidhi, purva, para)

This is understood as:  "The adesha (substitute) replaces the sthana (substituted) of the purva shabda when vidhi is true on the para shabda"

Panini uses natural linguistic approach and places sthana in 6th vibhakti, adesha in 1st vibhakti and vidhi in 7th vibhakti.

So lets rewrite this in functional programming notation -

  //purva rupa sandhi sutra - closure
  def purvaRupaSandhi = {sthana, adesha, condition, words ->
    def (purva, para) = words.tokenize()
    if (condition(para)) {
      def k = sthana.substitute(adesha, purva.lastVarna())
      purva.replaceLast(k)
      purva + para
    } else {
      words
    }
  }

Here sthana is the list of substituted varnas (eg ik), adesha is the substitute varna (yaN). Condition is not a list but something that evaluates to true or false based on the para shabda. So its a closure again.

  def aci = { word -> word.varnas()[0].svara() }
  def jshi = { word -> word.varnas()[0] in sivaSutra.jsh }
  

Basically the above closure evaluates to true if the first varna of the shabda is a svara.

Remember we defined the purvaRupaSandhi as a completely generic closure. It will take any sthana, adesha and condition. How do we apply this to iko yaN aci or say, jhalaam jash jhashi?

Groovy provides the "currying" feature --

  def iko_yaN_aci = purvaRupaSandhi.curry(sivaSutra.ik, sivaSutra.yN, aci)
  def JalAm_jash_Jashi = purvaRupaSandhi.curry(sivaSutra.Jl, sivaSutra.js, jshi)

Real functional programming stuff here. aci and jshi are closures/functions which are passed to purvaRupaSandhiwhich evaluates it based on the para shabda.

Now for some more beauty. How do we substitute sthana with adesha? Panini defines a really brilliant sutra 'sthAne antaratamaH' - the closest phoneme of the adesha to the sthana, must substitute the sthana. Now how do we find the closest ? When pronouncing it is easy to realize that i is close to y or u is close to v. But how does that translate to programming terms? This is when it dawns upon us that Panini's approach is extremely methodical.

Recall the definitions of phoneme-sets?

akUhavisarjaniyanaam kanTaH | icuyashaanaam taalu | RturaShaaNaam mUrhda | Ltulasaanaam danta | upUpadhmaanIyaanaam oshta |

So if a varna from sthAna exists in one of the above sets of phonemes, then the common varna between that phoneme-set and the adesha will substitute the sthana !!!

Illustration: jhalaam_jas_jashi

example: ap + dhi

purva shabda - ap (varna is p), para shabda - dhi, satisifies condition jashi (dha). Good.

sthAna - p, adesha will be one of jash = [j, b, g, d, dh] -- now which to pick?

p exists in oshta phoneme-set; so we have to pick one from pu = [p, ph, b, bh, m] - but which one?

Remember jash adesha is [j, b, g, d, dh]. So intersect oshta with adesha, which will result in b -> that substitutes 'p' - resulting in abdhi !

Can you now appreciate the functional beauty of maheshvara sutra?

So the formula is
  
  def ku = [k, kh, g, gh, ~n]
  def kanta = ['a', 'A'] + ku + ['h'] + [':']
    Closure sthaneAntaratamaH = { x, adesha ->
    for (def phonemeSet : [kanta, taalu, murdha, danta, oshta, dantoshtam]) {
      if (x in phonemeSet) return phonemeSet.intersect(adesha)
    }
  }
 }

That's it!! The 2 closures basically take care of any purva rupa sandhi rule! Only the additional conditional closures (aci, jashi etc.) must be provided as required.

Finally we verify

assert iko_yan_aci("iti api") == "ityapi"
assert jhalaam_jash_jashi("ap dhi") == "abdhi"

As usual the code can be found at github.com/vasya10/samskritam.

PS: Post this blog, I tried to verify purvaRupaSandhi closure by adding another rule "stoH shcuna shcu:" and it worked just fine. But there is a catch. The shcuna in the rule is not in 7th vibhakti, but is in instrumental case. And there is a reason why Panini uses 3rd vibhakti. The 7th vibhakti indicates the rule to be applied with respect to what follows, while the 3rd vibhakti implies just the contact of two varna-s are sufficient to produce the sandhi. The closure does not take care of that yet.

The functional programming approach of Panini makes me believe that universities should include ashTAdhyAyI as a course in Computer Science, instead of just being a research subject to elite academicians.