Skip to content

Commit 298b8e8

Browse files
committed
Parse existentials
1 parent 323d0e0 commit 298b8e8

File tree

2 files changed

+127
-4
lines changed

2 files changed

+127
-4
lines changed

src/annot.rs

Lines changed: 123 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_ast::token::{BinOpToken, Delimiter, LitKind, Token, TokenKind};
1212
use rustc_ast::tokenstream::{RefTokenTreeCursor, Spacing, TokenStream, TokenTree};
1313
use rustc_index::IndexVec;
1414
use rustc_span::symbol::Ident;
15+
use std::collections::HashMap;
1516

1617
use crate::chc;
1718
use crate::pretty::PrettyDisplayExt as _;
@@ -185,6 +186,7 @@ impl<T> FormulaOrTerm<T> {
185186
struct Parser<'a, T> {
186187
resolver: T,
187188
cursor: RefTokenTreeCursor<'a>,
189+
formula_existentials: HashMap<String, chc::Sort>,
188190
}
189191

190192
impl<'a, T> Parser<'a, T>
@@ -232,6 +234,15 @@ where
232234
}
233235
}
234236

237+
fn expect_next_ident(&mut self) -> Result<Ident> {
238+
let t = self.next_token("ident")?;
239+
if let Some((ident, _)) = t.ident() {
240+
Ok(ident)
241+
} else {
242+
Err(ParseAttrError::unexpected_token("ident", t.clone()))
243+
}
244+
}
245+
235246
fn consume(&mut self) {
236247
self.cursor.next().unwrap();
237248
}
@@ -296,6 +307,7 @@ where
296307
let mut parser = Parser {
297308
resolver: self.boxed_resolver(),
298309
cursor: s.trees(),
310+
formula_existentials: self.formula_existentials.clone(),
299311
};
300312
let formula_or_term = parser.parse_formula_or_term_or_tuple()?;
301313
parser.end_of_input()?;
@@ -305,9 +317,17 @@ where
305317
};
306318

