From 8e01e35f5db95e5b054394af79b31d4691940f66 Mon Sep 17 00:00:00 2001 From: Arun Prasad Date: Tue, 28 May 2024 19:47:52 -0700 Subject: [PATCH] [prakriya] Fix various UI and prakriya bugs - Fix GitHub issue #113 (UI: add help text) - Fix GitHub issue #114 (add prakriya generation example) - Fix GitHub issue #117 (UI: search by normal dhatu) - Fix GitHub issue #119 (yasya halaH) - Fix GitHub issue #125 (baBUva) - Fix small typos in comments --- vidyut-prakriya/examples/print_prakriyas.rs | 73 ++++++++++++ vidyut-prakriya/src/angasya.rs | 1 - vidyut-prakriya/src/angasya/abhyasasya.rs | 2 +- vidyut-prakriya/src/angasya/asiddhavat.rs | 11 +- vidyut-prakriya/src/vyakarana.rs | 4 +- vidyut-prakriya/src/wasm.rs | 14 +++ vidyut-prakriya/tests/prakriyas.rs | 104 +++++++++++++++++- vidyut-prakriya/tests/regressions.rs | 40 +------ vidyut-prakriya/www/index.html | 2 + .../www/static/vidyut-prakriya-app.js | 64 ++++++----- 10 files changed, 240 insertions(+), 75 deletions(-) create mode 100644 vidyut-prakriya/examples/print_prakriyas.rs diff --git a/vidyut-prakriya/examples/print_prakriyas.rs b/vidyut-prakriya/examples/print_prakriyas.rs new file mode 100644 index 0000000..7a661ae --- /dev/null +++ b/vidyut-prakriya/examples/print_prakriyas.rs @@ -0,0 +1,73 @@ +//! Prints some basic prakriyas. Usage: +//! +//! cargo run --example print_prakriyas +//! +//! In debug mode, prakriyas will also include debug information. To exclude this debug +//! information, build with `--release` instead: +//! +//! cargo run --release --example print_prakriyas +use vidyut_prakriya::args::*; +use vidyut_prakriya::{Prakriya, Vyakarana}; + +/// Prints the `prakriyas` provided. +fn print_prakriyas(prakriyas: &[Prakriya]) { + for p in prakriyas { + // `p.text()` contains the final output. + println!("{}", p.text()); + println!("---------------------------"); + // `p.history()` contains each rule that was applied as well as the rule's results. + for step in p.history() { + // `step.rule().code()` is a string that identifies the rule (e.g. "1.3.1"). + let code = step.rule().code(); + // `step.result()` contains all of the *terms* that are part of this step. These + // include dhatus, agamas, pratyayas, etc. + // + // Here, we create a single string to show all of the results from each term. + let terms: Vec<_> = step + .result() + .iter() + .map(|x| x.text()) + .filter(|x| !x.is_empty()) + .collect(); + let result = terms.join(" + "); + println!("{:<10} | {}", code, result); + } + println!("---------------------------"); + println!("\n"); + } +} + +fn main() { + // For extra options, see `Vyakarana::builder()`. + let v = Vyakarana::new(); + + // Create a basic dhatu with `Dhatu::mula` + // + // For supported dhatus, see `dhatupatha.tsv`. + let bhu = Dhatu::mula("BU", Gana::Bhvadi); + + let args = Tinanta::builder() + .dhatu(bhu) + .lakara(Lakara::Lat) + .prayoga(Prayoga::Kartari) + .purusha(Purusha::Prathama) + .vacana(Vacana::Eka) + .build() + .unwrap(); + let prakriyas = v.derive_tinantas(&args); + print_prakriyas(&prakriyas); + + // Create a sannanta dhatu with `with_sanadi`. + let jijnasa = Dhatu::mula("jYA\\", Gana::Kryadi).with_sanadi(&[Sanadi::san]); + + let args = Tinanta::builder() + .dhatu(jijnasa) + .lakara(Lakara::Lat) + .prayoga(Prayoga::Kartari) + .purusha(Purusha::Prathama) + .vacana(Vacana::Eka) + .build() + .unwrap(); + let prakriyas = v.derive_tinantas(&args); + print_prakriyas(&prakriyas); +} diff --git a/vidyut-prakriya/src/angasya.rs b/vidyut-prakriya/src/angasya.rs index 542bae1..7090824 100644 --- a/vidyut-prakriya/src/angasya.rs +++ b/vidyut-prakriya/src/angasya.rs @@ -55,7 +55,6 @@ fn add_num(t: &mut Term) { /// Runs rules that lengthen a vowel in the anga. fn try_do_dirgha(p: &mut Prakriya, i_anga: usize) -> Option<()> { - p.debug(format!("TRY DO HALAH {i_anga}")); let anga = p.get_if(i_anga, |t| t.is_anga())?; // Also include yAsut-Agama for ji + yAs + t --> jIyAt. // TODO: extend? diff --git a/vidyut-prakriya/src/angasya/abhyasasya.rs b/vidyut-prakriya/src/angasya/abhyasasya.rs index cb96e69..ec75a6c 100644 --- a/vidyut-prakriya/src/angasya/abhyasasya.rs +++ b/vidyut-prakriya/src/angasya/abhyasasya.rs @@ -343,7 +343,7 @@ fn try_rules_for_lit(p: &mut Prakriya, i: usize) -> Option<()> { // // We check gana 1 for `BU` and gana 2 for `as` replaced by `BU`. This check excludes BU // with gana 10. - p.run_at("7.4.73", i, op::text("ba")); + p.run_at("7.4.73", i, op::text("Ba")); // TODO: 7.4.74 } diff --git a/vidyut-prakriya/src/angasya/asiddhavat.rs b/vidyut-prakriya/src/angasya/asiddhavat.rs index 9848ca7..9b8f12e 100644 --- a/vidyut-prakriya/src/angasya/asiddhavat.rs +++ b/vidyut-prakriya/src/angasya/asiddhavat.rs @@ -491,12 +491,11 @@ fn try_ardhadhatuke(p: &mut Prakriya, i: usize) -> Option<()> { p.optional_run_at("6.4.47", i, op::text("Barj")); } else if anga.ends_with("ya") && is_halah(p, i) && !anga.has_u("kyac") { // TODO: why block kyac? SK mentions the "sannipAta-pariBAzA" in 2658 - p.run_at("6.4.49", i, |t| { - t.set_antya(""); - t.set_antya(""); - t.add_tag(T::FlagAtLopa); - }); - } else if has_antya_a_asiddhavat(anga) { + p.run_at("6.4.49", i, |t| t.set_adi("")); + } + + let anga = p.get(i)?; + if has_antya_a_asiddhavat(anga) { p.run_at("6.4.48", i, |t| { t.set_antya(""); t.add_tag(T::FlagAtLopa); diff --git a/vidyut-prakriya/src/vyakarana.rs b/vidyut-prakriya/src/vyakarana.rs index 291abcb..7de74e9 100644 --- a/vidyut-prakriya/src/vyakarana.rs +++ b/vidyut-prakriya/src/vyakarana.rs @@ -378,7 +378,7 @@ impl VyakaranaBuilder { self } - /// *(default: folse)* Controls whether or not to allow rules marked "chandasi," "mantre," etc.. + /// *(default: false)* Controls whether or not to allow rules marked "chandasi," "mantre," etc.. /// /// - If `true`, each `Prakriya` will have access to chAndasa rules. /// @@ -388,7 +388,7 @@ impl VyakaranaBuilder { self } - /// *(default: folse)* Controls whether or not to run svara rules. + /// *(default: false)* Controls whether or not to run svara rules. /// /// - If `true`, each `Prakriya` will have its svaras marked. /// diff --git a/vidyut-prakriya/src/wasm.rs b/vidyut-prakriya/src/wasm.rs index 333b8de..7fc3b96 100644 --- a/vidyut-prakriya/src/wasm.rs +++ b/vidyut-prakriya/src/wasm.rs @@ -247,4 +247,18 @@ impl Vidyut { serde_wasm_bindgen::to_value(&Vec::::new()).expect("wasm") } } + + /// Wrapper for `Vyakarana::derive_dhatus`. + #[allow(non_snake_case)] + pub fn deriveDhatus(&self, code: &str) -> JsValue { + if let Some(dhatu) = self.dhatupatha.get(code) { + let v = Vyakarana::new(); + let prakriyas = v.derive_dhatus(&dhatu); + let web_prakriyas = to_web_prakriyas(&prakriyas); + serde_wasm_bindgen::to_value(&web_prakriyas).expect("wasm") + } else { + error(&format!("[vidyut] Dhatu code not found: {code}")); + serde_wasm_bindgen::to_value(&Vec::::new()).expect("wasm") + } + } } diff --git a/vidyut-prakriya/tests/prakriyas.rs b/vidyut-prakriya/tests/prakriyas.rs index ce61dba..b8d169d 100644 --- a/vidyut-prakriya/tests/prakriyas.rs +++ b/vidyut-prakriya/tests/prakriyas.rs @@ -1,4 +1,4 @@ -//! Tests that verify that a prakriya has a specific format. +//! Tests to verify that a prakriya has a specific format. //! //! TODO: add tests from the पाणिनीयव्याकरणोदाहरणकोषः extern crate test_utils; @@ -7,6 +7,7 @@ use vidyut_prakriya::args::Gana::*; use vidyut_prakriya::args::*; use vidyut_prakriya::Rule; +// Sample test for `Bavati`. #[test] fn bhavati() { let bhu = d("BU", Bhvadi); @@ -36,6 +37,77 @@ fn bhavati() { ); } +/// Fixes https://github.com/ambuda-org/vidyut/issues/118 +/// +/// This test verifies the following: +/// - We correctly apply 6.4.108. +/// - We lengthen the dhatu's vowel with 6.4.2. +#[test] +fn jiyat() { + let jya = d("jyA\\", Kryadi); + let args = Tinanta::builder() + .dhatu(jya) + .prayoga(Prayoga::Kartari) + .purusha(Purusha::Prathama) + .vacana(Vacana::Eka) + .lakara(Lakara::AshirLin) + .build() + .unwrap(); + let t = Tester::default(); + let ps = t.derive_tinantas(&args); + let p = ps.iter().find(|p| p.text() == "jIyAt").unwrap(); + + use Rule::Ashtadhyayi as A; + + assert_matches_prakriya( + p, + &[ + (A("1.3.1"), vec!["jyA\\"]), + (A("3.4.116"), vec!["jyA", "ti"]), + (A("6.1.16"), vec!["jiA", "yAs", "st"]), + (A("6.1.108"), vec!["ji", "yAs", "st"]), + (A("6.4.2"), vec!["jI", "yAs", "st"]), + (A("8.4.56"), vec!["jI", "yA", "t"]), + ], + ); +} + +/// Fixes https://github.com/ambuda-org/vidyut/issues/119 +/// +/// This test verifies the following: +/// - We correctly apply 6.4.49. +#[test] +fn paspardhyate() { + let spardh = d("sparDa~\\", Bhvadi); + let args = Tinanta::builder() + .dhatu(spardh.with_sanadi(&[Sanadi::yaN])) + .prayoga(Prayoga::Karmani) + .purusha(Purusha::Prathama) + .vacana(Vacana::Eka) + .lakara(Lakara::Lat) + .build() + .unwrap(); + let t = Tester::default(); + let ps = t.derive_tinantas(&args); + for p in &ps { + println!("{}", p.text()); + } + let p = ps.iter().find(|p| p.text() == "pAsparDyate").unwrap(); + + use Rule::Ashtadhyayi as A; + + assert_matches_prakriya( + p, + &[ + (A("1.3.1"), vec!["sparDa~\\"]), + (A("1.2.4"), vec!["pA", "sparD", "ya", "ya", "te"]), + (A("6.4.49"), vec!["pA", "sparD", "a", "ya", "te"]), + (A("6.4.48"), vec!["pA", "sparD", "", "ya", "te"]), + (A("8.4.68"), vec!["pA", "sparD", "", "ya", "te"]), + ], + ); +} + // Test to make sure 8.4.1 applies in akzRoti (i.e when R immediately follows r/z) #[test] fn akshnoti() { @@ -77,3 +149,33 @@ fn krinaati() { assert_matches_prakriya(p, &[(A("8.4.2"), vec!["krI", "RA", "ti"])]); } + +// Fixes https://github.com/ambuda-org/vidyut/issues/125 +// +// This test verifies the following: +// - We correctly apply 8.4.54 with 7.4.73 +#[test] +fn babhuva() { + let bhu = d("BU", Bhvadi); + let args = Tinanta::builder() + .dhatu(bhu) + .prayoga(Prayoga::Kartari) + .purusha(Purusha::Prathama) + .vacana(Vacana::Eka) + .lakara(Lakara::Lit) + .build() + .unwrap(); + let t = Tester::default(); + let ps = t.derive_tinantas(&args); + let p = ps.iter().find(|p| p.text() == "baBUva").unwrap(); + + use Rule::Ashtadhyayi as A; + + assert_matches_prakriya( + p, + &[ + (A("7.4.73"), vec!["Ba", "BU", "v", "a"]), + (A("8.4.54"), vec!["ba", "BU", "v", "a"]), + ], + ); +} diff --git a/vidyut-prakriya/tests/regressions.rs b/vidyut-prakriya/tests/regressions.rs index 0a5cc87..4bad3c8 100644 --- a/vidyut-prakriya/tests/regressions.rs +++ b/vidyut-prakriya/tests/regressions.rs @@ -1,4 +1,7 @@ -//! Derivations that aren't captured in our other tests. +//! Bug fixes that aren't captured in other tests. +//! +//! The tests here are responses to bug fixes that users have filed. Each should show that the bug +//! has been fixed and help ensure that the bug does not reappear. extern crate test_utils; use test_utils::*; use vidyut_prakriya::args::Gana::*; @@ -43,38 +46,3 @@ fn irshy_san_lan() { &["Erzyiyizat", "Erzyizizat"], ); } - -/// Fixes https://github.com/ambuda-org/vidyut/issues/118 -/// -/// This test verifies the following: -/// - We correctly apply 6.4.108. -/// - We lengthen the dhatu's vowel with 6.4.2. -#[test] -fn jiyat_prakriya() { - let jya = d("jyA\\", Kryadi); - let args = Tinanta::builder() - .dhatu(jya) - .prayoga(Prayoga::Kartari) - .purusha(Purusha::Prathama) - .vacana(Vacana::Eka) - .lakara(Lakara::AshirLin) - .build() - .unwrap(); - let t = Tester::default(); - let ps = t.derive_tinantas(&args); - let p = ps.iter().find(|p| p.text() == "jIyAt").unwrap(); - - use Rule::Ashtadhyayi as A; - - assert_matches_prakriya( - p, - &[ - (A("1.3.1"), vec!["jyA\\"]), - (A("3.4.116"), vec!["jyA", "ti"]), - (A("6.1.16"), vec!["jiA", "yAs", "st"]), - (A("6.1.108"), vec!["ji", "yAs", "st"]), - (A("6.4.2"), vec!["jI", "yAs", "st"]), - (A("8.4.56"), vec!["jI", "yA", "t"]), - ], - ); -} diff --git a/vidyut-prakriya/www/index.html b/vidyut-prakriya/www/index.html index dc13b10..e8946be 100644 --- a/vidyut-prakriya/www/index.html +++ b/vidyut-prakriya/www/index.html @@ -168,6 +168,8 @@

+

(Click on a pada to see its prakriyā.)

+