Skip to content

Commit 26d5299

Browse files
committed
add by inverses
1 parent 0ce3026 commit 26d5299

File tree

4 files changed

+54
-6
lines changed

4 files changed

+54
-6
lines changed

src/algorithm/invert.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use ecow::{eco_vec, EcoString, EcoVec};
1111
use regex::Regex;
1212

1313
use crate::{
14-
check::{instrs_signature, instrs_signature_no_temp},
14+
check::{instrs_clean_signature, instrs_signature, instrs_signature_no_temp},
1515
primitive::{ImplPrimitive, Primitive},
1616
Assembly, BindingKind, Compiler, FmtInstrs, Function, FunctionId, Instr, Signature, Span,
1717
SysOp, TempStack, Uiua, UiuaResult, Value,
@@ -1349,7 +1349,41 @@ fn invert_temp_pattern<'a>(
13491349
comp: &mut Compiler,
13501350
) -> Option<(&'a [Instr], EcoVec<Instr>)> {
13511351
// Push temp
1352-
if let Some((input, instr, inner, end_instr, _)) = try_push_temp_wrap(input) {
1352+
if let Some((input, instr, inner, end_instr, depth)) = try_push_temp_wrap(input) {
1353+
// By-inverse
1354+
if let [Instr::Prim(Primitive::Dup, dup_span)] = inner {
1355+
for len in 1..=input.len() {
1356+
for mid in 0..len {
1357+
let before = &input[..mid];
1358+
if instrs_clean_signature(before).map_or(true, |sig| sig != (0, 0)) {
1359+
continue;
1360+
};
1361+
let instrs = &input[mid..len];
1362+
let Some(sig) = instrs_clean_signature(instrs) else {
1363+
continue;
1364+
};
1365+
if sig.args != depth + 1 {
1366+
continue;
1367+
}
1368+
for pat in ON_INVERT_PATTERNS {
1369+
if let Some((after, on_inv)) = pat.invert_extract(instrs, comp) {
1370+
if after.is_empty() {
1371+
let mut instrs = eco_vec![
1372+
instr.clone(),
1373+
Instr::Prim(Primitive::Dup, *dup_span),
1374+
end_instr.clone(),
1375+
Instr::Prim(Primitive::Flip, *dup_span),
1376+
];
1377+
instrs.extend(on_inv);
1378+
instrs.extend_from_slice(before);
1379+
return Some((&input[len..], instrs));
1380+
}
1381+
}
1382+
}
1383+
}
1384+
}
1385+
}
1386+
// Normal inverse
13531387
let mut instrs = invert_instrs(inner, comp)?;
13541388
instrs.insert(0, instr.clone());
13551389
instrs.push(end_instr.clone());
@@ -1369,7 +1403,7 @@ fn invert_temp_pattern<'a>(
13691403
continue;
13701404
}
13711405
for pat in ON_INVERT_PATTERNS {
1372-
if let Some((after, pseudo_inv)) = pat.invert_extract(after, comp) {
1406+
if let Some((after, on_inv)) = pat.invert_extract(after, comp) {
13731407
if let Some(after_inv) = invert_instrs(after, comp) {
13741408
let mut instrs = eco_vec![start_instr.clone()];
13751409

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

13861420
instrs.extend_from_slice(before);
13871421

1388-
instrs.extend(pseudo_inv);
1422+
instrs.extend(on_inv);
13891423

13901424
instrs.push(end_instr.clone());
13911425
return Some((input, instrs));

src/check.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ pub(crate) fn instrs_signature(instrs: &[Instr]) -> Result<Signature, SigCheckEr
3434
Ok(env.sig())
3535
}
3636

37+
/// The the signature of some instructions, but only
38+
/// if the temp stack signatures are `|0.0`
39+
pub(crate) fn instrs_clean_signature(instrs: &[Instr]) -> Option<Signature> {
40+
let (sig, temps) = instrs_all_signatures(instrs).ok()?;
41+
if temps.iter().any(|&sig| sig != (0, 0)) {
42+
return None;
43+
}
44+
Some(sig)
45+
}
46+
3747
pub(crate) fn instrs_temp_signatures(
3848
instrs: &[Instr],
3949
) -> Result<[Signature; TempStack::CARDINALITY], SigCheckError> {

tests/units.ua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ F ← +@A ⊟.
410410
⍤⟜≍: 3 °°+ 1 2
411411
⍤⟜≍: 3 °°°°°°+ 1 2
412412

413-
# Pseudo inverses
413+
# On-inverses
414414
⍤⟜≍: [3 2] [°⟜+ 3 5]
415415
⍤⟜≍: [3 2] [°⟜× 3 6]
416416
⍤⟜≍: [3 8] [°⟜- 3 5]
@@ -420,6 +420,11 @@ F ← +@A ⊟.
420420
⍤⟜≍: [3 5] [°⟜↥ 3 5]
421421
⍤⟜≍: [1_2 3_4] [°⟜⊂ 1_2 1_2_3_4]
422422

423+
# By-inverses
424+
⍤⟜≍: [3 5] [°⊸+ 8 5]
425+
⍤⟜≍: [3 5] [°⊸× 15 5]
426+
⍤⟜≍: [3 5] [°⊸(+?) 8 5]
427+
423428
F ← ×2+1
424429

425430
⍤⟜≍: [1 4] [°⟜(F+) ⟜(F+) 1 4]

todo.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Uiua Todo
22

33
- 0.12
4-
- by inverses
54
- `setinv` on and by inverses
65
- Document on and by inverses
76
- Pervasive switch functions and `repeat`

0 commit comments

Comments
 (0)