From bca339733517b43c2378d208d84a956840eac931 Mon Sep 17 00:00:00 2001 From: Arun Prasad Date: Wed, 29 May 2024 20:36:40 -0700 Subject: [PATCH] [prakriya] Fix two prakriya bugs - Fix GitHub issue #126 (rule choice for `carkarti`, etc.) - Fix GitHub issue #127 (rule order for `sADayati`) --- vidyut-prakriya/src/angasya/abhyasasya.rs | 40 ++++--- vidyut-prakriya/src/ardhadhatuka.rs | 20 +++- vidyut-prakriya/src/ashtadhyayi.rs | 3 + vidyut-prakriya/tests/prakriyas.rs | 134 ++++++++++++---------- vidyut-prakriya/tests/regressions.rs | 2 - 5 files changed, 119 insertions(+), 80 deletions(-) diff --git a/vidyut-prakriya/src/angasya/abhyasasya.rs b/vidyut-prakriya/src/angasya/abhyasasya.rs index ec75a6c..c93aaea 100644 --- a/vidyut-prakriya/src/angasya/abhyasasya.rs +++ b/vidyut-prakriya/src/angasya/abhyasasya.rs @@ -412,6 +412,12 @@ fn try_rules_for_yan(p: &mut Prakriya, i_abhyasa: usize) -> Option<()> { added }; + let add_agama = |rule, p: &mut Prakriya, i_dhatu, agama| -> bool { + p.run(rule, |p| op::insert_agama_before(p, i_dhatu, agama)); + it_samjna::run(p, i_dhatu).ok(); + true + }; + let abhyasa = p.get(i_abhyasa)?; let dhatu = p.get(i_dhatu)?; let is_yan_luk = p.has(i_yan, |t| t.is_empty()); @@ -463,22 +469,26 @@ fn try_rules_for_yan(p: &mut Prakriya, i_abhyasa: usize) -> Option<()> { } else if dhatu.text.contains('f') { // varIvfScyate, ... // (Check for "contains" and not "antya" to allow pfcC, vfSc, ...) - let mut added = false; - if is_yan_luk { - added = optional_add_agama("7.4.91:ruk", p, i_dhatu, "ru~k"); - if !added { - added = optional_add_agama("7.4.91:rik", p, i_dhatu, "rik"); + if is_yan_luk && dhatu.has_antya('f') { + // carkarti, carikarti, carIkarti, ... + _ = optional_add_agama("7.4.92:ruk", p, i_dhatu, "ru~k") + || optional_add_agama("7.4.92:rik", p, i_dhatu, "rik") + || add_agama("7.4.92:rIk", p, i_dhatu, "rIk"); + } else { + let mut added = false; + // narnarti, narinarti + if is_yan_luk { + added = optional_add_agama("7.4.91:ruk", p, i_dhatu, "ru~k") + || optional_add_agama("7.4.91:rik", p, i_dhatu, "rik"); } - } - if !added { - let dhatu = p.get(i_dhatu)?; - if dhatu.has_upadha('f') { - // varIvftyate, varIvftIti, ... - op::insert_agama_at("7.4.90", p, i_dhatu, "rIk"); - } else if dhatu.has_antya('f') { - op::insert_agama_at("7.4.92", p, i_dhatu, "rIk"); - } else { - op::insert_agama_at(Varttika("7.4.90.1"), p, i_dhatu, "rIk"); + if !added { + let dhatu = p.get(i_dhatu)?; + if dhatu.has_upadha('f') { + // varIvftyate, varIvftIti, ... + op::insert_agama_at("7.4.90", p, i_dhatu, "rIk"); + } else { + op::insert_agama_at(Varttika("7.4.90.1"), p, i_dhatu, "rIk"); + } } } } else if abhyasa.has_antya('a') { diff --git a/vidyut-prakriya/src/ardhadhatuka.rs b/vidyut-prakriya/src/ardhadhatuka.rs index 640e313..ba42520 100644 --- a/vidyut-prakriya/src/ardhadhatuka.rs +++ b/vidyut-prakriya/src/ardhadhatuka.rs @@ -294,9 +294,6 @@ fn try_aa_adesha(p: &mut Prakriya) -> Option<()> { } else if dhatu.has_u_in(&["qukrI\\Y", "i\\N", "ji\\"]) && n.has_u("Ric") { // krApayati, aDyApayati, jApayati p.run_at("6.1.48", i, op::antya("A")); - } else if dhatu.has_u("zi\\Du~") && n.has_u("Ric") { - // sADayati, seDayati - p.optional_run_at("6.1.49", i, op::upadha("A")); } // 6.1.50 has a circular dependency: @@ -348,6 +345,23 @@ fn try_aa_adesha(p: &mut Prakriya) -> Option<()> { Some(()) } +// Optional A-adesha for sADayati/seDayati. +// +// Per Neelesh Bodas, this should occur after guna, so for ease of use, I've put this in its own +// function. +pub fn try_aa_adesha_for_sedhayati(p: &mut Prakriya) -> Option<()> { + let i = p.find_first(T::Dhatu)?; + let dhatu = p.get(i)?; + let n = p.pratyaya(i + 1)?; + + if dhatu.has_u("zi\\Du~") && n.has_u("Ric") { + // sADayati, seDayati + p.optional_run_at("6.1.49", i, op::upadha("A")); + } + + Some(()) +} + /// Runs rules that try adding am-Agama to a dhatu when certain pratyayas follow. pub fn try_add_am_agama(p: &mut Prakriya) -> Option<()> { let i = p.find_first(T::Dhatu)?; diff --git a/vidyut-prakriya/src/ashtadhyayi.rs b/vidyut-prakriya/src/ashtadhyayi.rs index 7cb14c4..d07f5de 100644 --- a/vidyut-prakriya/src/ashtadhyayi.rs +++ b/vidyut-prakriya/src/ashtadhyayi.rs @@ -371,6 +371,9 @@ fn run_main_rules(p: &mut Prakriya, lakara: Option, is_ardhadhatuka: boo ac_sandhi::try_sup_sandhi_before_angasya(p); angasya::run_before_dvitva(p); + // After guna + ardhadhatuka::try_aa_adesha_for_sedhayati(p); + p.debug("==== Dvitva (default) ===="); dvitva::run(p); if !used_dvirvacane_aci { diff --git a/vidyut-prakriya/tests/prakriyas.rs b/vidyut-prakriya/tests/prakriyas.rs index b8d169d..a0e13ab 100644 --- a/vidyut-prakriya/tests/prakriyas.rs +++ b/vidyut-prakriya/tests/prakriyas.rs @@ -4,27 +4,31 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Gana::*; +use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::*; use vidyut_prakriya::Rule; -// Sample test for `Bavati`. -#[test] -fn bhavati() { - let bhu = d("BU", Bhvadi); - let args = Tinanta::builder() - .dhatu(bhu) +fn tip_args(dhatu: Dhatu, la: Lakara) -> Tinanta { + Tinanta::builder() + .dhatu(dhatu) .prayoga(Prayoga::Kartari) .purusha(Purusha::Prathama) .vacana(Vacana::Eka) - .lakara(Lakara::Lat) + .lakara(la) .build() - .unwrap(); + .unwrap() +} + +// Sample test for `Bavati`. +#[test] +fn bhavati() { + use Rule::Ashtadhyayi as A; + + let args = tip_args(d("BU", Bhvadi), Lat); let t = Tester::default(); let ps = t.derive_tinantas(&args); let p = ps.iter().find(|p| p.text() == "Bavati").unwrap(); - use Rule::Ashtadhyayi as A; - assert_matches_prakriya( p, &[ @@ -44,21 +48,13 @@ fn bhavati() { /// - We lengthen the dhatu's vowel with 6.4.2. #[test] fn jiyat() { - let jya = d("jyA\\", Kryadi); - let args = Tinanta::builder() - .dhatu(jya) - .prayoga(Prayoga::Kartari) - .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) - .lakara(Lakara::AshirLin) - .build() - .unwrap(); + use Rule::Ashtadhyayi as A; + + let args = tip_args(d("jyA\\", Kryadi), AshirLin); let t = Tester::default(); let ps = t.derive_tinantas(&args); let p = ps.iter().find(|p| p.text() == "jIyAt").unwrap(); - use Rule::Ashtadhyayi as A; - assert_matches_prakriya( p, &[ @@ -78,6 +74,8 @@ fn jiyat() { /// - We correctly apply 6.4.49. #[test] fn paspardhyate() { + use Rule::Ashtadhyayi as A; + let spardh = d("sparDa~\\", Bhvadi); let args = Tinanta::builder() .dhatu(spardh.with_sanadi(&[Sanadi::yaN])) @@ -87,15 +85,11 @@ fn paspardhyate() { .lakara(Lakara::Lat) .build() .unwrap(); + let t = Tester::default(); let ps = t.derive_tinantas(&args); - for p in &ps { - println!("{}", p.text()); - } let p = ps.iter().find(|p| p.text() == "pAsparDyate").unwrap(); - use Rule::Ashtadhyayi as A; - assert_matches_prakriya( p, &[ @@ -111,42 +105,26 @@ fn paspardhyate() { // Test to make sure 8.4.1 applies in akzRoti (i.e when R immediately follows r/z) #[test] fn akshnoti() { - let akz = d("akzU~", Bhvadi); - let args = Tinanta::builder() - .dhatu(akz) - .prayoga(Prayoga::Kartari) - .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) - .lakara(Lakara::Lat) - .build() - .unwrap(); + use Rule::Ashtadhyayi as A; + + let args = tip_args(d("akzU~", Bhvadi), Lat); let t = Tester::default(); let ps = t.derive_tinantas(&args); let p = ps.iter().find(|p| p.text() == "akzRoti").unwrap(); - use Rule::Ashtadhyayi as A; - - assert_matches_prakriya(p, &[(A("8.4.1"), vec!["ak", "Ro", "ti"])]); + assert_matches_prakriya(p, &[(A("8.4.1"), vec!["akz", "Ro", "ti"])]); } // Test to make sure 8.4.2 applies in when r/z and R are intervened by at, ku, etc. #[test] fn krinaati() { - let krii = d("qukrI\\Y", Kryadi); - let args = Tinanta::builder() - .dhatu(krii) - .prayoga(Prayoga::Kartari) - .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) - .lakara(Lakara::Lat) - .build() - .unwrap(); + use Rule::Ashtadhyayi as A; + + let args = tip_args(d("qukrI\\Y", Kryadi), Lat); let t = Tester::default(); let ps = t.derive_tinantas(&args); let p = ps.iter().find(|p| p.text() == "krIRAti").unwrap(); - use Rule::Ashtadhyayi as A; - assert_matches_prakriya(p, &[(A("8.4.2"), vec!["krI", "RA", "ti"])]); } @@ -156,21 +134,13 @@ fn krinaati() { // - We correctly apply 8.4.54 with 7.4.73 #[test] fn babhuva() { - let bhu = d("BU", Bhvadi); - let args = Tinanta::builder() - .dhatu(bhu) - .prayoga(Prayoga::Kartari) - .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) - .lakara(Lakara::Lit) - .build() - .unwrap(); + use Rule::Ashtadhyayi as A; + + let args = tip_args(d("BU", Bhvadi), Lit); let t = Tester::default(); let ps = t.derive_tinantas(&args); let p = ps.iter().find(|p| p.text() == "baBUva").unwrap(); - use Rule::Ashtadhyayi as A; - assert_matches_prakriya( p, &[ @@ -179,3 +149,47 @@ fn babhuva() { ], ); } + +// Fixes https://github.com/ambuda-org/vidyut/issues/126 +// +// This test verifies the following: +// - we use 7.4.92 for carkarti, etc. +#[test] +fn carkarti_etc() { + use Rule::Ashtadhyayi as A; + + let args = tip_args(yan_luk(&d("qukf\\Y", Tanadi)), Lat); + let t = Tester::default(); + let ps = t.derive_tinantas(&args); + + let p = ps.iter().find(|p| p.text() == "carkarti").unwrap(); + assert_matches_prakriya(p, &[(A("7.4.92:ruk"), vec!["ca", "ru~k", "kf", ""])]); + + let p = ps.iter().find(|p| p.text() == "carikarti").unwrap(); + assert_matches_prakriya(p, &[(A("7.4.92:rik"), vec!["ca", "rik", "kf", ""])]); + + let p = ps.iter().find(|p| p.text() == "carIkarti").unwrap(); + assert_matches_prakriya(p, &[(A("7.4.92:rIk"), vec!["ca", "rIk", "kf", ""])]); +} + +// Fixes https://github.com/ambuda-org/vidyut/issues/127 +// +// This test verifies the following: +// - we use 6.1.49 after guna. +#[test] +fn sadhayati() { + use Rule::Ashtadhyayi as A; + + let args = tip_args(nic(&d("zi\\Du~", Divadi)), Lat); + let t = Tester::default(); + let ps = t.derive_tinantas(&args); + + let p = ps.iter().find(|p| p.text() == "sADayati").unwrap(); + assert_matches_prakriya( + p, + &[ + (A("7.3.86"), vec!["seD", "i"]), + (A("6.1.49"), vec!["sAD", "i"]), + ], + ); +} diff --git a/vidyut-prakriya/tests/regressions.rs b/vidyut-prakriya/tests/regressions.rs index 4bad3c8..83dd63d 100644 --- a/vidyut-prakriya/tests/regressions.rs +++ b/vidyut-prakriya/tests/regressions.rs @@ -6,8 +6,6 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; -use vidyut_prakriya::args::*; -use vidyut_prakriya::Rule; #[test] fn ambibat() {