Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
41c3365
Add Isar mode to VerCors
Nov 17, 2025
66cfec3
add Isabelle type syntax to types pretty printer
Dec 10, 2025
b4870b6
add foldr to Doc
Dec 10, 2025
719af09
implement pretty printing of ADT as locale
Dec 10, 2025
9c109c6
fix locale declaration syntax error
Dec 10, 2025
e58b4b5
fix more issue with locale syntax
Dec 10, 2025
18f9035
implement basic binder syntax
Dec 10, 2025
f02ad1e
implement logical operators synta
Dec 10, 2025
95531e4
fix locale layout issues with fixes and asssumes
Dec 11, 2025
580ea11
setup Isar output and required transformation passes
superaxander Dec 11, 2025
5758891
only print the ADT when working in Isar mode
Dec 11, 2025
e00d208
[fix][Isar] only print the name of a variable and not its type
Dec 11, 2025
1964900
correctly print functions that are defined outside of an ADT
Dec 11, 2025
2e3778f
implement Isar printng for PVL functions and syntax
Dec 11, 2025
67f7dc9
implement isar output for rational division
Dec 19, 2025
77f73da
prelude: import rational numbers and add a type for references
Dec 19, 2025
91e2bf1
literal syntax fixes
Dec 19, 2025
7836a36
translate PVL sizes functions to be of type int in place of nat
Dec 19, 2025
783f197
use nice <--> binder in place of = when comparing booleans
Dec 19, 2025
4d9bb00
typo
Dec 19, 2025
614f4b4
fixes map constructor syntax and lookup translation
Dec 19, 2025
5fb2759
uses HOL implication instead of meta-implication
Dec 19, 2025
dc6e8a0
typo: oopsie
Dec 19, 2025
f50ce67
[fix] conversion to Isabelle/HOL tuples, range not inclusive
Jan 11, 2026
7a7c324
[isar] output of trigger should be optional
Jan 11, 2026
69df41e
implement conditional layout of triggers
Jan 26, 2026
f40b10e
[fix] correctly typeset constants
Jan 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/col/vct/col/ast/declaration/adt/ADTAxiomImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ trait ADTAxiomImpl[G] extends ADTAxiomOps[G] {
override def layout(implicit ctx: Ctx): Doc =
ctx.syntax match {
case Ctx.Silver => Group(Text("axiom") <+> "{" <>> axiom.show <+/> "}")
case Ctx.Isar => Group(Text("assumes") <>> Text("\"") <> axiom.show <> Text("\""))
case _ => Text("axiom") <+> axiom <> ";"
}
}
6 changes: 6 additions & 0 deletions src/col/vct/col/ast/declaration/adt/ADTFunctionImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ trait ADTFunctionImpl[G]
this: ADTFunction[G] =>
override def body: Option[Node[G]] = None

