Skip to content

Commit

Permalink
improve support for triggers
Browse files Browse the repository at this point in the history
actually adds trigger parsing support in forall expressions
fixes a bug where empty triggers where generated in the viper code
  • Loading branch information
haaase committed Jul 4, 2023
1 parent 2530067 commit 03fa984
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/main/scala/lore/AST.scala
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ sealed trait TQuantifier extends TBoolean:
def body: Term
case class TForall(
vars: NonEmptyList[TArgT],
triggers: Seq[TViper],
triggers: List[NonEmptyList[Term]],
body: Term,
sourcePos: Option[SourcePos] = None
) extends TQuantifier
Expand Down
6 changes: 4 additions & 2 deletions src/main/scala/lore/Optics.scala
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ given HasChildren[Term] with
case TFalse(sourcePos) => List.empty
case TNeg(body, sourcePos) => List(body)
case TForall(vars, triggers, body, sourcePos) =>
vars.toList ++ triggers.toList :+ body
vars.toList ++ triggers.map(_.toList).flatten :+ body
case TExists(vars, body, sourcePos) => vars.toList :+ body
case TParens(inner, sourcePos) => List(inner)
case TString(value, sourcePos) => List.empty
Expand Down Expand Up @@ -177,7 +177,9 @@ val children: Fold[Term, Term] =
case TInvariant(condition, sourcePos) => f(condition)
case TNeg(body, sourcePos) => f(body)
case TForall(vars, triggers, body, sourcePos) =>
Monoid[M].combineAll((vars.toList ++ triggers.toList :+ body).map(f))
Monoid[M].combineAll(
(vars.toList ++ triggers.map(_.toList).flatten :+ body).map(f)
)
case TExists(vars, body, sourcePos) =>
Monoid[M].combineAll(((vars.toList :+ body).map(f)))
case TParens(inner, sourcePos) => f(inner)
Expand Down
6 changes: 5 additions & 1 deletion src/main/scala/lore/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,11 @@ object Parser:
// quantifiers
val quantifierVars: P[NonEmptyList[TArgT]] =
(argT).repSep(ws.soft ~ P.char(',') ~ wsOrNl)
val triggers: P0[List[TViper]] = P.unit.as(List[TViper]())
val trigger: P[NonEmptyList[Term]] =
P.char('{') ~ wsOrNl *> inSetFactor.repSep(
wsOrNl ~ P.char(',') ~ wsOrNl
) <* wsOrNl ~ P.char('}')
val triggers: P0[List[NonEmptyList[Term]]] = trigger.repSep0(wsOrNl)
val forall: P[TForall] =
withSourcePos(
((P.string("forall") ~ ws *> quantifierVars) <* wsOrNl ~ P.string(
Expand Down
9 changes: 7 additions & 2 deletions src/main/scala/lore/backends/ViperBackend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,15 @@ object ViperBackend:
case f: TForall =>
(
"forall",
s"{${f.triggers.map(expressionToViper).mkString(", ")}}"
f.triggers
.map(x =>
s"{${x.map(expressionToViper).toList.mkString(", ")}}"
)
.mkString(" ")
// s"{${f.triggers.map(expressionToViper).mkString(", ")}}"
)
case e: TExists => ("exists", "")
s"$keyword $varString :: $triggers ${expressionToViper(t.body)}"
s"$keyword $varString ::${if triggers.isEmpty() then "" else " "}$triggers ${expressionToViper(t.body)}"
case t: TNum => t.value.toString
case t: TParens => s"(${expressionToViper(t.inner)})"
case TFunC(
Expand Down

0 comments on commit 03fa984

Please sign in to comment.