From b6020397be780f9f99a79c8a1a7a190cb106202b Mon Sep 17 00:00:00 2001 From: Arun Prasad Date: Wed, 11 Dec 2024 22:43:00 -0800 Subject: [PATCH] [prakriya] Add sutra tests and update examples Sutra tests: - Add 1.1.38 - Add 1.4.2 - Add 1.4.12 - Add 1.4.15 - Add 3.2.147 - Add 3.2.148 - Add 3.2.154 - Add 3.2.155 - Add 3.2.156 - Add 3.2.164 - Add 3.2.166 - Add 3.3.92 - Add 3.3.94 varttikas - Add 3.3.96 - Add 3.3.97 - Add 3.3.99 - Add 3.3.106 - Add 3.3.106.v1 - Add 6.4.13 - Add 6.4.22 - Add 6.4.39 - Add 6.4.74 - Add 8.2.62 (partial) - Add 8.2.64 - Enable 3.2.146 - Enable 3.2.168 - Enable 3.3.107 - Enable 7.4.40 Examples: - Add `create_all_krdantas` - Output sanadi text in `create_all_tinantas` - Update examples to properly support all vidyut-lipi schemes API: - change `upadesha()` to `aupadeshika()` - Simplify enum iteration with `.copied()` --- src/bin/create_kosha.rs | 18 +- vidyut-kosha/src/morph.rs | 2 +- vidyut-lipi/src/errors.rs | 2 + vidyut-prakriya/Makefile | 8 +- .../data/dhatupatha-ganasutras.tsv | 36 ++-- vidyut-prakriya/data/varttikas.tsv | 4 +- vidyut-prakriya/examples/bench.rs | 2 +- .../examples/create_all_krdantas.rs | 129 +++++++++++++ .../examples/create_all_tinantas.rs | 63 ++++--- .../examples/create_tinantas_babylon.rs | 2 +- .../scripts/check_rule_coverage.py | 13 +- vidyut-prakriya/src/angasya.rs | 26 +-- vidyut-prakriya/src/angasya/asiddhavat.rs | 12 +- vidyut-prakriya/src/ardhadhatuka.rs | 15 +- vidyut-prakriya/src/args/dhatu.rs | 24 +-- vidyut-prakriya/src/args/krt.rs | 127 ++++++++++--- vidyut-prakriya/src/args/macros.rs | 8 +- vidyut-prakriya/src/args/sup.rs | 12 ++ vidyut-prakriya/src/args/taddhita.rs | 18 +- vidyut-prakriya/src/args/tin.rs | 30 +++ vidyut-prakriya/src/args/unadi.rs | 7 + vidyut-prakriya/src/ashtadhyayi.rs | 11 +- vidyut-prakriya/src/bin/create_dhatus.rs | 2 +- vidyut-prakriya/src/bin/create_krdantas.rs | 4 +- vidyut-prakriya/src/bin/create_test_file.rs | 4 +- vidyut-prakriya/src/bin/create_tinantas.rs | 18 +- vidyut-prakriya/src/bin/test_results.rs | 8 +- vidyut-prakriya/src/caching.rs | 37 ++++ vidyut-prakriya/src/core/term.rs | 1 + vidyut-prakriya/src/dhatu_karya.rs | 4 +- vidyut-prakriya/src/dhatupatha.rs | 6 +- vidyut-prakriya/src/ganapatha.rs | 2 + vidyut-prakriya/src/krt/basic.rs | 171 +++++++++++++++--- vidyut-prakriya/src/krt/utils.rs | 12 +- vidyut-prakriya/src/vyakarana.rs | 66 ++++++- vidyut-prakriya/test_utils/src/lib.rs | 2 +- vidyut-prakriya/tests/integration/api.rs | 8 +- .../tests/integration/basic_tinantas.rs | 2 +- .../tests/integration/kashika_1_1.rs | 31 +++- .../tests/integration/kashika_1_4.rs | 54 ++++++ .../tests/integration/kashika_2_4.rs | 2 +- .../tests/integration/kashika_3_2.rs | 97 +++++++++- .../tests/integration/kashika_3_3.rs | 66 ++++++- .../tests/integration/kashika_6_1.rs | 14 +- .../tests/integration/kashika_6_4.rs | 151 ++++++++++++---- .../tests/integration/kashika_7_4.rs | 17 +- .../tests/integration/kashika_8_2.rs | 56 ++++++ .../tests/integration/sanadi_tinantas.rs | 2 +- 48 files changed, 1148 insertions(+), 258 deletions(-) create mode 100644 vidyut-prakriya/examples/create_all_krdantas.rs diff --git a/src/bin/create_kosha.rs b/src/bin/create_kosha.rs index efb32c3..3bb476f 100644 --- a/src/bin/create_kosha.rs +++ b/src/bin/create_kosha.rs @@ -86,7 +86,7 @@ fn linga_vibhakti_vacana_options() -> Vec<(vp::Linga, vp::Vibhakti, vp::Vacana)> for linga in vp::Linga::iter() { for vibhakti in vp::Vibhakti::iter() { for vacana in vp::Vacana::iter() { - ret.push((*linga, *vibhakti, *vacana)) + ret.push((linga, vibhakti, vacana)) } } } @@ -117,18 +117,18 @@ fn tinanta_options() -> Vec<( let mut ret = Vec::new(); for prayoga in vp::Prayoga::iter() { for pada in vp::DhatuPada::iter() { - if *prayoga == vp::Prayoga::Bhave { + if prayoga == vp::Prayoga::Bhave { // Duplicates karmani -- skip continue; } for lakara in vp::Lakara::iter() { - if *lakara == vp::Lakara::Let { + if lakara == vp::Lakara::Let { // Experimental -- skip continue; } for purusha in vp::Purusha::iter() { for vacana in vp::Vacana::iter() { - ret.push((*prayoga, *pada, *lakara, *purusha, *vacana)); + ret.push((prayoga, pada, lakara, purusha, vacana)); } } } @@ -478,8 +478,8 @@ fn create_sarvanamas(padas: &mut PadaVec) { let prati = vp::Pratipadika::basic(stem); let lingas = vec![Linga::Pum, Linga::Stri, Linga::Napumsaka]; - for (linga, vibhakti, vacana) in &linga_vibhakti_vacana { - let args = vp::Subanta::new(prati.clone(), *linga, *vibhakti, *vacana); + for (linga, vibhakti, vacana) in linga_vibhakti_vacana.iter().copied() { + let args = vp::Subanta::new(prati.clone(), linga, vibhakti, vacana); let prakriyas = v.derive_subantas(&args); for p in prakriyas { let morph = Pada::Subanta(Subanta { @@ -487,9 +487,9 @@ fn create_sarvanamas(padas: &mut PadaVec) { text: stem.to_string(), lingas: lingas.clone(), }, - linga: Some(Linga::from(*linga)), - vibhakti: Some(Vibhakti::from(*vibhakti)), - vacana: Some(Vacana::from(*vacana)), + linga: Some(Linga::from(linga)), + vibhakti: Some(Vibhakti::from(vibhakti)), + vacana: Some(Vacana::from(vacana)), is_purvapada: false, }); let text = p.text(); diff --git a/vidyut-kosha/src/morph.rs b/vidyut-kosha/src/morph.rs index dc63554..ee54574 100644 --- a/vidyut-kosha/src/morph.rs +++ b/vidyut-kosha/src/morph.rs @@ -372,7 +372,7 @@ impl From for Dhatu { Dhatu { prefixes: vp.prefixes().to_vec(), sanadi: vp.sanadi().to_vec(), - text: match vp.upadesha() { + text: match vp.aupadeshika() { Some(s) => s.to_string(), None => String::new(), }, diff --git a/vidyut-lipi/src/errors.rs b/vidyut-lipi/src/errors.rs index 6b84317..9b7d846 100644 --- a/vidyut-lipi/src/errors.rs +++ b/vidyut-lipi/src/errors.rs @@ -12,6 +12,8 @@ pub enum LipiError { ParseError, } +impl std::error::Error for LipiError {} + impl fmt::Display for LipiError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use LipiError::*; diff --git a/vidyut-prakriya/Makefile b/vidyut-prakriya/Makefile index 9f4f3de..dba1ba8 100644 --- a/vidyut-prakriya/Makefile +++ b/vidyut-prakriya/Makefile @@ -117,15 +117,15 @@ test_krdantas: ../target/release/test_results \ --data-type krdanta \ --test-cases test-files/krdantas-basic.csv \ - --hash "2633afc74d312baeaba290c517e2427571bf9a5d2fb6b65b57b97fe3274ed9f0" + --hash "769a763ab754ee5accf0edefa09b38b1084a069c6bf4e183c3f7039c295511fe" ../target/release/test_results \ --data-type krdanta \ --test-cases test-files/krdantas-nic.csv \ - --hash "b4ed0d24a5436a3879911ecc1ed420db09128056dea80d298cb12412ff79e04b" + --hash "7be488ee87ad8402487d39cc6e3c0fe8be7a9480e88b02a5eec5e05c4a790d0c" ../target/release/test_results \ --data-type krdanta \ --test-cases test-files/krdantas-san.csv \ - --hash "2b1cf48f5b3ad1073c83c9970acf778135bb3375d18b5316a826ece5f2105fca" + --hash "a2de7869bf2c6b534c7075ac37803c232f1c24f6fcc58713d85c4f89bbe79d55" ../target/release/test_results \ --data-type krdanta \ --test-cases test-files/krdantas-yan.csv \ @@ -133,7 +133,7 @@ test_krdantas: ../target/release/test_results \ --data-type krdanta \ --test-cases test-files/krdantas-yan-luk.csv \ - --hash "ed81f38274b4ac93370559b4b7881e80c4403e96770c09fcba0da41f1f39978d" + --hash "6bdaea4c974026fa7bfab4e874b1c3f0368d6a2f35bbf94ad626ab573bf8282d" test_dhatus: cargo build --release --bin test_results diff --git a/vidyut-prakriya/data/dhatupatha-ganasutras.tsv b/vidyut-prakriya/data/dhatupatha-ganasutras.tsv index bb5c46d..b7e76e1 100644 --- a/vidyut-prakriya/data/dhatupatha-ganasutras.tsv +++ b/vidyut-prakriya/data/dhatupatha-ganasutras.tsv @@ -1,18 +1,18 @@ -01.0933_GawAdayo mitaH -01.0934_janIjFzkanasuraYjo'mantASca -01.0935_jvalahvalahmalanamAmanupasargAdvA -01.0936_glAsnAvanuvamAM ca -01.0937_na kamyamicamAm -01.0938_Samo darSane -01.0939_yamo'parivezaRe -01.0940_sKadiravapariByAM ca -02.0076_carkarItaM ca -04.0162_svAdaya oditaH -10.0493_jYapAdayo mitaH -10.0494_nAnye mito'hetO -10.0495_kusma nAmno vA -10.0496_A kusmAdAtmanepadinaH -10.0497_A garvAdAtmanepadinaH -10.0498_A DfzAdvA -10.0499_A svadaH sakarmakAt -10.0500_hantyarTASca +01.0933 GawAdayo mitaH +01.0934 janIjFzkanasuraYjo'mantASca +01.0935 jvalahvalahmalanamAmanupasargAdvA +01.0936 glAsnAvanuvamAM ca +01.0937 na kamyamicamAm +01.0938 Samo darSane +01.0939 yamo'parivezaRe +01.0940 sKadiravapariByAM ca +02.0076 carkarItaM ca +04.0162 svAdaya oditaH +10.0493 jYapAdayo mitaH +10.0494 nAnye mito'hetO +10.0495 kusma nAmno vA +10.0496 A kusmAdAtmanepadinaH +10.0497 A garvAdAtmanepadinaH +10.0498 A DfzAdvA +10.0499 A svadaH sakarmakAt +10.0500 hantyarTASca diff --git a/vidyut-prakriya/data/varttikas.tsv b/vidyut-prakriya/data/varttikas.tsv index b9ddc21..da7659d 100644 --- a/vidyut-prakriya/data/varttikas.tsv +++ b/vidyut-prakriya/data/varttikas.tsv @@ -11,7 +11,8 @@ 2.1.37.1 BayaBItaBItiBIBiriti vaktavyam 2.4.45.1 iRvadika iti vaktavyam 2.4.54.1 varjane pratizeDo vaktavyaH -2.4.56.2 valAdAvArDaDAtuke vezyate +2.4.56.1 GaYapoH pratizeDe kyapa upasaNKyAnam +2.4.56.2 valAdAvArDaDAtuke vikalpa izyate 3.1.11.1 ojaso'psaraso nityamitarezAM viBAzayA 3.1.14.1 satrakazwakakzakfcCragahaneByaH kaRvacikIrzAyAm iti vaktavyam 3.1.15.2 tapasaH parasmEpadaM ca @@ -37,6 +38,7 @@ 3.2.60.1 samAnAnyayoSceti vaktavyam 3.2.174.1 krukannapi vaktavyaH 3.2.178.1 kvibvacipracCAyatastukawaprujuSrIRAM dIrGo'saMprasAraRaM ca +3.3.106.1 SradantarorupasargavadvfttiH 3.3.125.1 KanerqaqarekekavakA vAcyAH 4.1.6.1 DAtorugitaH pratizeDaH 4.1.68.1 SvaSurasyokArAkAralopaSca diff --git a/vidyut-prakriya/examples/bench.rs b/vidyut-prakriya/examples/bench.rs index 20e2179..58ed6a2 100644 --- a/vidyut-prakriya/examples/bench.rs +++ b/vidyut-prakriya/examples/bench.rs @@ -70,7 +70,7 @@ fn run(dhatupatha: Dhatupatha) -> Result<(), Box> { } } } - println!("{:?}", dhatu.upadesha()); + println!("{:?}", dhatu.aupadeshika()); } println!("Generated {} forms.", total); diff --git a/vidyut-prakriya/examples/create_all_krdantas.rs b/vidyut-prakriya/examples/create_all_krdantas.rs new file mode 100644 index 0000000..8ef4cb1 --- /dev/null +++ b/vidyut-prakriya/examples/create_all_krdantas.rs @@ -0,0 +1,129 @@ +//! Creates a very large list of krdantas. This list includes all combinations of: +//! +//! - Around 2000 dhatus from our dhatupatha +//! - 5 sanAdi combinations (none, nic, san, yan, yan-luk) +//! - Around 120 krt-pratyayas from the `Krt` enum, including variants like sya-Satf and sya-SAnac. +//! +//! These combinations produce around 2000 x 5 x 120 = 1.2 million krdantas. +//! +//! Usage: +//! +//! cargo run --release --example create_all_krdantas -- --output-scheme Devanagari +use clap::Parser; +use serde::Serialize; +use std::error::Error; +use std::io; +use vidyut_lipi::{Lipika, Scheme}; +use vidyut_prakriya::args::{BaseKrt, Krdanta, Sanadi}; +use vidyut_prakriya::{Dhatupatha, Vyakarana}; + +/// Command line arguments. +#[derive(Parser)] +#[command(author, version, about)] +struct Args { + /// If set, the output scheme to use. + /// + /// Any scheme name accepted by `vidyut-prakriya` is valid. Examples: `Devanagari`, `Iso15919`, + /// `Slp1`. + /// + /// (Default: `Slp1`) + #[arg(long)] + output_scheme: Option, +} + +#[derive(Debug, Serialize)] +struct Row<'a> { + krdantas: String, + dhatu: &'a str, + gana: &'static str, + number: u16, + sanadi: String, + krt: &'static str, +} + +fn create_output_string( + lipika: &mut Lipika, + mut items: Vec, + output_scheme: Scheme, +) -> String { + items.sort(); + if output_scheme != Scheme::Slp1 { + for s in items.iter_mut() { + *s = lipika.transliterate(&s, Scheme::Slp1, output_scheme); + } + } + items.join("|") +} + +fn run(dhatupatha: Dhatupatha, args: Args) -> Result<(), Box> { + let sanadi_choices = vec![ + vec![], + vec![Sanadi::san], + vec![Sanadi::Ric], + vec![Sanadi::yaN], + vec![Sanadi::yaNluk], + ]; + + let v = Vyakarana::builder().log_steps(false).build(); + let mut lipika = Lipika::new(); + let mut wtr = csv::Writer::from_writer(io::stdout()); + + let output_scheme: Scheme = match args.output_scheme { + Some(s) => s.parse()?, + None => Scheme::Slp1, + }; + + for sanadis in &sanadi_choices { + for entry in &dhatupatha { + let dhatu = entry.dhatu().clone().with_sanadi(&sanadis); + for krt in BaseKrt::iter() { + let krdanta = Krdanta::builder().dhatu(dhatu.clone()).krt(krt).build()?; + + let prakriyas = v.derive_krdantas(&krdanta); + if prakriyas.is_empty() { + continue; + } + + let dhatu_text = &dhatu.aupadeshika().expect("ok"); + let krdantas: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); + let krdantas = create_output_string(&mut lipika, krdantas, output_scheme); + let sanadi_text: Vec<_> = sanadis.iter().map(|x| x.as_str()).collect(); + let sanadi_text = sanadi_text.join("-"); + + let row = Row { + krdantas, + dhatu: dhatu_text, + gana: dhatu.gana().expect("ok").as_str(), + number: entry.number(), + sanadi: sanadi_text, + krt: krt.as_str(), + }; + + wtr.serialize(row)?; + } + } + } + + wtr.flush()?; + Ok(()) +} + +fn main() { + let args = Args::parse(); + + let dhatus = match Dhatupatha::from_path("data/dhatupatha.tsv") { + Ok(res) => res, + Err(err) => { + println!("{}", err); + std::process::exit(1); + } + }; + + match run(dhatus, args) { + Ok(()) => (), + Err(err) => { + eprintln!("{}", err); + std::process::exit(1); + } + } +} diff --git a/vidyut-prakriya/examples/create_all_tinantas.rs b/vidyut-prakriya/examples/create_all_tinantas.rs index c793980..7153562 100644 --- a/vidyut-prakriya/examples/create_all_tinantas.rs +++ b/vidyut-prakriya/examples/create_all_tinantas.rs @@ -8,6 +8,9 @@ //! - 3 vacanas //! //! These combinations produce around 2000 x 2 x 5 x 10 x 3 x 3 = 1.8 million tinantas. +//! Usage: +//! +//! cargo run --release --example create_all_tinantas -- --output-scheme Devanagari use clap::Parser; use serde::Serialize; use std::error::Error; @@ -20,9 +23,12 @@ use vidyut_prakriya::{Dhatupatha, Vyakarana}; #[derive(Parser)] #[command(author, version, about)] struct Args { - /// If set, the output scheme to use. Supported options are: slp1, devanagari, iast. + /// If set, the output scheme to use. + /// + /// Any scheme name accepted by `vidyut-prakriya` is valid. Examples: `Devanagari`, `Iso15919`, + /// `Slp1`. /// - /// (Default: slp1) + /// (Default: `Slp1`) #[arg(long)] output_scheme: Option, } @@ -33,21 +39,25 @@ struct Row<'a> { dhatu: &'a str, gana: &'static str, number: u16, + sanadi: String, prayoga: &'static str, lakara: &'static str, purusha: &'static str, vacana: &'static str, } -fn create_pada_string(mut padas: Vec, output_scheme: Scheme) -> String { - padas.sort(); - let mut lipika = Lipika::new(); +fn create_output_string( + lipika: &mut Lipika, + mut items: Vec, + output_scheme: Scheme, +) -> String { + items.sort(); if output_scheme != Scheme::Slp1 { - for s in padas.iter_mut() { + for s in items.iter_mut() { *s = lipika.transliterate(&s, Scheme::Slp1, output_scheme); } } - padas.join("|") + items.join("|") } fn run(dhatupatha: Dhatupatha, args: Args) -> Result<(), Box> { @@ -59,33 +69,31 @@ fn run(dhatupatha: Dhatupatha, args: Args) -> Result<(), Box> { vec![Sanadi::yaNluk], ]; - let mut wtr = csv::Writer::from_writer(io::stdout()); let v = Vyakarana::builder().log_steps(false).build(); + let mut lipika = Lipika::new(); + let mut wtr = csv::Writer::from_writer(io::stdout()); - let output_scheme = match args.output_scheme { - Some(x) => match x.as_str() { - "devanagari" => Scheme::Devanagari, - "iast" => Scheme::Iast, - "slp1" => Scheme::Slp1, - // We should handle this with an error, but it's easier to default to SLP1. - _ => Scheme::Slp1, - }, + let output_scheme: Scheme = match args.output_scheme { + Some(s) => s.parse()?, None => Scheme::Slp1, }; - for entry in dhatupatha { - let dhatu = entry.dhatu(); - for sanadis in &sanadi_choices { - for prayoga in &[Prayoga::Kartari, Prayoga::Karmani] { + for sanadis in &sanadi_choices { + for entry in &dhatupatha { + let dhatu = entry.dhatu().clone().with_sanadi(&sanadis); + let sanadi_text: Vec<_> = sanadis.iter().map(|x| x.as_str()).collect(); + let sanadi_text = sanadi_text.join("-"); + + for prayoga in [Prayoga::Kartari, Prayoga::Karmani] { for lakara in Lakara::iter() { for purusha in Purusha::iter() { for vacana in Vacana::iter() { let tinanta = Tinanta::builder() - .dhatu(dhatu.clone().with_sanadi(&sanadis)) - .prayoga(*prayoga) - .purusha(*purusha) - .vacana(*vacana) - .lakara(*lakara) + .dhatu(dhatu.clone()) + .prayoga(prayoga) + .purusha(purusha) + .vacana(vacana) + .lakara(lakara) .build()?; let prakriyas = v.derive_tinantas(&tinanta); @@ -93,15 +101,16 @@ fn run(dhatupatha: Dhatupatha, args: Args) -> Result<(), Box> { continue; } - let dhatu_text = &dhatu.upadesha().expect("ok"); + let dhatu_text = &dhatu.aupadeshika().expect("ok"); let padas: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); - let padas = create_pada_string(padas, output_scheme); + let padas = create_output_string(&mut lipika, padas, output_scheme); let row = Row { padas, dhatu: dhatu_text, gana: dhatu.gana().expect("ok").as_str(), number: entry.number(), + sanadi: sanadi_text.clone(), lakara: lakara.as_str(), purusha: purusha.as_str(), vacana: vacana.as_str(), diff --git a/vidyut-prakriya/examples/create_tinantas_babylon.rs b/vidyut-prakriya/examples/create_tinantas_babylon.rs index 9719b2e..a6e7b51 100644 --- a/vidyut-prakriya/examples/create_tinantas_babylon.rs +++ b/vidyut-prakriya/examples/create_tinantas_babylon.rs @@ -109,7 +109,7 @@ fn create_entry( // Dhatupatha sutra html_row += "("; - html_row += &replace_svaras(&mula.upadesha()); + html_row += &replace_svaras(&mula.aupadeshika()); html_row += " "; html_row += dhatu_entry.artha(); html_row += " "; diff --git a/vidyut-prakriya/scripts/check_rule_coverage.py b/vidyut-prakriya/scripts/check_rule_coverage.py index e8d7cd6..082a551 100755 --- a/vidyut-prakriya/scripts/check_rule_coverage.py +++ b/vidyut-prakriya/scripts/check_rule_coverage.py @@ -42,15 +42,20 @@ def print_legend(): for match in re.findall(r"(\d+_\d+_\d+)", line): tested_rules.add(match.replace('_', '.')) +had_ok = False for rule in all_rules: - status = None if rule in tested_rules: - status = RULE_OK + if had_ok: + continue + print(f"{RULE_OK}\t\t[...]") + had_ok = True elif rule in implemented_rules: - status = RULE_UNTESTED + print(f"{RULE_UNTESTED}\t\t{rule}") + had_ok = False else: status = RULE_MISSING - print(f"{status}\t\t{rule}") + print(f"{RULE_MISSING}\t\t{rule}") + had_ok = False print_legend() diff --git a/vidyut-prakriya/src/angasya.rs b/vidyut-prakriya/src/angasya.rs index 098f758..a131448 100644 --- a/vidyut-prakriya/src/angasya.rs +++ b/vidyut-prakriya/src/angasya.rs @@ -175,7 +175,8 @@ fn try_pratyaya_adesha_at_index(p: &mut Prakriya, i_anga: usize) -> Option<()> { } /// Runs rules that change one or more letters in the anga to a 't'. -fn try_anga_changes_to_t(p: &mut Prakriya, i_anga: usize) -> Option<()> { +fn try_anga_changes_before_t(p: &mut Prakriya, i_anga: usize) -> Option<()> { + p.debug("anga before t"); let anga = p.get(i_anga)?; if anga.is_dhatu() { @@ -187,13 +188,12 @@ fn try_anga_changes_to_t(p: &mut Prakriya, i_anga: usize) -> Option<()> { let anga = p.get(i_anga)?; let next = p.get_if(i_anga + 1, |t| t.has_adi('t') && t.has_tag(T::kit))?; - if anga.has_text_in(&["dyut", "mA", "sA", "sTA"]) { - let code = "7.4.40"; - if anga.has_text("dyut") { - p.run_at(code, i_anga, op::upadha("i")); - } else { - p.run_at(code, i_anga, op::antya("i")); - } + if anga.has_u_in(&["do\\", "zo\\", "mA\\", "zWA\\"]) + && anga.has_antya('A') + && !anga.has_tag(T::Complete) + { + // nirdita, avasita, ... + p.run_at("7.4.40", i_anga, op::antya("i")); } else if anga.has_u_in(&["So\\", "Co\\"]) { p.optional_run_at("7.4.41", i_anga, op::antya("i")); } else if anga.is_u(Au::quDAY) { @@ -540,7 +540,7 @@ pub fn run_before_stritva(p: &mut Prakriya) -> Option<()> { Some(()) } -pub fn run_before_dvitva(p: &mut Prakriya, is_lun: bool) -> Option<()> { +pub fn run_before_dvitva(p: &mut Prakriya, is_lun: bool, skip_at_agama: bool) -> Option<()> { // Mark relevant terms as `anga`. let mut added = false; for t in p.terms_mut() { @@ -956,7 +956,10 @@ pub fn run_before_dvitva(p: &mut Prakriya, is_lun: bool) -> Option<()> { return None; } - if p.has(i_start, |t| t.has_adi(AC)) { + if skip_at_agama { + // kArzIt, hArzIt, karot, harat, ... + p.step("6.4.74"); + } else if p.has(i_start, |t| t.has_adi(AC)) { op::insert_before("6.4.72", p, i_start, A::Aw); } else { op::insert_before("6.4.71", p, i_start, A::aw); @@ -1386,6 +1389,8 @@ pub fn run_before_dvitva(p: &mut Prakriya, is_lun: bool) -> Option<()> { option_block_iter(p, try_dhatu_rt_adesha); for i in 0..p.len() { + // Must run before asiddhavat for sTA + kta -> sTita + try_anga_changes_before_t(p, i); asiddhavat::run_after_guna(p, i); } @@ -1503,7 +1508,6 @@ pub fn run_after_dvitva(p: &mut Prakriya) -> Option<()> { try_tas_asti_lopa(p, i); try_didhi_vevi_lopa(p, i); - try_anga_changes_to_t(p, i); } for i in 0..p.terms().len() { diff --git a/vidyut-prakriya/src/angasya/asiddhavat.rs b/vidyut-prakriya/src/angasya/asiddhavat.rs index 525f79b..e81b803 100644 --- a/vidyut-prakriya/src/angasya/asiddhavat.rs +++ b/vidyut-prakriya/src/angasya/asiddhavat.rs @@ -970,8 +970,14 @@ pub fn try_bhasya_for_index(p: &mut Prakriya, i: usize) -> Option<()> { } } else if bha.has_text("pAd") { p.run_at("6.4.130", i, op::text("pad")); - } else if bha.has_u("kvasu~") { - p.run_at("6.4.131", i, op::text("us")); + } else if bha.is(K::kvasu) || bha.has_u("vasu~") { + p.run("6.4.131", |p| { + p.set(i, op::text("us")); + // valAdi is lost, so iw-Agama is also lost. + if i > 0 && p.has(i - 1, |t| t.is(A::iw)) { + p.terms_mut().remove(i - 1); + } + }); } else if i > 0 && p.has(i - 1, |t| t.has_text("vAh")) { p.run_at("6.4.132", i - 1, |t| { t.set_text("Uh"); @@ -1176,7 +1182,7 @@ pub fn run_after_guna(p: &mut Prakriya, i: usize) -> Option<()> { // pradAya p.step("6.4.69"); } - } else { + } else if !dhatu.has_tag(T::Complete) { // deya p.run_at("6.4.66", i, op::antya("I")); } diff --git a/vidyut-prakriya/src/ardhadhatuka.rs b/vidyut-prakriya/src/ardhadhatuka.rs index b1085a2..64cdb84 100644 --- a/vidyut-prakriya/src/ardhadhatuka.rs +++ b/vidyut-prakriya/src/ardhadhatuka.rs @@ -371,9 +371,14 @@ pub fn run_before_vikarana( // anudAtta to prevent iT op::adesha("2.4.53", p, i, "va\\ci~"); } else if dhatu.has_u("aja~") && !n.last().is_any_krt(&[K::GaY, K::ap]) { - let mut run = true; - if n.last().is(K::lyuw) { - run = !p.optional_run("2.4.57", |_| {}); + let mut blocked = false; + + if n.last().is(K::kyap) { + // samajyA + p.step(Varttika("2.4.56.1")); + blocked = true; + } else if n.last().is(K::lyuw) { + blocked = p.optional_run("2.4.57", |_| {}); } // vArttika: valAdAvArdhadhAtuke veSyate @@ -398,9 +403,9 @@ pub fn run_before_vikarana( // HACK: ignore Rvul, since it will be replaced with -aka. // HACK: ignore unadi, since here it seems mandatory. if n.has_adi(VAL) && will_have_valadi && !n.is_unadi() && !n.has_text("vu~") { - run = !p.optionally(Varttika("2.4.56.2"), |rule, p| p.step(rule)); + blocked = p.optionally(Varttika("2.4.56.2"), |rule, p| p.step(rule)); } - if run { + if !blocked { // aniT-tva comes from anudAtta in upadesha. op::adesha("2.4.56", p, i, "vI\\"); } diff --git a/vidyut-prakriya/src/args/dhatu.rs b/vidyut-prakriya/src/args/dhatu.rs index 6878b88..1997135 100644 --- a/vidyut-prakriya/src/args/dhatu.rs +++ b/vidyut-prakriya/src/args/dhatu.rs @@ -183,7 +183,7 @@ enum_boilerplate!(Sanadi, { #[derive(Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Muladhatu { - upadesha: String, + aupadeshika: String, gana: Gana, antargana: Option, sanadi: Vec, @@ -194,7 +194,7 @@ impl Muladhatu { /// Creates a new *mūla-dhātu*. pub fn new(upadesha: &str, gana: Gana) -> Self { Self { - upadesha: String::from(upadesha), + aupadeshika: String::from(upadesha), gana, antargana: None, sanadi: Vec::new(), @@ -204,8 +204,8 @@ impl Muladhatu { /// The dhatu as stated in its *aupadeśika* form. `upadesha` should be an SLP1 string that /// includes any necessary svaras. For examples, see the `dhatu` column in the /// `data/dhatupatha.tsv` file included in this crate. - pub fn upadesha(&self) -> &String { - &self.upadesha + pub fn aupadeshika(&self) -> &String { + &self.aupadeshika } /// The dhatu's *gaṇa*. @@ -480,10 +480,10 @@ impl Dhatu { } } - /// The upadesha to use with this dhatu, if defined. - pub fn upadesha(&self) -> Option<&String> { + /// The aupadeshika text for this dhatu, if defined. + pub fn aupadeshika(&self) -> Option<&String> { match self { - Self::Mula(m) => Some(m.upadesha()), + Self::Mula(m) => Some(m.aupadeshika()), _ => None, } } @@ -541,7 +541,7 @@ impl Dhatu { #[derive(Clone, Default, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct DhatuBuilder { - upadesha: Option, + aupadeshika: Option, gana: Option, antargana: Option, sanadi: Vec, @@ -553,8 +553,8 @@ impl DhatuBuilder { /// /// - For mula dhatus, this should be the dhatu as listed in the Dhatupatha, including svaras. /// - For namadhatus, this should be the text of the pratipadika. - pub fn upadesha(mut self, text: &str) -> Self { - self.upadesha = Some(String::from(text)); + pub fn aupadeshika(mut self, text: &str) -> Self { + self.aupadeshika = Some(String::from(text)); self } @@ -588,9 +588,9 @@ impl DhatuBuilder { /// Converts the arguments in this builder into a `Dhatu` struct. pub fn build(self) -> Result { Ok(Dhatu::Mula(Muladhatu { - upadesha: match self.upadesha { + aupadeshika: match self.aupadeshika { Some(x) => x, - _ => return Err(Error::missing_required_field("upadesha")), + _ => return Err(Error::missing_required_field("aupadeshika")), }, gana: match self.gana { Some(x) => x, diff --git a/vidyut-prakriya/src/args/krt.rs b/vidyut-prakriya/src/args/krt.rs index b951e44..66a8be3 100644 --- a/vidyut-prakriya/src/args/krt.rs +++ b/vidyut-prakriya/src/args/krt.rs @@ -28,6 +28,10 @@ pub enum BaseKrt { ac, /// -a aR, + /// -aDyE + aDyE, + /// -aDyE + aDyEn, /// -at (jarat) atfn, /// -aTu (vepaTu). Allowed only for dhatus that are `qvit`. @@ -38,6 +42,10 @@ pub enum BaseKrt { anIyar, /// -a ap, + /// -ase + ase, + /// -ase + asen, /// -Alu Aluc, /// -Aru @@ -64,12 +72,20 @@ pub enum BaseKrt { ka, /// -a kaY, + /// -aDyE + kaDyE, + /// -aDyE + kaDyEn, /// -am kamul, /// -as (visfpaH, ...) kasun, /// -a kap, + /// -ase + kase, + /// -ase + kasen, /// -Ana (cakrARa, ...) kAnac, /// -i (udaDi, ...) @@ -168,6 +184,12 @@ pub enum BaseKrt { Rvuc, /// -aka Rvul, + /// -tave + taveN, + /// -tave + taven, + /// -tavE + tavE, /// -tavya (gantavya, bhavitavya, ...) tavya, /// -tavya @@ -178,7 +200,7 @@ pub enum BaseKrt { tfc, /// -tf tfn, - /// -os + /// -tos (udetoH) tosun, /// -Taka (gATaka) Takan, @@ -192,14 +214,6 @@ pub enum BaseKrt { ni, /// -man manin, - /// -a - Sa, - /// -at (gacCat, Bavat, ...) - Satf, - /// -Ana (laBamAna, sevamAna, ...) - SAnac, - /// -Ana - SAnan, /// -ya yat, /// -ana @@ -230,6 +244,22 @@ pub enum BaseKrt { zwran, /// -aka zvun, + /// -a + Sa, + /// -at (gacCat, Bavat, ...) + Satf, + /// -aDyE + SaDyE, + /// -aDyE + SaDyEn, + /// -Ana (laBamAna, sevamAna, ...) + SAnac, + /// -Ana + SAnan, + /// -se + se, + /// -se + sen, } enum_boilerplate!(BaseKrt, { @@ -239,9 +269,13 @@ enum_boilerplate!(BaseKrt, { aR => "aR", atfn => "atf~n", aTuc => "aTuc", + aDyE => "aDyE", + aDyEn => "aDyEn", ani => "ani", anIyar => "anIyar", ap => "ap", + ase => "ase", + asen => "asen", Aluc => "Aluc", Aru => "Aru", ika => "ika", @@ -256,9 +290,13 @@ enum_boilerplate!(BaseKrt, { cAnaS => "cAnaS", ka => "ka", kaY => "kaY", + kaDyE => "kaDyE", + kaDyEn => "kaDyEn", kamul => "kamu~l", kasun => "kasu~n", kap => "kap", + kase => "kase", + kasen => "kasen", kAnac => "kAnac", ki => "ki", kin => "kin", @@ -307,6 +345,9 @@ enum_boilerplate!(BaseKrt, { Rvi => "Rvi~", Rvuc => "Rvu~c", Rvul => "Rvu~l", + taveN => "taveN", + taven => "taven", + tavE => "tavE", tavya => "tavya", tavyat => "tavyat", tumun => "tumu~n", @@ -319,10 +360,6 @@ enum_boilerplate!(BaseKrt, { nan => "nan", ni => "ni", manin => "mani~n", - Sa => "Sa", - Satf => "Satf~", - SAnac => "SAnac", - SAnan => "SAnan", yat => "yat", yuc => "yu~c", ra => "ra", @@ -335,11 +372,26 @@ enum_boilerplate!(BaseKrt, { viw => "vi~w", vuY => "vu~Y", vun => "vu~n", + Sa => "Sa", + Satf => "Satf~", + SaDyE => "SaDyE", + SaDyEn => "SaDyEn", + SAnac => "SAnac", + SAnan => "SAnan", zAkan => "zAkan", zwran => "zwran", zvun => "zvu~n", + se => "se", + sen => "sen", }); +impl BaseKrt { + /// Returns the *aupadeśika* form of this *pratyaya*. + pub fn aupadeshika(&self) -> &'static str { + self.as_str() + } +} + /// Models a *kṛt pratyaya*. #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -376,22 +428,55 @@ impl Krt { } } + /// Returns whether this krt pratyaya creates an *avyaya*. + /// + /// This is a convenience function for programs that generate Sanskrit words. If a *krt + /// pratyaya* creates *avyaya*s, then we don't need to try creating subantas for various + /// combinations of vibhakti and vacana. + pub fn is_avyaya(&self) -> bool { + use BaseKrt::*; + match self { + Krt::Base(k) => !matches!( + k, + tumun + | Ramul + | se + | sen + | ase + | asen + | kase + | kasen + | aDyE + | aDyEn + | kaDyE + | kaDyEn + | SaDyE + | SaDyEn + | tavE + | taveN + | taven + | ktvA + | tosun + | kasun + ), + Krt::Unadi(_) => true, + } + } + /// Returns a simple human-readable string that represents this enum's value. /// /// This mapping is not reversible. This is because some pratyayas are in both `Base` and /// `Unadi`. pub fn as_str(&self) -> &'static str { - match self { - Krt::Base(b) => b.as_str(), - Krt::Unadi(u) => u.as_str(), - } + self.aupadeshika() } -} -impl BaseKrt { - /// Returns the *aupadeśika* form of this *pratyaya*. + /// Returns the *aupadesika* form of this pratyaya. pub fn aupadeshika(&self) -> &'static str { - self.as_str() + match self { + Krt::Base(b) => b.aupadeshika(), + Krt::Unadi(u) => u.aupadeshika(), + } } } diff --git a/vidyut-prakriya/src/args/macros.rs b/vidyut-prakriya/src/args/macros.rs index 047846d..d0555be 100644 --- a/vidyut-prakriya/src/args/macros.rs +++ b/vidyut-prakriya/src/args/macros.rs @@ -14,14 +14,14 @@ macro_rules! enum_boilerplate { /// Iterates over all values of this enum in order. #[allow(dead_code)] - pub fn iter() -> impl Iterator { - /// In Rust, `const` items are created at compile time. + pub fn iter() -> impl Iterator { + // In Rust, `const` items are created at compile time. const ITEMS: &[$Enum] = &[ $( $Enum::$variant, )* ]; - ITEMS.iter() + ITEMS.iter().copied() } } @@ -32,7 +32,7 @@ macro_rules! enum_boilerplate { $( $str => $Enum::$variant, )* - _ => return Err(Error::enum_parse_error(value)) + _ => return Err($crate::core::errors::Error::enum_parse_error(value)) }; Ok(ret) } diff --git a/vidyut-prakriya/src/args/sup.rs b/vidyut-prakriya/src/args/sup.rs index a81b221..05282c1 100644 --- a/vidyut-prakriya/src/args/sup.rs +++ b/vidyut-prakriya/src/args/sup.rs @@ -98,6 +98,18 @@ impl Vibhakti { } /// The information required to derive a *subanta*. +/// +/// A *subanta* is any word that ends with one of the twenty-one suffixes in the *sup* list: +/// +/// | Singular | Dual | Plural | +/// |-----------|-----------|-----------| +/// | su । au । jas | +/// | am । auṭ । śas | +/// | ṭā । bhyām । bhis | +/// | ṅe । bhyām । bhyas | +/// | ṅasi । bhyām । bhyas | +/// | ṅas । os । ām | +/// | ṅi । os । sup | #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Subanta { diff --git a/vidyut-prakriya/src/args/taddhita.rs b/vidyut-prakriya/src/args/taddhita.rs index 0d110cd..7154813 100644 --- a/vidyut-prakriya/src/args/taddhita.rs +++ b/vidyut-prakriya/src/args/taddhita.rs @@ -40,7 +40,7 @@ pub enum Taddhita { asic, /// -astAt astAti, - /// -Akin, + /// -Akin Akinic, /// -Ara Arak, @@ -60,9 +60,9 @@ pub enum Taddhita { ilac, /// -izWa izWan, - /// -Ika, + /// -Ika Ikak, - /// -Ika, + /// -Ika Ikan, /// -Iyas Iyasun, @@ -86,7 +86,7 @@ pub enum Taddhita { kftvasuc, /// -kuwAra kuwArac, - /// -kura, + /// -kura kuRap, /// -Ina Ka, @@ -112,21 +112,21 @@ pub enum Taddhita { cvi, /// -Iya Ca, - /// -Iya, + /// -Iya CaR, - /// -Iya, + /// -Iya Cas, /// -jAtIya jAtIyar, /// -jAha jAhac, - /// -a, + /// -a Ya, /// -ika YiW, /// -ya Yya, - /// -ya, + /// -ya YyaN, /// -ya Yyaw, @@ -338,7 +338,7 @@ pub enum Taddhita { za, /// -ka zkan, - /// -tra + /// -tara zwarac, /// -ika zWac, diff --git a/vidyut-prakriya/src/args/tin.rs b/vidyut-prakriya/src/args/tin.rs index 85ab932..a053616 100644 --- a/vidyut-prakriya/src/args/tin.rs +++ b/vidyut-prakriya/src/args/tin.rs @@ -208,11 +208,26 @@ impl DhatuPada { /// The information required to derive a *tiṅanta*. /// +/// A *tiṅanta* (verb) is any word that ends with one of the eighteen suffixes in the *tiṅ* list: +/// +/// | Singular | Dual | Plural | +/// |-------------|-------------|-------------| +/// | *tip* | *tas* | *jhi (nti)* | +/// | *sip* | *tas* | *tha* | +/// | *mip* | *vas* | *mas* | +/// +/// | Singular | Dual | Plural | +/// |-------------|-------------|-------------| +/// | *ta* | *ātām* | *jha (nta)* | +/// | *thās* | *āthām* | *dhvam* | +/// | *iṭ* | *vahi* | *mahiṅ* | +/// /// If a *tiṅanta* were just a matter of prayoga/purusha/lakara/vacana, a struct like this would /// not be necessary. However, a *tiṅanta*'s derivation can have many other constraints, including: /// /// - specific *upasarga*s or other prefixes /// - specific *sanādi pratyaya*s +/// - whether or not we should skip adding the *aṭ*/*āṭ* *āgama* for certain past forms. /// - other constraints on the overall derivation /// /// Since we want to keep these args manageable and don't want to repeatedly break our main API, we @@ -226,6 +241,7 @@ pub struct Tinanta { purusha: Purusha, vacana: Vacana, pada: Option, + skip_at_agama: bool, } impl Tinanta { @@ -246,6 +262,7 @@ impl Tinanta { purusha, vacana, pada: None, + skip_at_agama: false, } } @@ -274,6 +291,11 @@ impl Tinanta { self.vacana } + /// Whether or not the *aṭ* and *āṭ* *āgama*s should be skipped in the derivation. + pub fn skip_at_agama(&self) -> bool { + self.skip_at_agama + } + /// (optional) The pada to use in the derivation. /// /// If unset, the program will use whatever padas are allowed by the Atmanepada section of the @@ -323,6 +345,7 @@ pub struct TinantaArgsBuilder { lakara: Option, vacana: Option, pada: Option, + skip_at_agama: bool, } impl TinantaArgsBuilder { @@ -356,6 +379,12 @@ impl TinantaArgsBuilder { self } + /// Sets whether or not to skip the `a` Agama in the derivation. + pub fn skip_at_agama(mut self, val: bool) -> Self { + self.skip_at_agama = val; + self + } + /// Sets the pada to use in the derivation. /// /// If unset, the program will use whatever padas are allowed by the Atmanepada section of the @@ -391,6 +420,7 @@ impl TinantaArgsBuilder { _ => return Err(Error::missing_required_field("vacana")), }, pada: self.pada, + skip_at_agama: self.skip_at_agama, }) } } diff --git a/vidyut-prakriya/src/args/unadi.rs b/vidyut-prakriya/src/args/unadi.rs index a783939..c6746f1 100644 --- a/vidyut-prakriya/src/args/unadi.rs +++ b/vidyut-prakriya/src/args/unadi.rs @@ -957,3 +957,10 @@ enum_boilerplate!(Unadi, { sya => "sya", syan => "syan", }); + +impl Unadi { + /// Returns the *aupadesika* form of this pratyaya. + pub fn aupadeshika(&self) -> &'static str { + self.as_str() + } +} diff --git a/vidyut-prakriya/src/ashtadhyayi.rs b/vidyut-prakriya/src/ashtadhyayi.rs index d05eb05..d7d6ec3 100644 --- a/vidyut-prakriya/src/ashtadhyayi.rs +++ b/vidyut-prakriya/src/ashtadhyayi.rs @@ -67,6 +67,7 @@ struct MainArgs { lakara: Option, is_ardhadhatuka: bool, needs_dhatu_pada: bool, + skip_at_agama: bool, } impl Default for MainArgs { @@ -75,6 +76,7 @@ impl Default for MainArgs { lakara: None, is_ardhadhatuka: false, needs_dhatu_pada: true, + skip_at_agama: false, } } } @@ -82,7 +84,7 @@ impl Default for MainArgs { impl MainArgs { fn dhatu_args(dhatu: &Dhatu, is_ardhadhatuka: bool, future_lakara: Option) -> Self { MainArgs { - lakara: match dhatu.upadesha() { + lakara: match dhatu.aupadeshika() { // Zero out the lakara for most dhatus to increase the cache hit rate. Some(s) => { if s == "aja~" || matches!(future_lakara, Some(Lakara::Lun)) { @@ -95,6 +97,7 @@ impl MainArgs { }, is_ardhadhatuka, needs_dhatu_pada: true, + skip_at_agama: false, } } } @@ -451,6 +454,7 @@ fn add_lakara_and_decide_pada(p: &mut Prakriya, lakara: Lakara) { fn run_main_rules(p: &mut Prakriya, dhatu_args: Option<&Dhatu>, args: MainArgs) { let lakara = args.lakara; let is_ardhadhatuka = args.is_ardhadhatuka; + let skip_at_agama = args.skip_at_agama; let is_tinanta = p.terms().last().map_or(false, |t| t.is_tin()); let is_lit_or_ashirlin = matches!(lakara, Some(Lakara::Lit) | Some(Lakara::AshirLin)); @@ -553,7 +557,7 @@ fn run_main_rules(p: &mut Prakriya, dhatu_args: Option<&Dhatu>, args: MainArgs) angasya::maybe_do_jha_adesha(p); ac_sandhi::try_sup_sandhi_before_angasya(p); - angasya::run_before_dvitva(p, is_lun); + angasya::run_before_dvitva(p, is_lun, skip_at_agama); // After guna ardhadhatuka::try_aa_adesha_for_sedhayati(p); @@ -590,6 +594,7 @@ pub fn derive_dhatu(mut prakriya: Prakriya, dhatu: &Dhatu) -> Result { lakara: None, is_ardhadhatuka: false, needs_dhatu_pada: true, + skip_at_agama: false, }, ); tripadi::run(p); @@ -630,6 +635,7 @@ pub fn derive_tinanta(mut prakriya: Prakriya, args: &Tinanta) -> Result Result Result<(), Box> { let dhatu = entry.dhatu().clone().with_sanadi(&s); let prakriyas = v.derive_dhatus(&dhatu); - let dhatu_text = &dhatu.upadesha().expect("ok"); + let dhatu_text = &dhatu.aupadeshika().expect("ok"); let mut results: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); results.sort(); results.dedup(); diff --git a/vidyut-prakriya/src/bin/create_krdantas.rs b/vidyut-prakriya/src/bin/create_krdantas.rs index 2e9af53..e4331e9 100644 --- a/vidyut-prakriya/src/bin/create_krdantas.rs +++ b/vidyut-prakriya/src/bin/create_krdantas.rs @@ -45,7 +45,7 @@ fn linga_vibhakti_vacana_options() -> Vec<(Linga, Vibhakti, Vacana)> { for linga in Linga::iter() { for vibhakti in Vibhakti::iter() { for vacana in Vacana::iter() { - ret.push((*linga, *vibhakti, *vacana)) + ret.push((linga, vibhakti, vacana)) } } } @@ -59,7 +59,7 @@ fn run(dhatupatha: Dhatupatha, args: Args) -> Result<(), Box> { for entry in dhatupatha { let dhatu = entry.dhatu().clone().with_sanadi(&args.sanadi); - let dhatu_text = &dhatu.upadesha().expect("mula"); + let dhatu_text = &dhatu.aupadeshika().expect("mula"); let sanadi_str = args .sanadi .iter() diff --git a/vidyut-prakriya/src/bin/create_test_file.rs b/vidyut-prakriya/src/bin/create_test_file.rs index 62c2369..6d2e18e 100644 --- a/vidyut-prakriya/src/bin/create_test_file.rs +++ b/vidyut-prakriya/src/bin/create_test_file.rs @@ -46,12 +46,12 @@ fn run(d: Dhatupatha) -> Result<(), Box> { .prayoga(prayoga) .purusha(*purusha) .vacana(*vacana) - .lakara(*lakara) + .lakara(lakara) .build()?; let prakriyas = v.derive_tinantas(&tinanta); - let dhatu_text = &dhatu.upadesha().expect("ok"); + let dhatu_text = &dhatu.aupadeshika().expect("ok"); let mut padas: Vec<_> = prakriyas.iter().map(|p| p.text()).collect(); padas.sort(); let padas = padas.join("|"); diff --git a/vidyut-prakriya/src/bin/create_tinantas.rs b/vidyut-prakriya/src/bin/create_tinantas.rs index 8be17d5..1e42c44 100644 --- a/vidyut-prakriya/src/bin/create_tinantas.rs +++ b/vidyut-prakriya/src/bin/create_tinantas.rs @@ -60,7 +60,7 @@ fn run(d: Dhatupatha, args: Args) -> Result<(), Box> { // Add sanadi to the dhatu. let mut builder = Dhatu::builder() - .upadesha(dhatu.upadesha()) + .aupadeshika(dhatu.aupadeshika()) .prefixes(dhatu.prefixes()) .gana(dhatu.gana()) .sanadi(&sanadi); @@ -73,21 +73,21 @@ fn run(d: Dhatupatha, args: Args) -> Result<(), Box> { for prayoga in Prayoga::iter() { // Filter prayoga based on args if let Some(p) = args.prayoga { - if *prayoga != p { + if prayoga != p { continue; } } for lakara in Lakara::iter() { - if *lakara == Lakara::Let { + if lakara == Lakara::Let { continue; } - for (purusha, vacana) in TIN_SEMANTICS { + for (purusha, vacana) in TIN_SEMANTICS.iter().copied() { let tinanta = Tinanta::builder() .dhatu(dhatu.clone()) - .prayoga(*prayoga) - .purusha(*purusha) - .vacana(*vacana) - .lakara(*lakara) + .prayoga(prayoga) + .purusha(purusha) + .vacana(vacana) + .lakara(lakara) .build()?; let prakriyas = v.derive_tinantas(&tinanta); @@ -106,7 +106,7 @@ fn run(d: Dhatupatha, args: Args) -> Result<(), Box> { .fold(String::new(), |b, x| b + x + "+"); let sanadi_str = sanadi_str.trim_end_matches('+'); - let dhatu_text = mula.upadesha(); + let dhatu_text = mula.aupadeshika(); let row = Row { padas, dhatu: dhatu_text, diff --git a/vidyut-prakriya/src/bin/test_results.rs b/vidyut-prakriya/src/bin/test_results.rs index 9c41462..e3ed0c3 100644 --- a/vidyut-prakriya/src/bin/test_results.rs +++ b/vidyut-prakriya/src/bin/test_results.rs @@ -69,7 +69,7 @@ fn test_tinanta(line: &str) -> Result<(), Box> { // TODO: this is very clumsy! let mut builder = Dhatu::builder() - .upadesha(dhatu.upadesha().expect("ok")) + .aupadeshika(dhatu.aupadeshika().expect("ok")) .gana(dhatu.gana().expect("ok")) .prefixes(dhatu.prefixes()) .sanadi(&sanadi); @@ -99,7 +99,7 @@ fn test_tinanta(line: &str) -> Result<(), Box> { let purusha = &r[6]; let vacana = &r[7]; let code = format!("{:0>2}.{:0>4}", gana, number); - let upadesha = dhatu.upadesha().expect("ok"); + let upadesha = dhatu.aupadeshika().expect("ok"); let mut out = std::io::stdout().lock(); writeln!( @@ -137,7 +137,7 @@ fn test_krdanta(r: Result) -> Result<(), Box> if expected != actual { let code = format!("{:0>2}.{:0>4}", gana, number); - let upadesha = dhatu.upadesha().expect("ok"); + let upadesha = dhatu.aupadeshika().expect("ok"); let mut out = std::io::stdout().lock(); writeln!(out, "[ FAIL ] {code:<10} {upadesha:<10} {krt:<10}")?; @@ -171,7 +171,7 @@ fn test_dhatu(line: &str) -> Result<(), Box> { if expected != actual { let code = format!("{gana:0>2}.{number:0>4}"); - let upadesha = dhatu.upadesha().expect("ok"); + let upadesha = dhatu.aupadeshika().expect("ok"); let mut out = std::io::stdout().lock(); writeln!(out, "[ FAIL ] {code:<10} {upadesha:<10} {sanadi:?}")?; diff --git a/vidyut-prakriya/src/caching.rs b/vidyut-prakriya/src/caching.rs index 70cb054..fc6fa76 100644 --- a/vidyut-prakriya/src/caching.rs +++ b/vidyut-prakriya/src/caching.rs @@ -79,3 +79,40 @@ pub(crate) fn calculate_hash(t: &T) -> u64 { t.hash(&mut s); s.finish() } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn basic_caching() { + let mut c: Cache = Cache::new(3); + + // Empty cache + assert_eq!(c.read(&1), None); + + // Fill up cache + c.write(1, 10); + assert_eq!(c.read(&1), Some(&10)); + c.write(2, 20); + assert_eq!(c.read(&2), Some(&20)); + c.write(3, 30); + assert_eq!(c.read(&3), Some(&30)); + + // Cache eviction of 1. + c.write(4, 40); + assert_eq!(c.read(&1), None); + + // Cache eviction of 3, since 2 is recently read. + assert_eq!(c.read(&2), Some(&20)); + c.write(5, 50); + assert_eq!(c.read(&2), Some(&20)); + + // Final state. + assert_eq!(c.read(&1), None); + assert_eq!(c.read(&2), Some(&20)); + assert_eq!(c.read(&3), None); + assert_eq!(c.read(&4), Some(&40)); + assert_eq!(c.read(&5), Some(&50)); + } +} diff --git a/vidyut-prakriya/src/core/term.rs b/vidyut-prakriya/src/core/term.rs index 92053de..592b6e0 100644 --- a/vidyut-prakriya/src/core/term.rs +++ b/vidyut-prakriya/src/core/term.rs @@ -766,6 +766,7 @@ impl Term { /// Returns whether the term has the `Upasarga` samjna. pub fn is_upasarga(&self) -> bool { + // Must check tag due to extensions like "antar". self.has_tag(Tag::Upasarga) } diff --git a/vidyut-prakriya/src/dhatu_karya.rs b/vidyut-prakriya/src/dhatu_karya.rs index 14683db..016c379 100644 --- a/vidyut-prakriya/src/dhatu_karya.rs +++ b/vidyut-prakriya/src/dhatu_karya.rs @@ -26,7 +26,7 @@ use crate::samjna; /// Adds the *mūla-dhātu* to the prakriya. fn add_mula_dhatu(p: &mut Prakriya, dhatu: &Muladhatu) { p.run("1.3.1", |p| { - let mut dhatu = Term::make_dhatu(dhatu.upadesha(), dhatu.gana(), dhatu.antargana()); + let mut dhatu = Term::make_dhatu(dhatu.aupadeshika(), dhatu.gana(), dhatu.antargana()); dhatu.add_tags(&[T::Dhatu, T::MulaDhatu]); p.push(dhatu); }); @@ -303,7 +303,7 @@ pub fn run(p: &mut Prakriya, dhatu: &Muladhatu) -> Result<()> { add_samjnas(p, i_dhatu); if p.has(i_dhatu, |t| t.is_empty()) { - return Err(Error::invalid_upadesha(dhatu.upadesha())); + return Err(Error::invalid_upadesha(dhatu.aupadeshika())); } } diff --git a/vidyut-prakriya/src/dhatupatha.rs b/vidyut-prakriya/src/dhatupatha.rs index 055b732..ec86674 100644 --- a/vidyut-prakriya/src/dhatupatha.rs +++ b/vidyut-prakriya/src/dhatupatha.rs @@ -79,7 +79,7 @@ pub struct Dhatupatha(Vec); pub fn create_dhatu(upadesha: impl AsRef, gana: Gana, number: u16) -> Result { let upadesha = upadesha.as_ref(); - let mut builder = Dhatu::builder().upadesha(upadesha).gana(gana); + let mut builder = Dhatu::builder().aupadeshika(upadesha).gana(gana); if let Some(x) = maybe_find_antargana(gana, number) { builder = builder.antargana(x); } @@ -231,7 +231,7 @@ mod tests { #[test] fn create_dhatu_basic() { let dhatu = create_dhatu("BU", Gana::Bhvadi, 1).unwrap(); - assert_eq!(dhatu.upadesha().unwrap(), "BU"); + assert_eq!(dhatu.aupadeshika().unwrap(), "BU"); assert_eq!(dhatu.gana().expect("ok"), Gana::Bhvadi); assert!(dhatu.prefixes().is_empty()); assert!(dhatu.sanadi().is_empty()); @@ -240,7 +240,7 @@ mod tests { #[test] fn create_dhatu_with_ashas() { let dhatu = create_dhatu("SAsu~\\", Gana::Adadi, 23).unwrap(); - assert_eq!(dhatu.upadesha().unwrap(), "SAsu~\\"); + assert_eq!(dhatu.aupadeshika().unwrap(), "SAsu~\\"); assert_eq!(dhatu.gana().expect("ok"), Gana::Adadi); assert_eq!(dhatu.prefixes(), &vec!["AN"]); assert!(dhatu.sanadi().is_empty()); diff --git a/vidyut-prakriya/src/ganapatha.rs b/vidyut-prakriya/src/ganapatha.rs index d046a76..05fdaf3 100644 --- a/vidyut-prakriya/src/ganapatha.rs +++ b/vidyut-prakriya/src/ganapatha.rs @@ -346,6 +346,8 @@ pub const BHRSHA_ADI: &[&str] = &[ /// 3.1.13 lohitAdi-qAj-ByaH kyaz (33) pub const LOHITA_ADI: &[&str] = &[ "lohita", "carita", "nIla", "Pena", "madra", "hari", "dAsa", "man", + // This is an Akrti-gana, so other terms are included here too. + "carman", ]; /// 3.1.17 suKAdiByaH kartf-vedanAyAm (34) diff --git a/vidyut-prakriya/src/krt/basic.rs b/vidyut-prakriya/src/krt/basic.rs index 30edb1c..42715a7 100644 --- a/vidyut-prakriya/src/krt/basic.rs +++ b/vidyut-prakriya/src/krt/basic.rs @@ -102,12 +102,14 @@ fn try_add_various_pratyayas(kp: &mut KrtPrakriya) { // Therefore, the pratyayas in this section are blocking: for a given dhatu, exactly one of these // pratyayas can be used. // - // That said, there are some minor exceptions here and there where multiple pratyayas can apply. + // However, there are some minor exceptions where multiple pratyayas can apply for the given + // dhatu. kp.with_context(TacchilaTaddharmaTatsadhukara, |kp| { let dhatu = kp.dhatu_start(); let i_dhatu = kp.i_dhatu; let has_prefix_and_text = |x, y| kp.has_upapada(x) && dhatu.has_text(y); + let has_upasarga_and_u = |x, y| kp.has_upasarga(x) && dhatu.has_u(y); let has_upasarga_and_text = |x, y| kp.has_upasarga(x) && dhatu.has_text(y); let last = kp.p.terms().last().expect("present"); let has_nic = last.is(S::Ric); @@ -157,41 +159,71 @@ fn try_add_various_pratyayas(kp: &mut KrtPrakriya) { } else if kp.has_upasarga(U::vi) && dhatu.has_text_in(&["kaz", "las", "katT", "sranB"]) { kp.try_add("3.2.143", GinuR); } else if kp.has_upasarga_in(&[U::vi, U::apa]) && dhatu.has_text("laz") { + // vilAzin, apalAzin kp.try_add("3.2.144", GinuR); } else if kp.has_upasarga(U::pra) && dhatu.has_u_in(&["lapa~", "sf\\", "dru\\", "maTe~", "vada~", "va\\sa~"]) { kp.try_add("3.2.145", GinuR); + } else if dhatu.has_text_in(&["sf", "Gas", "ad"]) { + // sfmara, Gasmara, admara + // (placed here because 'sf' matches elsewhere.) + kp.try_add("3.2.160", kmarac); + } else if dhatu.has_u("ga\\mx~") { + // gatvara + // ('gam' matches elsewhere.) + kp.try_add_with("3.2.164", kvarap, |p| p.set(i_dhatu, |t| t.set_antya("t"))); + } else if has_san || has_upasarga_and_u(U::AN, "Sasi~\\") || dhatu.has_u("Bikza~\\") { + // cikIrzu, jihIrzu, ... + // ('Bikz' matches elsewhere.) + kp.try_add("3.2.168", u); } // Break the `if` chain so that pari-kzip and pari-raw can match again here. let dhatu = kp.dhatu_start(); - let has_prefix_and_text = |x, y| kp.has_upapada(x) && dhatu.has_text(y); - let has_upasarga_and_text = |x, y| kp.has_upasarga(x) && dhatu.has_text(y); + let has_upasarga_and_u = |x, y| kp.has_upasarga(x) && dhatu.has_u(y); if dhatu.has_text_in(&["nind", "hins", "kliS", "KAd"]) - || (has_upasarga_and_text(U::vi, "naS") && has_nic) - || has_upasarga_and_text(U::pari, "kzip") - || has_upasarga_and_text(U::pari, "raw") - || (has_upasarga_and_text(U::pari, "vad") && has_nic) - || (kp.has_both_upasargas(U::vi, U::AN) && dhatu.has_text("BAz")) - // TODO: not in dhatupatha -- how does the prakriya start? - || dhatu.has_text("asUy") + || (has_upasarga_and_u(U::vi, "Ra\\Sa~") && has_nic) + || has_upasarga_and_u(U::pari, "kzi\\pa~") + || has_upasarga_and_u(U::pari, "rawa~") + || (has_upasarga_and_u(U::pari, "vada~") && has_nic) + || (kp.has_both_upasargas(U::vi, U::AN) && dhatu.has_u("BAza~\\")) + || dhatu.has_text("asU") { + // nindaka, hiMsaka kp.try_add("3.2.146", vuY); - } else if upasarge && dhatu.has_text_in(&["div", "kruS"]) { + } else if upasarge + && ((dhatu.has_u("divu~") && dhatu.has_gana(Gana::Curadi)) || dhatu.has_u("kru\\Sa~")) + { + // Adevaka, parikraSoka kp.try_add("3.2.147", vuY); - } else if dhatu.has_text_in(&[ - "laz", "pat", "pad", "sTA", "BU", "vfz", "han", "kam", "gam", "SF", + } else if dhatu.has_u_in(&["cala~", "cupa~", "Sabda~", "ru"]) { + // calana, copana, ... + kp.try_add("3.2.148", yuc); + } else if dhatu.has_u_in(&[ + "laza~^", + "patx~", + "pa\\da~\\", + "zWA\\", + "BU", + "vfzu~", + "ha\\na~", + "kamu~\\", + "ga\\mx~", + "SF", ]) { + // apalAzuka, prapAtuka, ... kp.try_add("3.2.154", ukaY); - } else if dhatu.has_text_in(&["jalp", "Bikz", "kuww", "lunw", "vf"]) { + } else if dhatu.has_u_in(&["jalpa~", "Bikza~\\", "kuwwa~", "lunwa~", "vfN"]) { + // jalpAka, ... kp.try_add("3.2.154", zAkan); + } else if kp.has_upasarga(U::pra) && dhatu.has_u("ju") { + // prajavin + kp.try_add("3.2.155", ini); } else if dhatu.has_u_in(&["spfha", "gfha", "pata", "daya~\\"]) { // Per kashika, first 3 are curAdi. kp.try_add("3.2.158", Aluc); // TODO: others - } else if dhatu.has_text_in(&["sf", "Gas", "ad"]) { - kp.try_add("3.2.160", kmarac); } else if dhatu.has_text_in(&["Banj", "BAs", "mid"]) { kp.try_add("3.2.161", Gurac); } else if (dhatu.is_u(Au::vida_2) && dhatu.has_gana(Gana::Adadi)) @@ -199,19 +231,17 @@ fn try_add_various_pratyayas(kp: &mut KrtPrakriya) { { // Per commentaries, allow only this specific `vid`. kp.try_add("3.2.162", kurac); - } else if dhatu.has_u("i\\R") || dhatu.has_text_in(&["naS", "ji", "sf"]) { + } else if dhatu.has_u_in(&["i\\R", "Ra\\Sa~", "ji\\", "sf\\"]) { // naSvara, ... kp.try_add("3.2.163", kvarap); } else if dhatu.has_text("jAgf") { // jAgarUka kp.try_add("3.2.165", Uka); - } else if dhatu.has_text_in(&["yaj", "jap", "daS"]) && has_yan { + } else if dhatu.has_u_in(&["ya\\ja~", "japa~", "da\\nSa~"]) && has_yan { // yAyajUka, ... kp.try_add("3.2.166", Uka); } else if dhatu.has_text_in(&["nam", "kanp", "smi", "jas", "kam", "hins", "dIp"]) { kp.try_add("3.2.167", ra); - } else if has_san || has_prefix_and_text("A", "Sans") || dhatu.has_text("Bikz") { - kp.try_add("3.2.168", u); } else if dhatu.has_text_in(&["svap", "tfz"]) { kp.try_add("3.2.172", najiN); } else if dhatu.has_text_in(&["SF", "vand"]) { @@ -659,7 +689,6 @@ fn try_add_upapada_krt(kp: &mut KrtPrakriya) -> Option { } } KaS if upapade => { - println!("{:?}", dhatu); let nasika = upapada.has_text("nAsikA"); let stana = upapada.has_text("stana"); let dhma = dhatu.has_u("DmA\\"); @@ -920,6 +949,11 @@ fn try_add_upapada_krt(kp: &mut KrtPrakriya) -> Option { fn try_add_krt(kp: &mut KrtPrakriya) -> Option { use BaseKrt as K; + if kp.krt == K::ki && kp.has_upapada("antar") { + let i_upapada = kp.i_upapada()?; + kp.p.run_at(Varttika("1.4.65"), i_upapada, op::add_tag(T::Upasarga)); + } + let i_start = kp.p.find_first_with_tag(T::Dhatu)?; let i_end = kp.p.find_last_with_tag(T::Dhatu)?; @@ -1423,6 +1457,12 @@ fn try_add_krt(kp: &mut KrtPrakriya) -> Option { } } + K::ki => { + if upasarge && dhatu.has_tag(T::Ghu) { + kp.try_add("3.3.92", krt); + } + } + K::Rvuc => {} K::ani => {} @@ -1484,6 +1524,13 @@ fn try_add_strilinga_pratyayas(kp: &mut KrtPrakriya) -> Option { // vrajyA, ijyA // BAve kp.optional_try_add_with("3.3.98", kyap, |p| p.add_tag(PT::Stri)); + } else if kp.has_upa_u(U::sam, "aja~") + || kp.has_upa_u(U::ni, "za\\dx~") + || kp.has_upa_u(U::ni, "patx~") + || dhatu.has_u_in(&["ma\\na~\\", "vida~", "zu\\Y", "SIN", "Bf\\Y", "i\\R"]) + { + // samajyA, nizadyA, ... + kp.try_add_with("3.3.99", kyap, |p| p.add_tag(PT::Stri)); } else if dhatu.has_u("qukf\\Y") { // kfti kp.optional_try_add_with("3.3.100:1", ktin, |p| { @@ -1502,13 +1549,73 @@ fn try_add_strilinga_pratyayas(kp: &mut KrtPrakriya) -> Option { }); } - let dhatu = kp.dhatu_start(); - if dhatu.has_u_in(&["glE\\", "mlE\\", "jyA\\", "o~hA\\k"]) { + fn map_uti_yuti(t: &Term) -> Option<&'static str> { + let ret = match t.u.as_ref()?.as_str() { + "ava~" => "U", + "yu" => "yU", + "ju" => "jU", + "zo\\" => "sA", + "zaRa~" => "sA", + "ha\\na~" => "he", + "hi\\" => "he", + "kFta~" => "kIr", + _ => return None, + }; + Some(ret) + } + + let dhatu = kp.dhatu_end(); + let i_dhatu_end = kp.i_dhatu_end; + if dhatu.has_u_in(&[ + "A\\px~", + "rA\\Da~", + "dIpI~\\", + "sransu~\\", + "Dvansu~\\", + "qula\\Ba~\\z", + ]) { + // Apti, ... + kp.try_add_with(Varttika("3.3.94.1"), ktin, |p| p.add_tag(PT::Stri)); + } else if dhatu.has_u_in(&["Sru\\", "ya\\ja~^", "zwu\\Y"]) { + // Sruti, izwi, stuti + kp.try_add_with(Varttika("3.3.94.2"), ktin, |p| p.add_tag(PT::Stri)); + } else if dhatu.has_u_in(&["glE\\", "mlE\\", "jyA\\", "o~hA\\k"]) { // glAni, ... kp.try_add_with(Varttika("3.3.94.3"), ni, |p| p.add_tag(PT::Stri)); + } else if dhatu.has_antya('F') || dhatu.has_u_in(gana::LU_ADI) { + // kIrRi, gIrRi, ... + kp.try_add_with(Varttika("3.3.94.4"), ktin, |p| { + p.add_tag(PT::Stri); + p.terms_mut().last_mut().expect("ok").add_tag(T::Nistha); + }); + } else if kp.has_upasarga(U::sam) && dhatu.has_u("pa\\da~\\") { + // sampat, sampatti, vipat, vipatti + kp.try_add_with(Varttika("3.3.94.5"), kvip, |p| p.add_tag(PT::Stri)); + } else if dhatu.has_u_in(&["zWA\\", "gE\\", "pA\\", "qupa\\ca~^z"]) { + // prasTiti, ... + kp.try_add_with(Varttika("3.3.96"), ktin, |p| p.add_tag(PT::Stri)); + } else if let Some(sub) = map_uti_yuti(kp.dhatu_start()) { + let i_dhatu_start = kp.i_dhatu; + let matches = (i_dhatu_start == i_dhatu_end) + || (i_dhatu_start + 1 == i_dhatu_end && kp.dhatu_start().has_u("kFta~")); + + if matches { + // Uti, yUti, ... + kp.try_add_with(Varttika("3.3.97"), ktin, |p| { + p.set(i_dhatu_start, |t| { + t.set_text(sub); + t.add_tag(T::Complete) + }); + p.add_tag(PT::Stri) + }); + } } else if dhatu.has_u("izu~") { // icCA kp.do_nipatana("3.3.101", "icCA"); + } else if dhatu.is(S::Ric) || dhatu.has_u_in(&["Asa~\\", "SranTa~"]) { + // kAraRA, hAraRA, ... + // (blocks 3.3.102) + kp.try_add_with("3.3.107", yuc, |p| p.add_tag(PT::Stri)); } else if kp.p.has(i_end, |t| t.is_pratyaya()) { // cikIrzA, jihIrzA, ... kp.try_add_with("3.3.102", a, |p| p.add_tag(PT::Stri)); @@ -1518,12 +1625,18 @@ fn try_add_strilinga_pratyayas(kp: &mut KrtPrakriya) -> Option { } else if dhatu.has_tag(T::zit) { // TODO: bhid-Adi kp.try_add_with("3.3.104", aN, |p| p.add_tag(PT::Stri)); - } else if dhatu.has_antya('A') && upasarge { - // pradA, upadA, ... - kp.try_add_with("3.3.106", aN, |p| p.add_tag(PT::Stri)); - } else if dhatu.is(S::Ric) || dhatu.has_u_in(&["Asa~\\", "SranTa~"]) { - // kAraRA, hAraRA, ... - kp.try_add_with("3.3.107", yuc, |p| p.add_tag(PT::Stri)); + } else if dhatu.has_antya('A') { + let ok = if kp.has_upapada_in(&["Srad", "antar"]) { + // SradDA, antarDA + kp.p.run_at(Varttika("3.3.106.1"), kp.i_upapada()?, |_| {}); + true + } else { + false + }; + if upasarge || ok { + // pradA, upadA, ... + kp.try_add_with("3.3.106", aN, |p| p.add_tag(PT::Stri)); + } } // kfti, citi, mati, ... diff --git a/vidyut-prakriya/src/krt/utils.rs b/vidyut-prakriya/src/krt/utils.rs index 956fb6d..a28fe02 100644 --- a/vidyut-prakriya/src/krt/utils.rs +++ b/vidyut-prakriya/src/krt/utils.rs @@ -39,6 +39,8 @@ pub(crate) struct KrtPrakriya<'a> { pub p: &'a mut Prakriya, /// The first index of the dhatu. pub i_dhatu: usize, + /// The last index of the dhatu. + pub i_dhatu_end: usize, /// The krt-pratyaya that the caller wishes to add. pub krt: BaseKrt, pub rule_artha: Option, @@ -50,9 +52,11 @@ impl<'a> KrtPrakriya<'a> { /// Creates a new `KrtPrakriya` struct. pub fn new(p: &'a mut Prakriya, krt: BaseKrt) -> Self { let i_dhatu = p.find_first_where(|t| t.is_dhatu()).unwrap_or(0); + let i_dhatu_end = p.find_last_where(|t| t.is_dhatu()).unwrap_or(0); KrtPrakriya { p, i_dhatu, + i_dhatu_end, krt, rule_artha: None, had_match: false, @@ -65,13 +69,19 @@ impl<'a> KrtPrakriya<'a> { self.p.get(self.i_dhatu).expect("present") } + pub fn has_upa_u(&self, upasarga: Upasarga, dhatu: &str) -> bool { + self.has_upasarga(upasarga) + && self.p.has(self.i_dhatu, |t| t.has_u(dhatu)) + && self.i_dhatu == self.i_dhatu_end + } + /// Returns a reference to the last dhatu term for this prakriya. pub fn dhatu_end(&self) -> &Term { let i = self.p.find_last_where(|t| t.is_dhatu()).expect("present"); self.p.get(i).expect("present") } - fn i_upapada(&self) -> Option { + pub fn i_upapada(&self) -> Option { self.p.find_prev_where(self.i_dhatu, |t| !t.is_empty()) } diff --git a/vidyut-prakriya/src/vyakarana.rs b/vidyut-prakriya/src/vyakarana.rs index 4aa5402..153fef8 100644 --- a/vidyut-prakriya/src/vyakarana.rs +++ b/vidyut-prakriya/src/vyakarana.rs @@ -169,8 +169,7 @@ impl Vyakarana { /// A basic *tiṅanta*: /// /// ``` - /// # use vidyut_prakriya::Error; - /// use vidyut_prakriya::Vyakarana; + /// use vidyut_prakriya::{Vyakarana, Error}; /// use vidyut_prakriya::args::*; /// /// let v = Vyakarana::new(); @@ -182,10 +181,69 @@ impl Vyakarana { /// .prayoga(Prayoga::Kartari) /// .purusha(Purusha::Prathama) /// .vacana(Vacana::Eka) - /// .build()?; + /// .build() + /// .unwrap(); /// let prakriyas = v.derive_tinantas(&args); /// assert_eq!(prakriyas[0].text(), "Bavati"); - /// # Ok::<(), Error>(()) + /// ``` + /// + /// A *tiṅanta* with one or more *upasarga*s: + /// + /// ``` + /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::args::*; + /// # let v = Vyakarana::new(); + /// let abhibhu = Dhatu::mula("BU", Gana::Bhvadi).with_prefixes(&["aBi"]); + /// let args = Tinanta::builder() + /// .dhatu(abhibhu) + /// .lakara(Lakara::Lat) + /// .prayoga(Prayoga::Kartari) + /// .purusha(Purusha::Prathama) + /// .vacana(Vacana::Eka) + /// .build() + /// .unwrap(); + /// let prakriyas = v.derive_tinantas(&args); + /// assert_eq!(prakriyas[0].text(), "aBiBavati"); + /// ``` + /// + /// A *tiṅanta* whose *dhātu* has one or more *sanādi-pratyaya*s: + /// + /// ``` + /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::args::*; + /// # let v = Vyakarana::new(); + /// let bobhuya = Dhatu::mula("BU", Gana::Bhvadi).with_sanadi(&[Sanadi::yaN]); + /// let args = Tinanta::builder() + /// .dhatu(bobhuya) + /// .lakara(Lakara::Lat) + /// .prayoga(Prayoga::Kartari) + /// .purusha(Purusha::Prathama) + /// .vacana(Vacana::Eka) + /// .build() + /// .unwrap(); + /// let prakriyas = v.derive_tinantas(&args); + /// assert_eq!(prakriyas[0].text(), "boBUyate"); + /// ``` + /// + /// A *tiṅanta* that must use *ātmanepada*. If the *dhātu* cannot support the requested *pada*, + /// this method returns no results: + /// + /// ``` + /// # use vidyut_prakriya::Vyakarana; + /// # use vidyut_prakriya::args::*; + /// # let v = Vyakarana::new(); + /// let kr = Dhatu::mula("qukf\\Y", Gana::Tanadi); + /// let args = Tinanta::builder() + /// .dhatu(kr) + /// .lakara(Lakara::Lat) + /// .prayoga(Prayoga::Kartari) + /// .purusha(Purusha::Prathama) + /// .vacana(Vacana::Eka) + /// .pada(DhatuPada::Atmane) + /// .build() + /// .unwrap(); + /// let prakriyas = v.derive_tinantas(&args); + /// assert_eq!(prakriyas[0].text(), "kurute"); /// ``` /// /// A *tiṅanta* with one or more *upasarga*s: diff --git a/vidyut-prakriya/test_utils/src/lib.rs b/vidyut-prakriya/test_utils/src/lib.rs index 75cca0d..2f61e3e 100644 --- a/vidyut-prakriya/test_utils/src/lib.rs +++ b/vidyut-prakriya/test_utils/src/lib.rs @@ -102,7 +102,7 @@ impl Tester { } /// Asserts that the given input conditions produce the tinantas `expected`. - fn assert_has_tinantas(&self, args: &Tinanta, expected: &[&str]) { + pub fn assert_has_tinantas(&self, args: &Tinanta, expected: &[&str]) { let mut actual = self.derive_tinantas(args); actual.retain(|p| !uses_va_padantasya(p) && !is_noisy_pada(p) && !has_bad_final(p)); sort_and_dedup(&mut actual); diff --git a/vidyut-prakriya/tests/integration/api.rs b/vidyut-prakriya/tests/integration/api.rs index 26069af..7a4eae5 100644 --- a/vidyut-prakriya/tests/integration/api.rs +++ b/vidyut-prakriya/tests/integration/api.rs @@ -100,7 +100,7 @@ fn derive_tinantas_with_invalid_dhatu() { let v = Vyakarana::new(); let empty_dhatu = Dhatu::builder() - .upadesha("") + .aupadeshika("") .gana(Gana::Tanadi) .build() .unwrap(); @@ -119,7 +119,7 @@ fn derive_tinantas_with_invalid_dhatu() { assert_has_results(prakriyas, &[]); let invalid_dhatu = Dhatu::builder() - .upadesha("k") + .aupadeshika("k") .gana(Gana::Tanadi) .build() .unwrap(); @@ -134,7 +134,7 @@ fn derive_krdantas() { let v = Vyakarana::new(); let kr = Dhatu::builder() - .upadesha("qukf\\Y") + .aupadeshika("qukf\\Y") .gana(Gana::Tanadi) .build() .unwrap(); @@ -144,7 +144,7 @@ fn derive_krdantas() { assert_has_results(prakriyas, &["kftvA"]); let kr_san = Dhatu::builder() - .upadesha("qukf\\Y") + .aupadeshika("qukf\\Y") .gana(Gana::Tanadi) .sanadi(&[Sanadi::Ric]) .build() diff --git a/vidyut-prakriya/tests/integration/basic_tinantas.rs b/vidyut-prakriya/tests/integration/basic_tinantas.rs index 7043aeb..caff399 100644 --- a/vidyut-prakriya/tests/integration/basic_tinantas.rs +++ b/vidyut-prakriya/tests/integration/basic_tinantas.rs @@ -4,7 +4,7 @@ use vidyut_prakriya::Vyakarana; fn derive(upadesha: &str, gana: &str, prayoga: Prayoga) -> Vec { let v = Vyakarana::new(); let dhatu = Dhatu::builder() - .upadesha(upadesha) + .aupadeshika(upadesha) .gana(gana.parse().expect("ok")) .build() .unwrap(); diff --git a/vidyut-prakriya/tests/integration/kashika_1_1.rs b/vidyut-prakriya/tests/integration/kashika_1_1.rs index 565804f..8381cbd 100644 --- a/vidyut-prakriya/tests/integration/kashika_1_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_1_1.rs @@ -6,11 +6,9 @@ use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Pada; -use vidyut_prakriya::args::Purusha as P; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::Unadi; -use vidyut_prakriya::args::Vacana::*; lazy_static! { static ref S: Tester = Tester::with_svara_rules(); @@ -111,9 +109,9 @@ fn sutra_1_1_5() { // Niti assert_has_tas(&[], &ci, Lat, &["cinutaH"]); assert_has_jhi(&[], &ci, Lat, &["cinvanti"]); - assert_has_tinantas(&[], &mfj, Lat, P::Prathama, Dvi, &["mfzwaH"]); + assert_has_tas(&[], &mfj, Lat, &["mfzwaH"]); // mArjanti per SK. - assert_has_tinantas(&[], &mfj, Lat, P::Prathama, Bahu, &["mfjanti", "mArjanti"]); + assert_has_jhi(&[], &mfj, Lat, &["mfjanti", "mArjanti"]); // git assert_has_krdanta(&[], &d("ji\\", Bhvadi), Krt::ksnu, &["jizRu"]); @@ -401,6 +399,31 @@ fn sutra_1_1_34() { assert_has_sup_1p("aDara", Pum, &["aDare", "aDarAH"]); } +#[test] +fn skip_sutra_1_1_37() {} + +#[test] +fn sutra_1_1_38() { + assert_has_taddhita("tad", T::tasil, &["tatas"]); + assert_has_taddhita("yad", T::tasil, &["yatas"]); + assert_has_taddhita("tad", T::tral, &["tatra"]); + assert_has_taddhita("yad", T::tral, &["yatra"]); + assert_has_taddhita("tad", T::dA, &["tadA"]); + assert_has_taddhita("yad", T::dA, &["yadA"]); + assert_has_taddhita("sarva", T::dA, &["sarvadA", "sadA"]); + + // taddhite? + assert_has_sup_1s("eka", Pum, &["ekaH"]); + assert_has_sup_1d("dvi", Pum, &["dvO"]); + assert_has_sup_1p("bahu", Pum, &["bahavaH"]); + + // asarvavibhakti? + let aupagava = taddhitanta("upagu", T::aR); + assert_has_sup_1s(&aupagava, Pum, &["OpagavaH"]); + assert_has_sup_1d(&aupagava, Pum, &["OpagavO"]); + assert_has_sup_1p(&aupagava, Pum, &["OpagavAH"]); +} + #[test] fn sutra_1_1_40() { assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), Krt::ktvA, &["kftvA"]); diff --git a/vidyut-prakriya/tests/integration/kashika_1_4.rs b/vidyut-prakriya/tests/integration/kashika_1_4.rs index 7c387ec..ad2a455 100644 --- a/vidyut-prakriya/tests/integration/kashika_1_4.rs +++ b/vidyut-prakriya/tests/integration/kashika_1_4.rs @@ -1,11 +1,30 @@ extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; +use vidyut_prakriya::args::Dhatu; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; +use vidyut_prakriya::args::Pratipadika; +use vidyut_prakriya::args::Sanadi; use vidyut_prakriya::args::Taddhita as T; +fn p(text: &str) -> Pratipadika { + Pratipadika::basic(text.to_string()) +} + +#[test] +fn sutra_1_4_2() { + assert_has_sup_3d("vfkza", Pum, &["vfkzAByAm"]); + assert_has_sup_3d("plakza", Pum, &["plakzAByAm"]); + + assert_has_sup_7p("vfkza", Pum, &["vfkzezu"]); + assert_has_sup_7p("plakza", Pum, &["plakzezu"]); + + assert_has_sup_5p("vfkza", Pum, &["vfkzeByaH"]); + assert_has_sup_5p("plakza", Pum, &["plakzeByaH"]); +} + #[test] fn sutra_1_4_3() { // IkArAnta @@ -98,6 +117,20 @@ fn sutra_1_4_11() { assert_has_krdanta(&[], &d("Bikza~\\", Bhvadi), Krt::a, &["BikzA"]); } +#[test] +fn sutra_1_4_12() { + assert_has_lit( + &[], + &d("Iha~\\", Bhvadi), + &["IhAYcakre", "IhAmbaBUva", "IhAmAsa"], + ); + assert_has_lit( + &[], + &d("Ikza~\\", Bhvadi), + &["IkzAYcakre", "IkzAmbaBUva", "IkzAmAsa"], + ); +} + #[test] fn sutra_1_4_13() { let kf = d("qukf\\Y", Tanadi); @@ -125,6 +158,27 @@ fn sutra_1_4_14() { assert_has_sup_1p("brAhmaRa", Pum, &["brAhmaRAH"]); } +#[ignore] +#[test] +fn sutra_1_4_15() { + // TODO: 8.2.2 to make na-lopa siddha + let rajiya = Dhatu::nama(p("rAjan"), Some(Sanadi::kyac)); + assert_has_tip(&[], &rajiya, Lat, &["rAjIyati"]); + + let rajaya = Dhatu::nama(p("rAjan"), Some(Sanadi::kyaN)); + assert_has_tip(&[], &rajaya, Lat, &["rAjAyate"]); + + let varmaya = Dhatu::nama(p("carman"), None); + assert_has_tip(&[], &varmaya, Lat, &["carmAyati"]); + assert_has_ta(&[], &varmaya, Lat, &["carmAyate"]); + + let vacya = Dhatu::nama(p("vAc"), Some(Sanadi::kyac)); + assert_has_tip(&[], &vacya, Lat, &["vAcyati"]); + + let sucya = Dhatu::nama(p("sruc"), Some(Sanadi::kyac)); + assert_has_tip(&[], &sucya, Lat, &["srucyati"]); +} + #[test] fn sutra_1_4_16() { assert_has_taddhita("Bavat", T::Cas, &["BavadIya"]); diff --git a/vidyut-prakriya/tests/integration/kashika_2_4.rs b/vidyut-prakriya/tests/integration/kashika_2_4.rs index 31b954e..b39480c 100644 --- a/vidyut-prakriya/tests/integration/kashika_2_4.rs +++ b/vidyut-prakriya/tests/integration/kashika_2_4.rs @@ -383,5 +383,5 @@ fn sutra_2_4_85() { // praTamasya assert_has_sip(&[], &kf, Lut, &["kartAsi"]); - assert_has_tinantas(&["aDi"], &i, Lut, Madhyama, Eka, &["aDyetAse"]); + assert_has_thaas(&["aDi"], &i, Lut, &["aDyetAse"]); } diff --git a/vidyut-prakriya/tests/integration/kashika_3_2.rs b/vidyut-prakriya/tests/integration/kashika_3_2.rs index 3bbaebd..c4923ad 100644 --- a/vidyut-prakriya/tests/integration/kashika_3_2.rs +++ b/vidyut-prakriya/tests/integration/kashika_3_2.rs @@ -1242,6 +1242,88 @@ fn sutra_3_2_145() { assert_has_krdanta(&["pra"], &d("vasa~\\", Adadi), GinuR, &[]); } +#[test] +fn sutra_3_2_146() { + use Krt::vuY; + assert_has_krdanta(&[], &d("Ridi~", Bhvadi), vuY, &["nindaka"]); + assert_has_krdanta(&[], &d("hisi~", Rudhadi), vuY, &["hiMsaka"]); + assert_has_krdanta(&[], &d("kliSU~", Kryadi), vuY, &["kleSaka"]); + assert_has_krdanta(&[], &d("KAdf~", Bhvadi), vuY, &["KAdaka"]); + assert_has_krdanta(&["vi"], &nic(&d("Ra\\Sa~", Divadi)), vuY, &["vinASaka"]); + assert_has_krdanta(&["pari"], &d("kzi\\pa~", Divadi), vuY, &["parikzepaka"]); + assert_has_krdanta(&["pari"], &d("rawa~", Bhvadi), vuY, &["parirAwaka"]); + assert_has_krdanta(&["pari"], &nic(&d("vada~", Bhvadi)), vuY, &["parivAdaka"]); + assert_has_krdanta(&["vi", "AN"], &d("BAza~\\", Bhvadi), vuY, &["vyABAzaka"]); + assert_has_krdanta(&[], &d("asU", Kandvadi), vuY, &["asUyaka"]); +} + +#[test] +fn sutra_3_2_147() { + use Krt::vuY; + let dev = &d("divu~", Curadi); + let krush = &d("kru\\Sa~", Bhvadi); + assert_has_krdanta(&["AN"], &dev, vuY, &["Adevaka"]); + assert_has_krdanta(&["pari"], &dev, vuY, &["paridevaka"]); + assert_has_krdanta(&["AN"], &krush, vuY, &["AkroSaka"]); + assert_has_krdanta(&["pari"], &krush, vuY, &["parikroSaka"]); + + // upasarge? + // devitf allowed by Kaumudi 2560 + assert_has_krdanta(&[], &dev, vuY, &[]); + assert_has_krdanta(&[], &dev, Krt::tfn, &["devayitf", "devitf"]); + assert_has_krdanta(&[], &krush, vuY, &[]); + assert_has_krdanta(&[], &krush, Krt::tfn, &["krozwf"]); +} + +#[test] +fn sutra_3_2_148() { + use Krt::yuc; + assert_has_krdanta(&[], &d("cala~", Bhvadi), yuc, &["calana"]); + assert_has_krdanta(&[], &d("cupa~", Bhvadi), yuc, &["copana"]); + assert_has_krdanta(&[], &d("Sabda~", Curadi), yuc, &["Sabdana"]); + assert_has_krdanta(&[], &d("ru", Adadi), yuc, &["ravaRa"]); + + // akarmakAt? + assert_has_krdanta(&[], &d("paWa~", Bhvadi), yuc, &[]); + assert_has_krdanta(&[], &d("paWa~", Bhvadi), Krt::tfn, &["paWitf"]); +} + +#[test] +fn sutra_3_2_154() { + use Krt::ukaY; + assert_has_krdanta(&["apa"], &d("laza~^", Bhvadi), ukaY, &["apalAzuka"]); + assert_has_krdanta(&["pra"], &d("patx~", Bhvadi), ukaY, &["prapAtuka"]); + assert_has_krdanta(&["upa"], &d("pa\\da~\\", Divadi), ukaY, &["upapAduka"]); + assert_has_krdanta(&["upa"], &d("zWA\\", Bhvadi), ukaY, &["upasTAyuka"]); + assert_has_krdanta(&["pra"], &d("BU", Bhvadi), ukaY, &["praBAvuka"]); + assert_has_krdanta(&["pra"], &d("vfzu~", Bhvadi), ukaY, &["pravarzuka"]); + assert_has_krdanta(&["AN"], &d("ha\\na~", Adadi), ukaY, &["AGAtuka"]); + assert_has_krdanta(&[], &d("kamu~\\", Bhvadi), ukaY, &["kAmuka"]); + assert_has_krdanta(&["AN"], &d("ga\\mx~", Bhvadi), ukaY, &["AgAmuka"]); + assert_has_krdanta(&["kim"], &d("SF", Kryadi), ukaY, &["kiMSAruka"]); +} + +#[test] +fn sutra_3_2_155() { + use Krt::zAkan; + assert_has_krdanta(&[], &d("jalpa~", Bhvadi), zAkan, &["jalpAka"]); + assert_has_krdanta(&[], &d("Bikza~\\", Bhvadi), zAkan, &["BikzAka"]); + assert_has_krdanta(&[], &d("kuwwa~", Curadi), zAkan, &["kuwwAka"]); + assert_has_krdanta(&[], &d("lunwa~", Curadi), zAkan, &["luRwAka"]); + assert_has_krdanta(&[], &d("vfN", Kryadi), zAkan, &["varAka"]); + + // stri + let varaka = krdanta(&[], &d("vfN", Kryadi), zAkan); + assert_has_sup_1s(&varaka, Stri, &["varAkI"]); +} + +#[test] +fn sutra_3_2_156() { + let prajavin = krdanta(&["pra"], &d("ju", Bhvadi), Krt::ini); + assert_has_sup_1s(&prajavin, Pum, &["prajavI"]); + assert_has_sup_1d(&prajavin, Pum, &["prajavinO"]); +} + #[test] fn sutra_3_2_160() { assert_has_krdanta(&[], &d("sf\\", Bhvadi), Krt::kmarac, &["sfmara"]); @@ -1263,7 +1345,6 @@ fn sutra_3_2_162() { assert_has_krdanta(&[], &d("Ci\\di~^r", Rudhadi), Krt::kurac, &["Cidura"]); } -#[ignore] #[test] fn sutra_3_2_163() { use Krt::kvarap; @@ -1273,11 +1354,24 @@ fn sutra_3_2_163() { assert_has_krdanta(&[], &d("sf\\", Bhvadi), kvarap, &["sftvara"]); } +#[test] +fn sutra_3_2_164() { + use Krt::kvarap; + assert_has_krdanta(&[], &d("ga\\mx~", Bhvadi), kvarap, &["gatvara"]); +} + #[test] fn sutra_3_2_165() { assert_has_krdanta(&[], &d("jAgf", Adadi), Krt::Uka, &["jAgarUka"]); } +#[test] +fn sutra_3_2_166() { + assert_has_krdanta(&[], &yan(&d("ya\\ja~", Bhvadi)), Krt::Uka, &["yAyajUka"]); + assert_has_krdanta(&[], &yan(&d("japa~", Bhvadi)), Krt::Uka, &["jaYjapUka"]); + assert_has_krdanta(&[], &yan(&d("da\\nSa~", Bhvadi)), Krt::Uka, &["dandaSUka"]); +} + #[ignore] #[test] fn sutra_3_2_167() { @@ -1289,7 +1383,6 @@ fn sutra_3_2_167() { assert_has_krdanta(&[], &d("dIpI~\\", Divadi), Krt::ra, &["dIpra"]); } -#[ignore] #[test] fn sutra_3_2_168() { assert_has_krdanta(&[], &san(&d("qukf\\Y", Tanadi)), Krt::u, &["cikIrzu"]); diff --git a/vidyut-prakriya/tests/integration/kashika_3_3.rs b/vidyut-prakriya/tests/integration/kashika_3_3.rs index 38a7012..0b40ff1 100644 --- a/vidyut-prakriya/tests/integration/kashika_3_3.rs +++ b/vidyut-prakriya/tests/integration/kashika_3_3.rs @@ -611,6 +611,13 @@ fn sutra_3_3_91() { assert_has_krdanta(&[], &d("Yizva\\pa~", Adadi), K::nan, &["svapna"]); } +#[test] +fn sutra_3_3_92() { + assert_has_krdanta(&["pra"], &d("qudA\\Y", Juhotyadi), K::ki, &["pradi"]); + assert_has_krdanta(&["pra"], &d("quDA\\Y", Juhotyadi), K::ki, &["praDi"]); + assert_has_krdanta(&["antar"], &d("quDA\\Y", Juhotyadi), K::ki, &["antarDi"]); +} + #[test] fn sutra_3_3_94() { assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), K::ktin, &["kfti"]); @@ -644,7 +651,6 @@ fn sutra_3_3_94_v3() { assert_has_krdanta(&[], &d("o~hA\\k", Juhotyadi), K::ni, &["hAni"]); } -#[ignore] #[test] fn sutra_3_3_94_v4() { assert_has_krdanta(&[], &d("kF", Tudadi), K::ktin, &["kIrRi"]); @@ -652,9 +658,7 @@ fn sutra_3_3_94_v4() { assert_has_krdanta(&[], &d("jF", Kryadi), K::ktin, &["jIrRi"]); assert_has_krdanta(&[], &d("SF", Kryadi), K::ktin, &["SIrRi"]); assert_has_krdanta(&[], &d("lUY", Kryadi), K::ktin, &["lUni"]); - assert_has_krdanta(&[], &d("yu\\Y", Kryadi), K::ktin, &["yUni"]); assert_has_krdanta(&[], &d("DUY", Kryadi), K::ktin, &["DUni"]); - assert_has_krdanta(&[], &d("pUY", Kryadi), K::ktin, &["pUni"]); } #[test] @@ -668,12 +672,48 @@ fn sutra_3_3_94_v5() { assert_has_krdanta(&["vi"], &pad, K::ktin, &["vipatti"]); } +#[test] +fn sutra_3_3_96() { + assert_has_krdanta(&["pra"], &d("zWA\\", Bhvadi), K::ktin, &["prasTiti"]); + assert_has_krdanta(&["ud"], &d("gE\\", Bhvadi), K::ktin, &["udgIti"]); + assert_has_krdanta(&["sam"], &d("gE\\", Bhvadi), K::ktin, &["saNgIti"]); + assert_has_krdanta(&["pra"], &d("pA\\", Bhvadi), K::ktin, &["prapIti"]); + assert_has_krdanta(&["sam"], &d("pA\\", Bhvadi), K::ktin, &["sampIti"]); + assert_has_krdanta(&[], &d("qupa\\ca~^z", Bhvadi), K::ktin, &["pakti"]); +} + +#[test] +fn sutra_3_3_97() { + assert_has_krdanta(&[], &d("ava~", Bhvadi), K::ktin, &["Uti"]); + assert_has_krdanta(&[], &d("yu", Adadi), K::ktin, &["yUti"]); + assert_has_krdanta(&[], &d("ju", Bhvadi), K::ktin, &["jUti"]); + assert_has_krdanta(&[], &d("zo\\", Divadi), K::ktin, &["sAti"]); + assert_has_krdanta(&[], &d("zaRa~", Bhvadi), K::ktin, &["sAti"]); + assert_has_krdanta(&[], &d("ha\\na~", Adadi), K::ktin, &["heti"]); + assert_has_krdanta(&[], &d("hi\\", Svadi), K::ktin, &["heti"]); + assert_has_krdanta(&[], &d("kFta~", Curadi), K::ktin, &["kIrti"]); +} + #[test] fn sutra_3_3_98() { assert_has_krdanta(&[], &d("vraja~", Bhvadi), K::kyap, &["vrajyA"]); assert_has_krdanta(&[], &d("ya\\ja~^", Bhvadi), K::kyap, &["ijyA"]); } +#[test] +fn sutra_3_3_99() { + assert_has_krdanta(&["sam"], &d("aja~", Bhvadi), K::kyap, &["samajyA"]); + assert_has_krdanta(&["ni"], &d("za\\dx~", Bhvadi), K::kyap, &["nizadyA"]); + assert_has_krdanta(&["ni"], &d("patx~", Bhvadi), K::kyap, &["nipatyA"]); + assert_has_krdanta(&[], &d("ma\\na~\\", Divadi), K::kyap, &["manyA"]); + assert_has_krdanta(&[], &d("vida~", Adadi), K::kyap, &["vidyA"]); + assert_has_krdanta(&[], &d("zu\\Y", Svadi), K::kyap, &["sutyA"]); + assert_has_krdanta(&[], &d("SIN", Adadi), K::kyap, &["SayyA"]); + // Bftya is from 3.1.112. + assert_has_krdanta(&[], &d("Bf\\Y", Bhvadi), K::kyap, &["Bftya", "BftyA"]); + assert_has_krdanta(&[], &d("i\\R", Adadi), K::kyap, &["ityA"]); +} + #[test] fn sutra_3_3_100() { let kr = d("qukf\\Y", Tanadi); @@ -707,11 +747,27 @@ fn sutra_3_3_103() { assert_has_krdanta(&[], &d("RI\\Y", Bhvadi), K::a, &[]); } -#[ignore] +#[test] +fn sutra_3_3_106() { + let da = &d("qudA\\Y", Juhotyadi); + let dha = &d("quDA\\Y", Juhotyadi); + assert_has_krdanta(&["pra"], &da, K::aN, &["pradA"]); + assert_has_krdanta(&["upa"], &da, K::aN, &["upadA"]); + assert_has_krdanta(&["pra"], &dha, K::aN, &["praDA"]); + assert_has_krdanta(&["upa"], &dha, K::aN, &["upaDA"]); +} + +#[test] +fn sutra_3_3_106_v1() { + let dha = &d("quDA\\Y", Juhotyadi); + assert_has_upapada_krdanta("Srad", &[], &dha, K::aN, &["SradDA"]); + assert_has_upapada_krdanta("antar", &[], &dha, K::aN, &["antarDA"]); +} + #[test] fn sutra_3_3_107() { assert_has_krdanta(&[], &nic(&d("qukf\\Y", Tanadi)), K::yuc, &["kAraRA"]); - assert_has_krdanta(&[], &nic(&d("hf\\Y", Bhvadi)), K::yuc, &["hArRA"]); + assert_has_krdanta(&[], &nic(&d("hf\\Y", Bhvadi)), K::yuc, &["hAraRA"]); assert_has_krdanta(&[], &nic(&d("Asa~\\", Adadi)), K::yuc, &["AsanA"]); assert_has_krdanta(&[], &nic(&d("SranTa~", Kryadi)), K::yuc, &["SranTanA"]); } diff --git a/vidyut-prakriya/tests/integration/kashika_6_1.rs b/vidyut-prakriya/tests/integration/kashika_6_1.rs index 5a0d867..2cedd61 100644 --- a/vidyut-prakriya/tests/integration/kashika_6_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_6_1.rs @@ -5,10 +5,8 @@ use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; -use vidyut_prakriya::args::Purusha::*; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha::*; -use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::*; lazy_static! { @@ -388,13 +386,13 @@ fn sutra_6_1_28() { #[test] fn sutra_6_1_29() { let pyay = d("o~pyAyI~\\", Bhvadi); - assert_has_tinantas(&["AN"], &pyay, Lit, Prathama, Eka, &["Apipye"]); - assert_has_tinantas(&["AN"], &pyay, Lit, Prathama, Dvi, &["ApipyAte"]); - assert_has_tinantas(&["AN"], &pyay, Lit, Prathama, Bahu, &["Apipyire"]); + assert_has_ta(&["AN"], &pyay, Lit, &["Apipye"]); + assert_has_aataam(&["AN"], &pyay, Lit, &["ApipyAte"]); + assert_has_jha(&["AN"], &pyay, Lit, &["Apipyire"]); // yaNi - assert_has_tinantas(&["AN"], &yan(&pyay), Lat, Prathama, Eka, &["ApepIyate"]); - assert_has_tinantas(&["AN"], &yan(&pyay), Lat, Prathama, Dvi, &["ApepIyete"]); - assert_has_tinantas(&["AN"], &yan(&pyay), Lat, Prathama, Bahu, &["ApepIyante"]); + assert_has_ta(&["AN"], &yan(&pyay), Lat, &["ApepIyate"]); + assert_has_aataam(&["AN"], &yan(&pyay), Lat, &["ApepIyete"]); + assert_has_jha(&["AN"], &yan(&pyay), Lat, &["ApepIyante"]); } #[test] diff --git a/vidyut-prakriya/tests/integration/kashika_6_4.rs b/vidyut-prakriya/tests/integration/kashika_6_4.rs index 9449934..51228cb 100644 --- a/vidyut-prakriya/tests/integration/kashika_6_4.rs +++ b/vidyut-prakriya/tests/integration/kashika_6_4.rs @@ -4,10 +4,8 @@ use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; -use vidyut_prakriya::args::Purusha::*; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha::*; -use vidyut_prakriya::args::Vacana::*; use vidyut_prakriya::args::*; fn assert_has_hi(prefixes: &[&str], d: &Dhatu, expected: &[&str]) { @@ -141,6 +139,14 @@ fn sutra_6_4_12() { assert_has_sup_1p(&bahucchatrin, Napumsaka, &["bahucCatrIRi"]); } +#[test] +fn sutra_6_4_13() { + assert_has_sup_1s("daRqin", Pum, &["daRqI"]); + assert_has_sup_1s("vftrahan", Pum, &["vftrahA"]); + assert_has_sup_1s("pUzan", Pum, &["pUzA"]); + assert_has_sup_1s("aryaman", Pum, &["aryamA"]); +} + #[test] fn sutra_6_4_14() { let bhavat = create_krdanta("Bavat", &[], &d("BA\\", Adadi), Unadi::qavatu); @@ -262,6 +268,29 @@ fn sutra_6_4_21() { assert_has_krdanta(&[], &dhurv, Krt::ktin, &["DUrti"]); } +#[ignore] +#[test] +fn sutra_6_4_22() { + assert_has_sip(&[], &d("asa~", Adadi), Lot, &["eDi", "stAt"]); + assert_has_sip(&[], &d("SAsu~", Adadi), Lot, &["SADi", "SizwAt"]); + + // TODO: AgAhi + assert_has_sip(&[], &d("ha\\na~", Adadi), Lot, &["jahi", "hatAt"]); + + // ABAt? + assert_has_ta_k(&[], &d("Ba\\njo~", Rudhadi), Lun, &["aBAji", "aBaYji"]); + assert_has_krdanta(&[], &d("ra\\nja~^", Bhvadi), Krt::GaY, &["rAga", "raNga"]); + + // atra? + let papivas = krdanta(&[], &d("pA\\", Bhvadi), Krt::kvasu); + let cicyivas = krdanta(&[], &d("ci\\Y", Svadi), Krt::kvasu); + let luluvivas = krdanta(&[], &d("lUY", Kryadi), Krt::kvasu); + assert_has_sup_2p(&papivas, Pum, &["papuzaH"]); + // cikyuzaH also allowed by 7.3.58. + assert_has_sup_2p(&cicyivas, Pum, &["cicyuzaH", "cikyuzaH"]); + assert_has_sup_2p(&luluvivas, Pum, &["luluvuzaH"]); +} + #[test] fn sutra_6_4_23() { assert_has_lat(&[], &d("anjU~", Rudhadi), &["anakti"]); @@ -530,6 +559,13 @@ fn sutra_6_4_38() { assert_has_krdanta(&["pra"], &d("kzaRu~^", Tanadi), Krt::ktvA, &["prakzatya"]); } +#[test] +fn sutra_6_4_39() { + assert_has_krdanta(&[], &d("ya\\ma~", Bhvadi), Krt::ktic, &["yanti"]); + assert_has_krdanta(&[], &d("vanu~\\", Tanadi), Krt::ktic, &["vanti"]); + assert_has_krdanta(&[], &d("tanu~^", Tanadi), Krt::ktic, &["tanti"]); +} + #[test] fn sutra_6_4_40() { let gam = d("ga\\mx~", Bhvadi); @@ -824,9 +860,9 @@ fn sutra_6_4_62() { #[test] fn sutra_6_4_63() { let di = d("dI\\N", Divadi); - assert_has_tinantas(&["upa"], &di, Lit, Prathama, Eka, &["upadidIye"]); - assert_has_tinantas(&["upa"], &di, Lit, Prathama, Dvi, &["upadidIyAte"]); - assert_has_tinantas(&["upa"], &di, Lit, Prathama, Bahu, &["upadidIyire"]); + assert_has_ta(&["upa"], &di, Lit, &["upadidIye"]); + assert_has_aataam(&["upa"], &di, Lit, &["upadidIyAte"]); + assert_has_jha(&["upa"], &di, Lit, &["upadidIyire"]); // aci? assert_has_lat(&["upa"], &yan(&di), &["upadedIyate"]); @@ -993,7 +1029,7 @@ fn sutra_6_4_71() { #[test] fn sutra_6_4_72() { let ikz = d("Ikza~\\", Bhvadi); - let ih = d("Eha~\\", Bhvadi); + let ih = d("Iha~\\", Bhvadi); let ubj = d("ubja~", Tudadi); let umbh = d("unBa~", Tudadi); @@ -1013,6 +1049,49 @@ fn sutra_6_4_72() { assert_has_lrn(&[], &umbh, &["OmBizyat"]); } +#[test] +fn sutra_6_4_74() { + fn assert_has_no_agama( + prefixes: &[&str], + dhatu: &Dhatu, + pada: DhatuPada, + lakara: Lakara, + expected: &[&str], + ) { + use vidyut_prakriya::Vyakarana; + + let args = Tinanta::builder() + .dhatu(dhatu.clone().with_prefixes(prefixes)) + .prayoga(Prayoga::Kartari) + .purusha(Purusha::Prathama) + .vacana(Vacana::Eka) + .lakara(lakara) + .pada(pada) + .skip_at_agama(true) + .build() + .unwrap(); + let t = Tester::new(Vyakarana::new()); + t.assert_has_tinantas(&args, expected); + } + + let assert_has_tip_no_agama = |a, b, c, d| assert_has_no_agama(a, b, DhatuPada::Parasmai, c, d); + let assert_has_ta_no_agama = |a, b, c, d| assert_has_no_agama(a, b, DhatuPada::Atmane, c, d); + + let kf = d("qukf\\Y", Tanadi); + let hf = d("hf\\Y", Bhvadi); + assert_has_tip_no_agama(&[], &kf, Lun, &["kArzIt"]); + assert_has_tip_no_agama(&[], &hf, Lun, &["hArzIt"]); + assert_has_tip_no_agama(&[], &kf, Lan, &["karot"]); + assert_has_tip_no_agama(&[], &hf, Lan, &["harat"]); + + let ikz = d("Ikza~\\", Bhvadi); + let ih = d("Iha~\\", Bhvadi); + assert_has_ta_no_agama(&[], &ih, Lun, &["Ihizwa"]); + assert_has_ta_no_agama(&[], &ikz, Lun, &["Ikzizwa"]); + assert_has_ta_no_agama(&[], &ih, Lan, &["Ihata"]); + assert_has_ta_no_agama(&[], &ikz, Lan, &["Ikzata"]); +} + #[test] fn sutra_6_4_77() { // Snu @@ -1111,9 +1190,9 @@ fn sutra_6_4_80() { #[test] fn sutra_6_4_81() { let i = d("i\\R", Adadi); - assert_has_tinantas(&[], &i, Lat, Prathama, Bahu, &["yanti"]); - assert_has_tinantas(&[], &i, Lot, Prathama, Bahu, &["yantu"]); - assert_has_tinantas(&[], &i, Lan, Prathama, Bahu, &["Ayan"]); + assert_has_jhi(&[], &i, Lat, &["yanti"]); + assert_has_jhi(&[], &i, Lot, &["yantu"]); + assert_has_jhi(&[], &i, Lan, &["Ayan"]); assert_has_krdanta(&[], &i, Krt::lyuw, &["ayana"]); assert_has_krdanta(&[], &i, Krt::Rvul, &["Ayaka"]); } @@ -1567,16 +1646,16 @@ fn sutra_6_4_113() { #[test] fn sutra_6_4_114() { let daridra = d("daridrA", Adadi); - assert_has_tinantas(&[], &daridra, Lat, Prathama, Dvi, &["daridritaH"]); - assert_has_tinantas(&[], &daridra, Lat, Madhyama, Dvi, &["daridriTaH"]); - assert_has_tinantas(&[], &daridra, Lat, Uttama, Dvi, &["daridrivaH"]); - assert_has_tinantas(&[], &daridra, Lat, Uttama, Bahu, &["daridrimaH"]); + assert_has_tas(&[], &daridra, Lat, &["daridritaH"]); + assert_has_thas(&[], &daridra, Lat, &["daridriTaH"]); + assert_has_vas(&[], &daridra, Lat, &["daridrivaH"]); + assert_has_mas(&[], &daridra, Lat, &["daridrimaH"]); // hali - assert_has_tinantas(&[], &daridra, Lat, Prathama, Bahu, &["daridrati"]); + assert_has_jhi(&[], &daridra, Lat, &["daridrati"]); // kNiti - assert_has_tinantas(&[], &daridra, Lat, Prathama, Eka, &["daridrAti"]); + assert_has_tip(&[], &daridra, Lat, &["daridrAti"]); } #[test] @@ -1600,16 +1679,16 @@ fn sutra_6_4_115() { #[test] fn sutra_6_4_116() { let haa = d("o~hA\\k", Juhotyadi); - assert_has_tinantas(&[], &haa, Lat, Prathama, Dvi, &["jahitaH", "jahItaH"]); - assert_has_tinantas(&[], &haa, Lat, Madhyama, Dvi, &["jahiTaH", "jahITaH"]); - assert_has_tinantas(&[], &haa, Lat, Uttama, Dvi, &["jahivaH", "jahIvaH"]); - assert_has_tinantas(&[], &haa, Lat, Uttama, Bahu, &["jahimaH", "jahImaH"]); + assert_has_tas(&[], &haa, Lat, &["jahitaH", "jahItaH"]); + assert_has_thas(&[], &haa, Lat, &["jahiTaH", "jahITaH"]); + assert_has_vas(&[], &haa, Lat, &["jahivaH", "jahIvaH"]); + assert_has_mas(&[], &haa, Lat, &["jahimaH", "jahImaH"]); // hali - assert_has_tinantas(&[], &haa, Lat, Prathama, Bahu, &["jahati"]); + assert_has_jhi(&[], &haa, Lat, &["jahati"]); // kNiti - assert_has_tinantas(&[], &haa, Lat, Prathama, Eka, &["jahAti"]); + assert_has_tip(&[], &haa, Lat, &["jahAti"]); // sArvadhAtuke assert_has_ta_k(&[], &haa, Lat, &["hIyate"]); @@ -1619,12 +1698,10 @@ fn sutra_6_4_116() { #[test] fn sutra_6_4_117() { let haa = d("o~hA\\k", Juhotyadi); - assert_has_tinantas( + assert_has_sip( &[], &haa, Lot, - Madhyama, - Eka, &["jahAhi", "jahihi", "jahIhi", "jahitAt", "jahItAt"], ); } @@ -1632,9 +1709,9 @@ fn sutra_6_4_117() { #[test] fn sutra_6_4_118() { let haa = d("o~hA\\k", Juhotyadi); - assert_has_tinantas(&[], &haa, VidhiLin, Prathama, Eka, &["jahyAt"]); - assert_has_tinantas(&[], &haa, VidhiLin, Prathama, Dvi, &["jahyAtAm"]); - assert_has_tinantas(&[], &haa, VidhiLin, Prathama, Bahu, &["jahyuH"]); + assert_has_tip(&[], &haa, VidhiLin, &["jahyAt"]); + assert_has_tas(&[], &haa, VidhiLin, &["jahyAtAm"]); + assert_has_jhi(&[], &haa, VidhiLin, &["jahyuH"]); } #[test] @@ -1855,14 +1932,18 @@ fn sutra_6_4_130() { #[ignore] #[test] fn sutra_6_4_131() { - assert_has_sup_2p("vidvas", Pum, &["viduzaH"]); - assert_has_sup_3s("vidvas", Pum, &["viduzA"]); - assert_has_sup_4s("vidvas", Pum, &["viduze"]); - - assert_has_sup_2p("pecivas", Pum, &["pecuzaH"]); - assert_has_sup_3s("pecivas", Pum, &["pecuzA"]); - assert_has_sup_4s("pecivas", Pum, &["pecuze"]); - assert_has_sup_6s("papivas", Pum, &["papuzaH"]); + let vidvas = krdanta(&[], &d("vida~", Adadi), Krt::Satf); + assert_has_sup_2p(&vidvas, Pum, &["viduzaH", "vidataH"]); + assert_has_sup_3s(&vidvas, Pum, &["viduzA", "vidatA"]); + assert_has_sup_4s(&vidvas, Pum, &["viduze", "vidate"]); + + let pecivas = krdanta(&[], &d("qupa\\ca~^z", Adadi), Krt::kvasu); + assert_has_sup_2p(&pecivas, Pum, &["pecuzaH"]); + assert_has_sup_3s(&pecivas, Pum, &["pecuzA"]); + assert_has_sup_4s(&pecivas, Pum, &["pecuze"]); + + let papivas = krdanta(&[], &d("pA\\", Bhvadi), Krt::kvasu); + assert_has_sup_2p(&papivas, Pum, &["papuzaH"]); } #[test] diff --git a/vidyut-prakriya/tests/integration/kashika_7_4.rs b/vidyut-prakriya/tests/integration/kashika_7_4.rs index 57a881a..18fb241 100644 --- a/vidyut-prakriya/tests/integration/kashika_7_4.rs +++ b/vidyut-prakriya/tests/integration/kashika_7_4.rs @@ -415,24 +415,28 @@ fn sutra_7_4_33() { assert_has_tip(&[], &kyac(p("mAlA")), Lat, &["mAlIyati"]); } -#[ignore] #[test] fn sutra_7_4_40() { let do_ = d("do\\", Divadi); assert_has_krdanta(&["nis"], &do_, Krt::kta, &["nirdita"]); - assert_has_krdanta(&["nis"], &do_, Krt::ktavatu, &["nirdita"]); + assert_has_krdanta(&["nis"], &do_, Krt::ktavatu, &["nirditavat"]); + let so = d("zo\\", Divadi); assert_has_krdanta(&["ava"], &so, Krt::kta, &["avasita"]); assert_has_krdanta(&["ava"], &so, Krt::ktavatu, &["avasitavat"]); + let maa = d("mA\\", Adadi); assert_has_krdanta(&[], &maa, Krt::kta, &["mita"]); assert_has_krdanta(&[], &maa, Krt::ktavatu, &["mitavat"]); + let stha = d("zWA\\", Bhvadi); assert_has_krdanta(&[], &stha, Krt::kta, &["sTita"]); assert_has_krdanta(&[], &stha, Krt::ktavatu, &["sTitavat"]); - // ti - assert_has_krdanta(&["ava"], &do_, Krt::kta, &["avadAya"]); - // kiti + + // ti? + assert_has_krdanta(&["ava"], &do_, Krt::ktvA, &["avadAya"]); + + // kiti? assert_has_krdanta(&["ava"], &do_, Krt::tfc, &["avadAtf"]); } @@ -524,7 +528,7 @@ fn sutra_7_4_49() { fn sutra_7_4_50() { let kf = d("qukf\\Y", Tanadi); assert_has_tinantas(&[], &kf, Lut, Madhyama, Eka, &["kartAsi", "kartAse"]); - assert_has_tinantas(&[], &d("asa~", Adadi), Lat, Madhyama, Eka, &["asi"]); + assert_has_sip(&[], &d("asa~", Adadi), Lat, &["asi"]); // TODO: vyatise } @@ -533,6 +537,7 @@ fn sutra_7_4_51() { let kf = d("qukf\\Y", Tanadi); assert_has_tinantas(&[], &kf, Lut, Prathama, Dvi, &["kartArO"]); assert_has_tinantas(&[], &kf, Lut, Prathama, Bahu, &["kartAraH"]); + let i = d("i\\N", Adadi); assert_has_tinantas(&["aDi"], &i, Lut, Prathama, Dvi, &["aDyetArO"]); assert_has_tinantas(&["aDi"], &i, Lut, Prathama, Bahu, &["aDyetAraH"]); diff --git a/vidyut-prakriya/tests/integration/kashika_8_2.rs b/vidyut-prakriya/tests/integration/kashika_8_2.rs index 72fa903..14a206d 100644 --- a/vidyut-prakriya/tests/integration/kashika_8_2.rs +++ b/vidyut-prakriya/tests/integration/kashika_8_2.rs @@ -5,8 +5,12 @@ use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::Lakara::*; use vidyut_prakriya::args::Linga::*; use vidyut_prakriya::args::Pada; +use vidyut_prakriya::args::Pratipadika; +use vidyut_prakriya::args::Subanta; use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha; +use vidyut_prakriya::args::Vacana; +use vidyut_prakriya::args::Vibhakti; #[test] fn sutra_8_2_7() { @@ -744,6 +748,58 @@ fn sutra_8_2_60() { assert_has_krdanta(&[], &d("f\\", Juhotyadi), Krt::kta, &["fta", "fRa"]); } +#[test] +fn sutra_8_2_62() { + let ghrtasprk = upapada_krdanta("Gfta", &[], &d("spf\\Sa~", Tudadi), Krt::kvin); + assert_has_sup_1s(&ghrtasprk, Pum, &["Gftaspfk"]); + + let halasprk = upapada_krdanta("hala", &[], &d("spf\\Sa~", Tudadi), Krt::kvin); + assert_has_sup_1s(&halasprk, Pum, &["halaspfk"]); + + let mantrasprk = upapada_krdanta("mantra", &[], &d("spf\\Sa~", Tudadi), Krt::kvin); + assert_has_sup_1s(&mantrasprk, Pum, &["mantraspfk"]); + + // TODO: asrAk, etc. +} + +#[test] +fn sutra_8_2_64() { + use Krt::kvip; + let k = krdanta; + assert_has_sup_1s(k(&["pra"], &d("Samu~", Tudadi), kvip), Pum, &["praSAn"]); + assert_has_sup_1s(k(&["pra"], &d("tamu~", Tudadi), kvip), Pum, &["pratAn"]); + assert_has_sup_1s(k(&["pra"], &d("damu~", Tudadi), kvip), Pum, &["pradAn"]); + + // ma? + assert_has_sup_1s(k(&[], &d("Bi\\di~^r", Rudhadi), kvip), Pum, &["Bit"]); + assert_has_sup_1s(k(&[], &d("Ci\\di~^r", Rudhadi), kvip), Pum, &["Cit"]); + + // dhAtoH? + assert_has_sup_1s("idam", Napumsaka, &["idam"]); + assert_has_sup_1s("kim", Napumsaka, &["kim"]); + + // padasya? + let pratam = k(&["pra"], &d("tamu~", Tudadi), kvip); + assert_has_sup_1d(&pratam, Pum, &["pratAmO"]); + assert_has_sup_1p(&pratam, Pum, &["pratAmaH"]); +} + +#[ignore] +#[test] +fn sutra_8_2_66() { + let pada = Pada::from_text; + assert_has_vakya(&pada("agnis"), &pada("atra"), &["agnir atra"]); + assert_has_vakya(&pada("vAyus"), &pada("atra"), &["vAyur atra"]); + + // TODO: sandhi applied at pada before moving to vakya, which prevents match. + let jush = krdanta(&[], &d("juzI~\\", Tudadi), Krt::kvip); + // HACK: technically "saha", but use "sa" for convenience. + let sajush = bahuvrihi(Pratipadika::basic("sa"), jush); + let sajuh = Subanta::new(&sajush, Stri, Vibhakti::Prathama, Vacana::Eka).into(); + assert_has_vakya(&sajuh, &pada("ftuBis"), &["sajUr ftuBiH"]); + assert_has_vakya(&sajuh, &pada("deveBiH"), &["sajUr deeBiH"]); +} + #[test] fn sutra_8_2_68() { assert_has_sup_3d("ahan", Pum, &["ahoByAm"]); diff --git a/vidyut-prakriya/tests/integration/sanadi_tinantas.rs b/vidyut-prakriya/tests/integration/sanadi_tinantas.rs index fa3f1e4..34a38b5 100644 --- a/vidyut-prakriya/tests/integration/sanadi_tinantas.rs +++ b/vidyut-prakriya/tests/integration/sanadi_tinantas.rs @@ -10,7 +10,7 @@ fn create_sanadyanta(upadesha: &str, gana: &str, sanadi: Sanadi) -> Vec let v = Vyakarana::new(); let gana = gana.parse().expect("ok"); let dhatu = Dhatu::builder() - .upadesha(upadesha) + .aupadeshika(upadesha) .gana(gana) .sanadi(&[sanadi]) .build()