Skip to content

Commit

Permalink
[prakriya] Fix two prakriya bugs
Browse files Browse the repository at this point in the history
- Fix GitHub issue #126 (rule choice for `carkarti`, etc.)
- Fix GitHub issue #127 (rule order for `sADayati`)
  • Loading branch information
akprasad committed May 30, 2024
1 parent 8e01e35 commit bca3397
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 80 deletions.
40 changes: 25 additions & 15 deletions vidyut-prakriya/src/angasya/abhyasasya.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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') {
Expand Down
20 changes: 17 additions & 3 deletions vidyut-prakriya/src/ardhadhatuka.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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)?;
Expand Down
3 changes: 3 additions & 0 deletions vidyut-prakriya/src/ashtadhyayi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,9 @@ fn run_main_rules(p: &mut Prakriya, lakara: Option<Lakara>, 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 {
Expand Down
134 changes: 74 additions & 60 deletions vidyut-prakriya/tests/prakriyas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
&[
Expand All @@ -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,
&[
Expand All @@ -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]))
Expand All @@ -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,
&[
Expand All @@ -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"])]);
}

Expand All @@ -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,
&[
Expand All @@ -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"]),
],
);
}
2 changes: 0 additions & 2 deletions vidyut-prakriya/tests/regressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down

0 comments on commit bca3397

Please sign in to comment.