def layoutIsar(implicit ctx: Ctx) : Doc = {
Group(
Text("fixes") <+> Text(ctx.name(this)) <+> Text("::") <+> Text("\"") <> Doc.foldr(args.map(_.t) :+ returnType)(_ <+> "⇒" <+> _) <> Text("\"")
)
}
override def layout(implicit ctx: Ctx): Doc =
ctx.syntax match {
case Ctx.Silver =>
Group(
Text("function") <+> ctx.name(this) <> "(" <> Doc.args(args) <>
"):" <+> returnType
)
case Ctx.Isar => layoutIsar
case _ =>
Group(
Text("pure") <+> returnType <+> ctx.name(this) <> "(" <>
Expand Down
18 changes: 18 additions & 0 deletions src/col/vct/col/ast/declaration/global/AxiomaticDataTypeImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ trait AxiomaticDataTypeImpl[G]
this: AxiomaticDataType[G] =>
override def declarations: Seq[Declaration[G]] = decls ++ typeArgs

def layoutIsar(implicit ctx: Ctx): Doc = {
Group(
Group(
Text("typedecl") <+>
(if (typeArgs.nonEmpty)
Text("(") <> Doc.args(typeArgs.map(Text("'") <> _.show)) <>
Text(")")
else
Empty) <+> ctx.name(this)
) <+/> Group(
Text("locale") <+> ctx.name(this) <> "_signature" <+>
(if (decls.isEmpty) { Empty }
else { Text(" =") <>> Doc.stack(decls) }) <+/> "begin" <+/> "end"
)
)
}

def layoutSilver(implicit ctx: Ctx): Doc =
Group(
Text("domain") <+> ctx.name(this) <>
Expand All @@ -31,6 +48,7 @@ trait AxiomaticDataTypeImpl[G]
override def layout(implicit ctx: Ctx): Doc =
ctx.syntax match {
case Ctx.Silver => layoutSilver
case Ctx.Isar => layoutIsar
case _ => Doc.spec(Show.lazily(layoutSpec(_)))
}
}
1 change: 1 addition & 0 deletions src/col/vct/col/ast/declaration/global/FunctionImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ trait FunctionImpl[G]
override def layout(implicit ctx: Ctx): Doc =
ctx.syntax match {
case Ctx.Silver => layoutSilver
case Ctx.Isar => Empty
case _ => Doc.spec(Show.lazily(layoutSpec(_)))
}
}
1 change: 1 addition & 0 deletions src/col/vct/col/ast/declaration/global/ProcedureImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ trait ProcedureImpl[G] extends ProcedureOps[G] {
case Ctx.Silver => layoutSilver
case Ctx.C | Ctx.Cuda | Ctx.OpenCL | Ctx.CPP => layoutC
case Ctx.PVL | Ctx.Java => Doc.spec(Show.lazily(layoutSpec(_)))
case Ctx.Isar => Empty
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ trait VariableImpl[G] extends VariableOps[G] with VariableFamilyOps[G] {
case Ctx.C | Ctx.Cuda | Ctx.OpenCL | Ctx.CPP =>
val (spec, decl) = t.layoutSplitDeclarator
spec <+> decl <> ctx.name(this)
case Ctx.Isar => Text(ctx.name(this))
case Ctx.PVL | Ctx.Java => t.show <+> ctx.name(this)
case Ctx.Silver => Text(ctx.name(this)) <> ":" <+> t
}
Expand Down
10 changes: 10 additions & 0 deletions src/col/vct/col/ast/expr/apply/ADTFunctionInvocationImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,20 @@ trait ADTFunctionInvocationImpl[G] extends ADTFunctionInvocationOps[G] {
def layoutSilver(implicit ctx: Ctx): Doc =
Group(Text(ctx.name(ref)) <> "(" <> Doc.args(args) <> ")")

def layoutIsar(implicit ctx: Ctx): Doc =
Group(
(if (args.nonEmpty)
Text("(") <> Text(ctx.name(ref)) <+> Doc.spread(args) <> ")"
else
Text(ctx.name(ref))
)
)

override def precedence: Int = Precedence.POSTFIX
override def layout(implicit ctx: Ctx): Doc =
ctx.syntax match {
case Ctx.Silver => layoutSilver
case Ctx.Isar => layoutIsar
case _ => layoutSpec
}
}
7 changes: 7 additions & 0 deletions src/col/vct/col/ast/expr/apply/FunctionInvocationImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@ trait FunctionInvocationImpl[G] extends FunctionInvocationOps[G] {
) <> Doc.args(args) <> ")" <> DocUtil.givenYields(givenMap, yields)
)

def layoutIsar(implicit ctx: Ctx): Doc =
Group((if (args.nonEmpty)
Text("(") <> Text(ctx.name(ref)) <+> Doc.spread(args) <> ")"
else
Text(ctx.name(ref))))

override def precedence: Int = Precedence.POSTFIX
override def layout(implicit ctx: Ctx): Doc =
ctx.syntax match {
case Ctx.Silver => layoutSilver
case Ctx.Isar => layoutIsar
case _ => layoutSpec
}

Expand Down
6 changes: 6 additions & 0 deletions src/col/vct/col/ast/expr/binder/ExistsImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@ trait ExistsImpl[G] extends ExistsOps[G] {
layoutTriggers <>> body </> ")"
)

def layoutIsar(implicit ctx : Ctx): Doc =
Group(
Text("∃") <+> Doc.spread(bindings) <+> "." <+> body
)

override def precedence: Int = Precedence.ATOMIC
override def layout(implicit ctx: Ctx): Doc =
ctx.syntax match {
case Ctx.Silver => layoutSilver
case Ctx.Isar => layoutIsar
case _ => layoutSpec
}
}
6 changes: 6 additions & 0 deletions src/col/vct/col/ast/expr/binder/ForallImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@ trait ForallImpl[G] extends ForallOps[G] {
layoutTriggers <>> body </> ")"
)

def layoutIsar(implicit ctx : Ctx): Doc =
Group(
Text("∀") <+> Doc.spread(bindings) <+> "." <+> body
)

override def precedence: Int = Precedence.ATOMIC
override def layout(implicit ctx: Ctx): Doc =
ctx.syntax match {
case Ctx.Silver => layoutSilver
case Ctx.Isar => layoutIsar
case _ => layoutSpec
}
}
6 changes: 6 additions & 0 deletions src/col/vct/col/ast/expr/binder/LetImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@ trait LetImpl[G] extends LetOps[G] {
")" <+> "in" <>> main </> ")"
)

