Skip to content

Commit

Permalink
Work out the ramifications
Browse files Browse the repository at this point in the history
  • Loading branch information
wrsturgeon committed Nov 14, 2023
1 parent a00dcba commit 1a01224
Show file tree
Hide file tree
Showing 15 changed files with 108 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn state_0<I: Iterator<Item = (usize, char)>>(
'('..='(' => {
let detour = state_0(input, (), Some(("parentheses", index)))?;
let postprocessed = (|(), ()| ())(acc, detour);
state_0(input, postprocessed, stack_top)
state_0(input, acc, stack_top)
}
')'..=')' => match stack_top {
Some((region, _)) if region == "parentheses" => Ok(acc),
Expand Down
10 changes: 9 additions & 1 deletion automata/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,15 @@ impl<I: Input, C: Ctrl<I>> Check<I, C> for Transition<I, C> {
#[inline]
fn check(&self, n_states: NonZeroUsize) -> Result<(), IllFormed<I, C>> {
match *self {
Self::Lateral { ref dst, .. } | Self::Call { ref dst, .. } => dst.check(n_states),
Self::Lateral { ref dst, .. } => dst.check(n_states),
Self::Call {
ref detour,
ref dst,
..
} => {
detour.check(n_states)?;
dst.check(n_states)
}
Self::Return { .. } => Ok(()),
}
}
Expand Down
8 changes: 6 additions & 2 deletions automata/src/combinators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,16 @@ fn add_tail_call_transition<I: Input, C: Ctrl<I>>(
Transition::Call {
region,
ref detour,
ref dst,
dst,
combine,
} => Transition::Call {
region,
detour: add_tail_call_c(detour, other_init, accepting_indices),
dst: add_tail_call_c(dst, other_init, accepting_indices),
dst: Box::new(add_tail_call_transition(
*dst,
other_init,
accepting_indices,
)),
combine,
},
Transition::Return { region } => Transition::Return { region },
Expand Down
2 changes: 1 addition & 1 deletion automata/src/generalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl<I: Input, C: Ctrl<I>> Transition<I, C> {
} => Transition::Call {
region,
detour: detour.view().collect(),
dst: dst.view().collect(),
dst: Box::new(dst.generalize()),
combine,
},
Self::Return { region } => Transition::Return { region },
Expand Down
6 changes: 3 additions & 3 deletions automata/src/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,13 @@ fn fix_indices_transition<I: Input, C: Ctrl<I>>(
},
Transition::Call {
region,
detour,
ref detour,
dst,
combine,
} => Transition::Call {
region,
detour: unwrap!(ordering.binary_search(&detour)),
dst: unwrap!(ordering.binary_search(&dst)),
detour: unwrap!(ordering.binary_search(detour)),
dst: Box::new(fix_indices_transition(*dst, ordering)),
combine,
},
Transition::Return { region } => Transition::Return { region },
Expand Down
6 changes: 3 additions & 3 deletions automata/src/in_progress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

//! Execute an automaton on an input sequence.

use crate::{try_merge, Ctrl, Graph, IllFormed, Input, ToSrc};
use crate::{try_merge, Ctrl, Graph, IllFormed, Input, ToSrc, Transition};
use core::fmt;

/// Execute an automaton on an input sequence.
Expand All @@ -17,7 +17,7 @@ pub struct InProgress<'graph, I: Input, C: Ctrl<I>, In: Iterator<Item = I>> {
/// Iterator over input tokens.
pub input: In,
/// Internal stack.
pub stack: Vec<C>,
pub stack: Vec<Transition<I, C>>,
/// Internal state.
pub ctrl: C,
/// Output type as we go.
Expand Down Expand Up @@ -90,7 +90,7 @@ fn step<I: Input, C: Ctrl<I>>(
graph: &Graph<I, C>,
ctrl: &C,
maybe_token: Option<I>,
stack: &mut Vec<C>,
stack: &mut Vec<Transition<I, C>>,
output_t: &str,
) -> Result<(Option<C>, String), ParseError<I, C>> {
ctrl.view().try_fold((), |(), i| {
Expand Down
10 changes: 8 additions & 2 deletions automata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,10 @@ pub fn dyck_d() -> Deterministic<char> {
Transition::Call {
region: "parentheses",
detour: 0,
dst: 0,
dst: Box::new(Transition::Lateral {
dst: 0,
update: None,
}),
combine: ff!(|(), ()| ()),
},
),
Expand Down Expand Up @@ -269,7 +272,10 @@ pub fn dyck_nd() -> Nondeterministic<char> {
Transition::Call {
region: "parentheses",
detour: iter::once(0).collect(),
dst: iter::once(0).collect(),
dst: Box::new(Transition::Lateral {
dst: iter::once(0).collect(),
update: None,
}),
combine: ff!(|(), ()| ()),
},
),
Expand Down
2 changes: 1 addition & 1 deletion automata/src/map_indices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl<I: Input, C: Ctrl<I>> Transition<I, C> {
} => Self::Call {
region,
detour: detour.map_indices(&mut f),
dst: dst.map_indices(f),
dst: Box::new(dst.map_indices(f)),
combine,
},
Self::Return { region } => Self::Return { region },
Expand Down
4 changes: 1 addition & 3 deletions automata/src/merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,7 @@ impl<I: Input, C: Ctrl<I>> Merge for Transition<I, C> {
detour: l_detour
.merge(r_detour)
.map_err(|(a, b)| IllFormed::Superposition(a, b))?,
dst: l_dst
.merge(r_dst)
.map_err(|(a, b)| IllFormed::Superposition(a, b))?,
dst: Box::new(l_dst.merge(*r_dst)?),
combine: l_combine.merge(r_combine).map_err(|(a, b)| {
IllFormed::IncompatibleCombinators(Box::new(a), Box::new(b))
})?,
Expand Down
48 changes: 22 additions & 26 deletions automata/src/qc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,37 +152,33 @@ shrink_only!(|self: &Curry| match *self {

shrink_only!(|self: &Transition| {
#[allow(clippy::shadow_unrelated, unreachable_code, unused_variables)]
match self.clone() {
Self::Return { region: _ } => Box::new(iter::empty()),
Self::Lateral { dst, update } => Box::new(
match *self {
Self::Return { .. } => Box::new(iter::empty()),
Self::Lateral {
ref dst,
ref update,
} => Box::new(
iter::once(Self::Return { region: "region" }).chain(
(dst, update)
(dst.clone(), update.clone())
.shrink()
.map(|(dst, update)| Self::Lateral { dst, update }),
),
),
Self::Call {
region: _,
detour,
dst,
combine,
} => {
Box::new(
Self::Lateral {
dst: dst.clone(),
update: None,
}
.shrink()
.chain((detour, dst, combine).shrink().map(
|(detour, dst, combine)| Self::Call {
region: "region",
detour,
dst,
combine,
},
)),
)
}
ref detour,
ref dst,
ref combine,
..
} => Box::new(dst.as_ref().shrink().chain(
(detour.clone(), dst.clone(), combine.clone()).shrink().map(
|(detour, dst, combine)| Self::Call {
region: "region",
detour,
dst,
combine,
},
),
)),
}
});

Expand Down Expand Up @@ -255,7 +251,7 @@ impl<C: Ctrl<u8>> Transition<u8, C> {
|n, r| Self::Call {
region: "region",
detour: C::arbitrary_given(n, r),
dst: C::arbitrary_given(n, r),
dst: Box::new(Transition::arbitrary_given(n, r)),
combine: Arbitrary::arbitrary(r),
},
|_, _| Self::Return { region: "region" },
Expand Down
2 changes: 1 addition & 1 deletion automata/src/reindex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl<I: Input, C: Ctrl<I>> Transition<I, C> {
} => Self::Call {
region,
detour: detour.clone().map_indices(update_fn),
dst: dst.clone().map_indices(update_fn),
dst: Box::new(dst.clone().map_indices(update_fn)),
combine: combine.clone(),
},
Self::Return { region } => Self::Return { region },
Expand Down
18 changes: 16 additions & 2 deletions automata/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,14 @@ mod prop {
};
star.accept(input).is_ok()
}

fn star_star_identity(d: Deterministic<u8>, input: Vec<u8>) -> bool {
let Ok(once) = panic::catch_unwind(|| d.star()) else {
return true;
};
let twice = once.clone().star();
once.accept(input.iter().copied()) == twice.accept(input)
}
}
}

Expand Down Expand Up @@ -506,7 +514,10 @@ mod reduced {
transitions: Curry::Wildcard(Transition::Call {
region: "region",
detour: 0,
dst: 1,
dst: Box::new(Transition::Lateral {
dst: 1,
update: None,
}),
combine: FF {
src: "|(), ()| ()".to_owned(),
lhs_t: "()".to_owned(),
Expand Down Expand Up @@ -662,7 +673,10 @@ mod reduced {
transitions: Curry::Wildcard(Transition::Call {
region: "region",
detour: 0,
dst: 0,
dst: Box::new(Transition::Lateral {
dst: 0,
update: None,
}),
combine: ff!(|(), ()| ()),
}),
non_accepting: BTreeSet::new(),
Expand Down
16 changes: 10 additions & 6 deletions automata/src/to_src.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,9 @@ impl<I: Input> Curry<I, usize> {
match *self {
Self::Wildcard(ref etc) => format!(
r#"
_ => {},"#,
_ => {{
{}
}}"#,
etc.to_src(),
),
Self::Scrutinize {
Expand All @@ -318,7 +320,9 @@ impl<I: Input> RangeMap<I, usize> {
self.0.iter().fold(String::new(), |acc, (k, v)| {
format!(
r#"{acc}
{} => {},"#,
{} => {{
{}
}},"#,
k.to_src(),
v.to_src(),
)
Expand All @@ -342,15 +346,15 @@ impl<I: Input> Transition<I, usize> {
Self::Call {
region,
detour,
dst,
ref dst,
combine: FF { ref src, .. },
} => format!(
r#"{{
"\
let detour = state_{detour}(input, (), Some(({}, index)))?;
let postprocessed = ({src})(acc, detour);
state_{dst}(input, postprocessed, stack_top)
}}"#,
{}",
region.to_src(),
dst.to_src(),
),
Self::Return { region } => {
format!(
Expand Down
24 changes: 14 additions & 10 deletions automata/src/transition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! Transition in an automaton: an action and a destination state.

use crate::{Ctrl, Input, InputError, Merge, ParseError, Update, FF};
use core::{cmp, mem};
use core::{cmp, iter, mem};
use std::collections::BTreeSet;

// TODO: rename `Call` to `Open` and `Return` to `Close`
Expand Down Expand Up @@ -137,7 +137,7 @@ impl<I: Input, C: Ctrl<I>> Transition<I, C> {
pub fn invoke(
&self,
output_t: &str,
stack: &mut Vec<C>,
stack: &mut Vec<Transition<I, C>>,
) -> Result<Option<(C, String)>, ParseError<I, C>> {
match *self {
Self::Lateral {
Expand All @@ -156,14 +156,17 @@ impl<I: Input, C: Ctrl<I>> Transition<I, C> {
ref dst,
..
} => {
stack.push(dst.clone());
stack.push(*dst.clone());
Ok(Some((detour.clone(), "()".to_owned())))
}
Self::Return { .. } => {
let rtn_to = stack
.pop()
.ok_or(ParseError::BadInput(InputError::Unopened))?;
Ok(Some((rtn_to, output_t.to_owned())))
// Ok(Some((rtn_to, output_t.to_owned())))
// No longer strictly small-step semantics,
// but the alternative is a nightmare
rtn_to.invoke(output_t, stack)
}
}
}
Expand All @@ -185,15 +188,15 @@ impl<I: Input, C: Ctrl<I>> Transition<I, C> {
/// For returns, it's nothing.
#[inline]
#[must_use]
pub fn dsts(&self) -> Vec<&C> {
pub fn dsts(&self) -> BTreeSet<&C> {
match *self {
Self::Lateral { ref dst, .. } => vec![dst],
Self::Lateral { ref dst, .. } => iter::once(dst).collect(),
Self::Call {
ref detour,
ref dst,
..
} => vec![detour, dst],
Self::Return { .. } => vec![],
} => iter::once(detour).chain(dst.dsts()).collect(),
Self::Return { .. } => BTreeSet::new(),
}
}

Expand Down Expand Up @@ -227,7 +230,7 @@ impl<I: Input> Transition<I, usize> {
} => Transition::Call {
region,
detour: C::from_usize(detour),
dst: C::from_usize(dst),
dst: Box::new(dst.convert_ctrl()),
combine,
},
Self::Return { region } => Transition::Return { region },
Expand All @@ -241,11 +244,12 @@ impl<I: Input> Transition<I, BTreeSet<usize>> {
#[allow(clippy::missing_panics_doc)]
pub fn star(&mut self, init: &BTreeSet<usize>, accepting: &BTreeSet<usize>) {
match *self {
Transition::Lateral { ref mut dst, .. } | Transition::Call { ref mut dst, .. } => {
Transition::Lateral { ref mut dst, .. } => {
if dst.iter().any(|i| accepting.contains(i)) {
*dst = unwrap!(mem::take(dst).merge(init.clone()));
}
}
Transition::Call { ref mut dst, .. } => dst.star(init, accepting),
Transition::Return { .. } => {}
}
}
Expand Down
Loading

0 comments on commit 1a01224

Please sign in to comment.