307319
let formula_or_term = if let Some((ident, _)) = t.ident() {
308-
match ident.as_str() {
309-
"true" => FormulaOrTerm::Formula(chc::Formula::top()),
310-
"false" => FormulaOrTerm::Formula(chc::Formula::bottom()),
320+
match (
321+
ident.as_str(),
322+
self.formula_existentials.get(ident.name.as_str()),
323+
) {
324+
("true", _) => FormulaOrTerm::Formula(chc::Formula::top()),
325+
("false", _) => FormulaOrTerm::Formula(chc::Formula::bottom()),
326+
(_, Some(sort)) => {
327+
let var =
328+
chc::Term::FormulaExistentialVar(sort.clone(), ident.name.to_string());
329+
FormulaOrTerm::Term(var, sort.clone())
330+
}
311331
_ => {
312332
let (v, sort) = self.resolve(ident)?;
313333
FormulaOrTerm::Term(chc::Term::var(v), sort)
@@ -575,8 +595,102 @@ where
575595
Ok(formula_or_term)
576596
}
577597

598+
fn parse_exists(&mut self) -> Result<FormulaOrTerm<T::Output>> {
599+
match self.look_ahead_token(0) {
600+
Some(Token {
601+
kind: TokenKind::Ident(sym, _),
602+
..
603+
}) if sym.as_str() == "exists" => {
604+
self.consume();
605+
let mut vars = Vec::new();
606+
loop {
607+
let ident = self.expect_next_ident()?;
608+
self.expect_next_token(TokenKind::Colon, ":")?;
609+
let sort = self.parse_sort()?;
610+
vars.push((ident.name.to_string(), sort));
611+
match self.next_token(". or ,")? {
612+
Token {
613+
kind: TokenKind::Comma,
614+
..
615+
} => {}
616+
Token {
617+
kind: TokenKind::Dot,
618+
..
619+
} => break,
620+
t => return Err(ParseAttrError::unexpected_token("., or ,", t.clone())),
621+
}
622+
}
623+
self.formula_existentials.extend(vars.iter().cloned());
624+
let formula = self
625+
.parse_formula_or_term()?
626+
.into_formula()
627+
.ok_or_else(|| ParseAttrError::unexpected_term("in exists formula"))?;
628+
for (name, _) in &vars {
629+
self.formula_existentials.remove(name);
630+
}
631+
return Ok(FormulaOrTerm::Formula(chc::Formula::exists(vars, formula)));
632+
}
633+
_ => self.parse_binop_5(),
634+
}
635+
}
636+
578637
fn parse_formula_or_term(&mut self) -> Result<FormulaOrTerm<T::Output>> {
579-
self.parse_binop_5()
638+
self.parse_exists()
639+
}
640+
641+
fn parse_sort(&mut self) -> Result<chc::Sort> {
642+
let tt = self.next_token_tree("sort")?.clone();
643+
match tt {
644+
TokenTree::Token(
645+
Token {
646+
kind: TokenKind::Ident(sym, _),
647+
..
648+
},
649+
_,
650+
) => {
651+
let sort = match sym.as_str() {
652+
"bool" => chc::Sort::bool(),
653+
"int" => chc::Sort::int(),
654+
"string" => unimplemented!(),
655+
"null" => chc::Sort::null(),
656+
"fn" => unimplemented!(),
657+
_ => unimplemented!(),
658+
};
659+
Ok(sort)
660+
}
661+
//TokenTree::Token(
662+
// Token {
663+
// kind: TokenKind::Gt,
664+
// ..
665+
// },
666+
// _,
667+
//) => {
668+
//}
669+
TokenTree::Delimited(_, _, Delimiter::Parenthesis, ts) => {
670+
let mut parser = Parser {
671+
resolver: self.boxed_resolver(),
672+
cursor: ts.trees(),
673+
formula_existentials: self.formula_existentials.clone(),
674+
};
675+
let mut sorts = Vec::new();
676+
loop {
677+
sorts.push(parser.parse_sort()?);
678+
match parser.look_ahead_token(0) {
679+
Some(Token {
680+
kind: TokenKind::Comma,
681+
..
682+
}) => {
683+
parser.consume();
684+
}
685+
None => break,
686+
Some(t) => return Err(ParseAttrError::unexpected_token(",", t.clone())),
687+
}
688+
}
689+
parser.end_of_input()?;
690+
Ok(chc::Sort::tuple(sorts).into())
691+
}
692+
t => Err(ParseAttrError::unexpected_token_tree("sort", t.clone())),
693+
}
580694
}
581695

582696
fn parse_ty(&mut self) -> Result<rty::Type<T::Output>> {
@@ -662,6 +776,7 @@ where
662776
let mut parser = Parser {
663777
resolver: self.boxed_resolver(),
664778
cursor: ts.trees(),
779+
formula_existentials: self.formula_existentials.clone(),
665780
};
666781
let mut rtys = Vec::new();
667782
loop {
@@ -697,6 +812,7 @@ where
697812
let mut parser = Parser {
698813
resolver: self.boxed_resolver(),
699814
cursor: ts.trees(),
815+
formula_existentials: self.formula_existentials.clone(),
700816
};
701817
let self_ident = if matches!(
702818
parser.look_ahead_token(1),
@@ -720,6 +836,7 @@ where
720836
let mut parser = Parser {
721837
resolver: RefinementResolver::new(self.boxed_resolver()),
722838
cursor: parser.cursor,
839+
formula_existentials: self.formula_existentials.clone(),
723840
};
724841
if let Some(self_ident) = self_ident {
725842
parser.resolver.set_self(self_ident, ty.to_sort());
@@ -859,6 +976,7 @@ where
859976
let mut parser = Parser {
860977
resolver: &self.resolver,
861978
cursor: ts.trees(),
979+
formula_existentials: Default::default(),
862980
};
863981
let rty = parser.parse_rty()?;
864982
parser.end_of_input()?;
@@ -869,6 +987,7 @@ where
869987
let mut parser = Parser {
870988
resolver: &self.resolver,
871989
cursor: ts.trees(),
990+
formula_existentials: Default::default(),
872991
};
873992
let formula = parser.parse_annot_formula()?;
874993
parser.end_of_input()?;

src/chc.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,10 @@ impl<V> Formula<V> {
12281228
}
12291229
}
12301230

1231+
pub fn exists(vars: Vec<(String, Sort)>, body: Self) -> Self {
1232+
Formula::Exists(vars, Box::new(body))
1233+
}
1234+
12311235
pub fn subst_var<F, W>(self, f: F) -> Formula<W>
12321236
where
12331237
F: FnMut(V) -> Term<W>,

0 commit comments

Comments
 (0)