def layoutIsar(implicit ctx : Ctx): Doc =
Group(
Text("(") <> Text("let") <+> ctx.name(binding) <+> "=" <+> value <+> "in" <>> main <> Text(")")
)

override def precedence: Int = Precedence.ATOMIC
override def layout(implicit ctx: Ctx): Doc =
ctx.syntax match {
case Ctx.Silver => layoutSilver
case Ctx.Isar => layoutIsar
case _ => layoutSpec
}
}
7 changes: 6 additions & 1 deletion src/col/vct/col/ast/expr/literal/build/EitherLeftImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,10 @@ trait EitherLeftImpl[G] extends EitherLeftOps[G] {
override def t: Type[G] = TEither(e.t, TNothing())

override def precedence: Int = Precedence.ATOMIC
override def layout(implicit ctx: Ctx): Doc = Text("Left(") <> e <> ")"
override def layout(implicit ctx: Ctx): Doc = {
ctx.syntax match {
case Ctx.Isar => Text("Inl") <+> e
case _ => Text("Left(") <> e <> ")"
}
}
}
7 changes: 6 additions & 1 deletion src/col/vct/col/ast/expr/literal/build/EitherRightImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,10 @@ trait EitherRightImpl[G] extends EitherRightOps[G] {
override def t: Type[G] = TEither(TNothing(), e.t)

override def precedence: Int = Precedence.ATOMIC
override def layout(implicit ctx: Ctx): Doc = Text("Right(") <> e <> ")"
override def layout(implicit ctx: Ctx): Doc = {
ctx.syntax match {
case Ctx.Isar => Text("Inr") <+> e
case _ => Text("Right(") <> e <> ")"
}
}
}
11 changes: 9 additions & 2 deletions src/col/vct/col/ast/expr/literal/build/LiteralBagImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ trait LiteralBagImpl[G] extends LiteralBagOps[G] {
override def t: Type[G] = TBag(element)

override def precedence: Int = Precedence.POSTFIX
override def layout(implicit ctx: Ctx): Doc =
Group(Text("bag<") <> element <> ">{" <> Doc.args(values) <> "}")
override def layout(implicit ctx: Ctx): Doc = {
ctx.syntax match {
case Ctx.Isar =>
if (values.isEmpty) { Group(Text("{#}")) }
else { Group(Text("{#") <+> Doc.args(values) <+> Text("#}")) }
case _ =>
Group(Text("bag<") <> element <> ">{" <> Doc.args(values) <> "}")
}
}
}
20 changes: 19 additions & 1 deletion src/col/vct/col/ast/expr/literal/build/LiteralMapImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,26 @@ trait LiteralMapImpl[G] extends LiteralMapOps[G] {
override def t: Type[G] = TMap(k, v)

override def precedence: Int = Precedence.POSTFIX
override def layout(implicit ctx: Ctx): Doc =

def layoutIsar(implicit ctx: Ctx): Doc = {
if (values.isEmpty) { Group(Text("Map.empty")) }
else {
Group(Text("[") <+> Doc.args(values.map { case (k, v) =>
k.show <+> "↦" <+> v
}) <+> Text("]"))
}
}

def layoutPvl(implicit ctx: Ctx): Doc =
Group(Text("map<") <> k <> "," <+> v <> ">{" <> Doc.args(values.map {
case (k, v) => k.show <+> "->" <+> v
}) <> "}")

override def layout(implicit ctx: Ctx): Doc = {
ctx.syntax match {
case Ctx.Isar => layoutIsar
case _ => layoutPvl
}

}
}
11 changes: 9 additions & 2 deletions src/col/vct/col/ast/expr/literal/build/LiteralSeqImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ trait LiteralSeqImpl[G] extends LiteralSeqOps[G] {
override def t: Type[G] = TSeq(element)

override def precedence: Int = Precedence.POSTFIX
override def layout(implicit ctx: Ctx): Doc =
Group(Text("seq<") <> element <> ">{" <> Doc.args(values) <> "}")
override def layout(implicit ctx: Ctx): Doc = {
ctx.syntax match {
case Ctx.Isar =>
if (values.isEmpty) { Group(Text("[]")) }
else { Group(Text("[") <> Doc.args(values) <> Text(")")) }
case _ =>
Group(Text("seq<") <> element <> ">{" <> Doc.args(values) <> "}")
}
}
}
12 changes: 10 additions & 2 deletions src/col/vct/col/ast/expr/literal/build/LiteralSetImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ trait LiteralSetImpl[G] extends LiteralSetOps[G] {
override def t: Type[G] = TSet(element)

override def precedence: Int = Precedence.POSTFIX
override def layout(implicit ctx: Ctx): Doc =
Group(Text("set<") <> element <> ">{" <> Doc.args(values) <> "}")
override def layout(implicit ctx: Ctx): Doc = {
ctx.syntax match {
case Ctx.Isar =>
if (values.isEmpty) { Group(Text("{}")) }
else { Group(Text("{") <> Doc.args(values) <> "}") }
case _ =>
Group(Text("set<") <> element <> ">{" <> Doc.args(values) <> "}")
}

}
}
10 changes: 8 additions & 2 deletions src/col/vct/col/ast/expr/literal/build/LiteralTupleImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ trait LiteralTupleImpl[G] extends ExprImpl[G] with LiteralTupleOps[G] {
else { Seq(TupleTypeCount(this)) }

override def precedence: Int = Precedence.POSTFIX
override def layout(implicit ctx: Ctx): Doc =
Group(Text("tuple<") <> Doc.args(ts) <> ">{" <> Doc.args(values) <> "}")
override def layout(implicit ctx: Ctx): Doc = {
ctx.syntax match {
case Ctx.Isar => Group(Text("(") <> "," <> Doc.args(values) <> Text(")"))
case _ =>
Group(Text("tuple<") <> Doc.args(ts) <> ">{" <> Doc.args(values) <> "}")
}

}
}
8 changes: 7 additions & 1 deletion src/col/vct/col/ast/expr/literal/build/OptSomeImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@ trait OptSomeImpl[G] extends OptSomeOps[G] {
override def t: Type[G] = TOption(e.t)

override def precedence: Int = Precedence.POSTFIX
override def layout(implicit ctx: Ctx): Doc = Text("Some(") <> e <> ")"
override def layout(implicit ctx: Ctx): Doc = {
ctx.syntax match {
case Ctx.Isar => Text("(Some") <+> e <> ")"
case _ => Text("Some(") <> e <> ")"
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@ trait OptSomeTypedImpl[G] extends OptSomeTypedOps[G] {
override def t: Type[G] = TOption(element)

override def precedence: Int = Precedence.POSTFIX
override def layout(implicit ctx: Ctx): Doc = Text("Some(") <> e <> ")"
override def layout(implicit ctx: Ctx): Doc = {
ctx.syntax match {
case Ctx.Isar => Text("(Some ") <> e <> ")"
case _ => Text("Some(") <> e <> ")"
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ trait UntypedLiteralBagImpl[G] extends UntypedLiteralBagOps[G] {
override def t: Type[G] = TBag(elementType)

override def precedence: Int = Precedence.ATOMIC
override def layout(implicit ctx: Ctx): Doc =
Group(Text("b{") <> Doc.args(values) <> "}")
override def layout(implicit ctx: Ctx): Doc = {
ctx.syntax match {
case Ctx.Isar => Group(Text("{#") <+> Doc.args(values) <+> Text("#}"))
case _ => Group(Text("b{") <> Doc.args(values) <> "}")
}
}
}
16 changes: 15 additions & 1 deletion src/col/vct/col/ast/expr/literal/constant/BooleanValueImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,26 @@ trait BooleanValueImpl[G] extends BooleanValueOps[G] {
SharedLayoutElement('e'),
)
override def precedence: Int = Precedence.ATOMIC
override def layout(implicit ctx: Ctx): Doc =
def layoutDefault(implicit ctx: Ctx) =
Text(
orderedLayoutFixture.collect {
case e @ SharedLayoutElement(_) => e;
case e @ DedicatedLayoutElement(r, _) if r.toString == value.toString =>
e
}.map(_.textualData).mkString("")
)

def layoutIsar(implicit ctx: Ctx) =
if (value)
Text("True")
else
Text("False")

override def layout(implicit ctx: Ctx): Doc = {
ctx.syntax match {
case Ctx.Isar => layoutIsar
case _ => layoutDefault
}

}
}
6 changes: 5 additions & 1 deletion src/col/vct/col/ast/expr/literal/constant/NoPermImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ trait NoPermImpl[G] extends NoPermOps[G] {
override def t: Type[G] = TBoundedInt(0, 1)

override def precedence: Int = Precedence.ATOMIC
override def layout(implicit ctx: Ctx): Doc = Text("none")
override def layout(implicit ctx: Ctx): Doc =
ctx.syntax match {
case Ctx.Isar => Text("0")
case _ => Text("none")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ trait WritePermImpl[G] extends WritePermOps[G] {
override def t: Type[G] = TBoundedInt(1, 2)

override def precedence: Int = Precedence.ATOMIC
override def layout(implicit ctx: Ctx): Doc = Text("write")
override def layout(implicit ctx: Ctx): Doc =
ctx.syntax match {
case Ctx.Isar => Text("1")
case _ => Text("write")
}
}
Loading