Skip to content

Commit

Permalink
check global dv ordering
Browse files Browse the repository at this point in the history
fixes #163
  • Loading branch information
digama0 committed Jul 3, 2024
1 parent 6d16caa commit ae11e6c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 2 deletions.
2 changes: 2 additions & 0 deletions metamath-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ mod parser_tests;
mod usage_tests;
#[cfg(test)]
mod util_tests;
#[cfg(test)]
mod verify_tests;

pub use database::Database;
pub use formula::Formula;
Expand Down
21 changes: 21 additions & 0 deletions metamath-rs/src/nameck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ where
}
}

/// A position in the `dv_info` array.
#[derive(Debug, Copy, Clone)]
pub struct DvId(u32);

// that which we keep in the hash slot for math symbols
#[derive(Default, PartialEq, Eq, Debug, Clone)]
struct SymbolInfo {
Expand Down Expand Up @@ -315,6 +319,23 @@ impl Nameset {
}
}

/// Looks up the list of global $d statements before index `idx`.
#[inline]
#[must_use]
pub fn global_dv_before(&self, idx: DvId) -> &[(StatementAddress, Vec<Atom>)] {
&self.dv_info[..idx.0 as usize]
}

/// Returns the initial position of the global $d index at the start of segment `id`.
#[inline]
#[must_use]
pub fn global_dv_initial(&self, id: SegmentId) -> DvId {
let i = self
.dv_info
.partition_point(|(addr, _)| self.order.lt(&addr.segment_id, &id));
DvId(i as u32)
}

/// Given a name which is known to represent a defined atom, get the atom.
///
/// If you don't know about the name, use [`lookup_symbol`](Self::lookup_symbol) instead.
Expand Down
8 changes: 6 additions & 2 deletions metamath-rs/src/scopeck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

use crate::bit_set::Bitset;
use crate::diag::Diagnostic;
use crate::nameck::{Atom, NameReader, NameUsage, Nameset};
use crate::nameck::{Atom, DvId, NameReader, NameUsage, Nameset};
use crate::segment::{Comparer, Segment, SegmentOrder, SegmentRef};
use crate::segment_set::SegmentSet;
use crate::statement::{
Expand Down Expand Up @@ -267,6 +267,9 @@ struct ScopeState<'a> {
nameset: &'a Nameset,
/// Name reader, tracks labels and math symbols used in this segment.
gnames: NameReader<'a>,
/// Current position in `nameset.dv_info`; global `$d` statements before this index are
/// in effect at this point.
global_dv_pos: DvId,
/// Local `$v` statements in effect at this point.
local_vars: HashMap<Token, Vec<LocalVarInfo>>,
/// Local `$f` statements in effect at this point.
Expand Down Expand Up @@ -609,7 +612,7 @@ fn construct_full_frame<'a>(
// any variables added for DV are not mandatory
iframe.mandatory_count = iframe.var_list.len();

for (_, vars) in state.gnames.lookup_global_dv() {
for (_, vars) in state.nameset.global_dv_before(state.global_dv_pos) {
scan_dv(&mut iframe, vars)
}

Expand Down Expand Up @@ -897,6 +900,7 @@ fn scope_check_single(
order: &sset.order,
nameset: names,
gnames: NameReader::new(names),
global_dv_pos: names.global_dv_initial(seg.id),
local_vars: HashMap::default(),
local_floats: HashMap::default(),
local_dv: Vec::new(),
Expand Down
25 changes: 25 additions & 0 deletions metamath-rs/src/verify_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::grammar_tests::mkdb;

#[test]
fn issue_163() {
const DB: &[u8] = b"
$c term |- R $.
$v x y $.
x-term $f term x $.
y-term $f term y $.
R-any $a |- x R y $.
R-id $p |- x R x $= x-term x-term R-any $.
$( The offending $d may come after multiple declarations $)
$v z $.
z-term $f term z $.
padding-lemma $a |- x R x $.
$d x y $.
";
let mut db = mkdb(DB);

assert!(db.parse_result().parse_diagnostics().is_empty());
assert!(db.verify_pass().diagnostics().is_empty());
}

0 comments on commit ae11e6c

Please sign in to comment.