Skip to content

Commit

Permalink
add by inverses
Browse files Browse the repository at this point in the history
  • Loading branch information
kaikalii committed Jun 12, 2024
1 parent 0ce3026 commit 26d5299
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 6 deletions.
42 changes: 38 additions & 4 deletions src/algorithm/invert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use ecow::{eco_vec, EcoString, EcoVec};
use regex::Regex;

use crate::{
check::{instrs_signature, instrs_signature_no_temp},
check::{instrs_clean_signature, instrs_signature, instrs_signature_no_temp},
primitive::{ImplPrimitive, Primitive},
Assembly, BindingKind, Compiler, FmtInstrs, Function, FunctionId, Instr, Signature, Span,
SysOp, TempStack, Uiua, UiuaResult, Value,
Expand Down Expand Up @@ -1349,7 +1349,41 @@ fn invert_temp_pattern<'a>(
comp: &mut Compiler,
) -> Option<(&'a [Instr], EcoVec<Instr>)> {
// Push temp
if let Some((input, instr, inner, end_instr, _)) = try_push_temp_wrap(input) {
if let Some((input, instr, inner, end_instr, depth)) = try_push_temp_wrap(input) {
// By-inverse
if let [Instr::Prim(Primitive::Dup, dup_span)] = inner {
for len in 1..=input.len() {
for mid in 0..len {
let before = &input[..mid];
if instrs_clean_signature(before).map_or(true, |sig| sig != (0, 0)) {
continue;
};
let instrs = &input[mid..len];
let Some(sig) = instrs_clean_signature(instrs) else {
continue;
};
if sig.args != depth + 1 {
continue;
}
for pat in ON_INVERT_PATTERNS {
if let Some((after, on_inv)) = pat.invert_extract(instrs, comp) {
if after.is_empty() {
let mut instrs = eco_vec![
instr.clone(),
Instr::Prim(Primitive::Dup, *dup_span),
end_instr.clone(),
Instr::Prim(Primitive::Flip, *dup_span),
];
instrs.extend(on_inv);
instrs.extend_from_slice(before);
return Some((&input[len..], instrs));
}
}
}
}
}
}
// Normal inverse
let mut instrs = invert_instrs(inner, comp)?;
instrs.insert(0, instr.clone());
instrs.push(end_instr.clone());
Expand All @@ -1369,7 +1403,7 @@ fn invert_temp_pattern<'a>(
continue;
}
for pat in ON_INVERT_PATTERNS {
if let Some((after, pseudo_inv)) = pat.invert_extract(after, comp) {
if let Some((after, on_inv)) = pat.invert_extract(after, comp) {
if let Some(after_inv) = invert_instrs(after, comp) {
let mut instrs = eco_vec![start_instr.clone()];

Expand All @@ -1385,7 +1419,7 @@ fn invert_temp_pattern<'a>(

instrs.extend_from_slice(before);

instrs.extend(pseudo_inv);
instrs.extend(on_inv);

instrs.push(end_instr.clone());
return Some((input, instrs));
Expand Down
10 changes: 10 additions & 0 deletions src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ pub(crate) fn instrs_signature(instrs: &[Instr]) -> Result<Signature, SigCheckEr
Ok(env.sig())
}

/// The the signature of some instructions, but only
/// if the temp stack signatures are `|0.0`
pub(crate) fn instrs_clean_signature(instrs: &[Instr]) -> Option<Signature> {
let (sig, temps) = instrs_all_signatures(instrs).ok()?;
if temps.iter().any(|&sig| sig != (0, 0)) {
return None;
}
Some(sig)
}

pub(crate) fn instrs_temp_signatures(
instrs: &[Instr],
) -> Result<[Signature; TempStack::CARDINALITY], SigCheckError> {
Expand Down
7 changes: 6 additions & 1 deletion tests/units.ua
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ F ← +@A ⊟.
⍤⟜≍: 3 °°+ 1 2
⍤⟜≍: 3 °°°°°°+ 1 2

# Pseudo inverses
# On-inverses
⍤⟜≍: [3 2] [°⟜+ 3 5]
⍤⟜≍: [3 2] [°⟜× 3 6]
⍤⟜≍: [3 8] [°⟜- 3 5]
Expand All @@ -420,6 +420,11 @@ F ← +@A ⊟.
⍤⟜≍: [3 5] [°⟜↥ 3 5]
⍤⟜≍: [1_2 3_4] [°⟜⊂ 1_2 1_2_3_4]

# By-inverses
⍤⟜≍: [3 5] [°⊸+ 8 5]
⍤⟜≍: [3 5] [°⊸× 15 5]
⍤⟜≍: [3 5] [°⊸(+?) 8 5]

F ← ×2+1

⍤⟜≍: [1 4] [°⟜(F+) ⟜(F+) 1 4]
Expand Down
1 change: 0 additions & 1 deletion todo.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Uiua Todo

- 0.12
- by inverses
- `setinv` on and by inverses
- Document on and by inverses
- Pervasive switch functions and `repeat`
Expand Down

0 comments on commit 26d5299

Please sign in to comment.