Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VeyMont: parameterization syntax & AST changes #1281

Draft
wants to merge 44 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
645ed31
STart implementing assuming, asserting
bobismijnnaam Nov 7, 2024
36b9467
Assuming/asserting seems to work
bobismijnnaam Nov 8, 2024
ebc310d
Add spec/tests for assuming/asserting
bobismijnnaam Nov 8, 2024
5e241b0
Initial datatype sketch for parameterized veymont
bobismijnnaam Nov 8, 2024
1e0369f
More initial draft suff
bobismijnnaam Nov 8, 2024
2994a57
Make progress on syntax & ast changes
bobismijnnaam Nov 19, 2024
6ea3d61
Improve parser general error message
bobismijnnaam Nov 20, 2024
1388686
Start integrating the pvl endpoint family nodes
bobismijnnaam Nov 20, 2024
af2ea3e
Enable endpoint ranges in endpoint exprs
bobismijnnaam Nov 20, 2024
8ab0c9d
Start working on subscript operation for endpoint families
bobismijnnaam Nov 20, 2024
c13d809
AmbiguousSubscript now knows about EndpointFamilies
bobismijnnaam Nov 21, 2024
0507248
Next up, teaching scopes about rangedbinder. also, maybe check for un…
bobismijnnaam Nov 21, 2024
392fa50
Tie PVLEndpoint into Endpoint
bobismijnnaam Nov 22, 2024
dedbbef
Make progress towards tying PVLCommunicate into core col
bobismijnnaam Nov 22, 2024
e9561b8
forgot some files
bobismijnnaam Nov 22, 2024
287390c
Nice progress on refactoring towards (PVL)CommunicateTarget et al."
bobismijnnaam Nov 26, 2024
c9a4acb
Commit before doing InferEndpointContexts refactor
bobismijnnaam Nov 26, 2024
a7ce7d0
Outline how we will move away from EndpointName, and instead reuse Co…
bobismijnnaam Nov 26, 2024
23089c5
Before StratifyUnpointed refactor
bobismijnnaam Nov 27, 2024
0ff72ed
Finish full integration of CommunicateTarget migration
bobismijnnaam Nov 27, 2024
9401d0e
Not sure why it is failing now
bobismijnnaam Nov 27, 2024
d722c64
Add TraceOrigin. Get almost the entire technical veymont test suite w…
bobismijnnaam Dec 10, 2024
7ba053f
Revert changes to add asserting/assuming expressions. This is now imp…
bobismijnnaam Dec 10, 2024
f6ab8ab
Add reformat commits from me, philip
bobismijnnaam Dec 10, 2024
fde1216
Get started on intersect
bobismijnnaam Dec 11, 2024
19bbf72
Making progress on endpoint projection
bobismijnnaam Dec 12, 2024
ec820f1
Branch unanimity is closed to finished
bobismijnnaam Dec 13, 2024
44c2442
Started working on the simplified (though less user-friendly) version…
bobismijnnaam Dec 18, 2024
3ea5010
First run of branch unanimity works
bobismijnnaam Dec 19, 2024
b2bd9bf
Need to handle rangebinder properly in stratifyunpointedexpressions
bobismijnnaam Dec 19, 2024
76969dc
Fix some scoping bugs
bobismijnnaam Dec 20, 2024
661c2fc
Reach the choreography encoding pass
bobismijnnaam Dec 20, 2024
163776b
Finally do something about prettyprinting. Also add endpoint expressi…
bobismijnnaam Dec 20, 2024
80546e2
Refactor t to be more clearly named
bobismijnnaam Dec 20, 2024
f82ebb2
Starting with encoding endpoint families!
bobismijnnaam Dec 20, 2024
b977a93
Refactor EncodeChoreography to use scopes in a smart way instead of o…
bobismijnnaam Mar 4, 2025
e36e4d3
Generate endpoint bounds
bobismijnnaam Mar 5, 2025
be93f08
Ensure loop invariants for endpoint family construction are generated
bobismijnnaam Mar 5, 2025
9c6a209
Ensure --choreography really only does choreographic verification
bobismijnnaam Mar 5, 2025
56523ab
Make range binder leaking work
bobismijnnaam Mar 5, 2025
0b3406e
Add colprinter. start hotfixing communicate
bobismijnnaam Mar 6, 2025
a534c87
Make headway in generating generalized endpoint inequalities
bobismijnnaam Mar 6, 2025
eebdfed
Move exit_code_success out
bobismijnnaam Mar 6, 2025
0df6591
Add identity case (even though it's probably not necessary, let's kee…
bobismijnnaam Mar 6, 2025
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
6 changes: 6 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@
# Date: Tue May 28 19:06:33 2024 +0200
# reformat scala sources
7a81a51d7791bc2e407fcfc6aef24bc1d1a52850

# Bob Rubbens: wanted to merge some stuff in after reformatting
fecd37bf5922332cc449f0ef95f79b09f370aa8e

# Bob Rubbens: (I think the same happened to Philip Tasche)
97fb61d23cf04a909145ecb28946d1297d947ef4
1 change: 1 addition & 0 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ object vercors extends Module {
}
override def generatedSources = T { Seq(helpers.sources()) }
override def moduleDeps = Seq(hre, serialize)
override def ivyDeps = Agg(ivy"com.lihaoyi::sourcecode:0.4.2")

object test extends Tests
}
Expand Down
118 changes: 73 additions & 45 deletions src/col/vct/col/ast/Node.scala
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,6 @@ final case class TEnum[G](enum: Ref[G, Enum[G]])(
final case class TProverType[G](ref: Ref[G, ProverType[G]])(
implicit val o: Origin = DiagnosticOrigin
) extends DeclaredType[G] with TProverTypeImpl[G]
final case class TVeyMontChannel[G](channelType: String)(
implicit val o: Origin = DiagnosticOrigin
) extends DeclaredType[G] with TVeyMontChannelImpl[G]

@family
sealed trait ParRegion[G] extends NodeFamily[G] with ParRegionImpl[G]
Expand Down Expand Up @@ -294,6 +291,7 @@ final case class CatchClause[G](decl: Variable[G], body: Statement[G])(
implicit val o: Origin
) extends NodeFamily[G] with CatchClauseImpl[G]

// TODO (RR): Unify with RangeBinder...!
@family
final case class IterVariable[G](
variable: Variable[G],
Expand Down Expand Up @@ -3777,19 +3775,25 @@ final case class TChoreography[G](cls: Ref[G, Choreography[G]])(
final case class TPVLChoreography[G](cls: Ref[G, PVLChoreography[G]])(
implicit val o: Origin = DiagnosticOrigin
) extends DeclaredType[G] with TPVLChoreographyImpl[G]
final case class TEndpoint[G](cls: Ref[G, Endpoint[G]])(
implicit val o: Origin = DiagnosticOrigin
) extends DeclaredType[G] with TEndpointImpl[G]

@scopes[Variable]
final class PVLEndpoint[G](
val name: String,
val range: Option[RangeBinder[G]],
val cls: Ref[G, Class[G]],
val typeArgs: Seq[Type[G]],
val args: Seq[Expr[G]],
)(val blame: Blame[InvocationFailure])(implicit val o: Origin)
extends ClassDeclaration[G] with PVLEndpointImpl[G] {
extends ClassDeclaration[G] with PVLEndpointImpl[G] with Declarator[G] {
var ref: Option[PVLConstructorTarget[G]] = None
}
@family
final case class RangeBinder[G](
binder: Variable[G],
low: Expr[G],
high: Expr[G],
)(implicit val o: Origin)
extends NodeFamily[G] with RangeBinderImpl[G]
final class PVLChoreography[G](
val name: String,
val declarations: Seq[ClassDeclaration[G]],
Expand All @@ -3803,11 +3807,33 @@ final class PVLChorRun[G](
)(val blame: Blame[ChorRunFailure])(implicit val o: Origin)
extends ClassDeclaration[G] with PVLChorRunImpl[G]

// Represents naming a specific endpoint, or a subrange of endpoints. Used in endpoint expressions, communicate statements to indicate sender/receiver,
// and in communicate statements to indicate sender/receiver inline in the message/destination location.
/* TODO (RR): It's annoying here that we both use PVLLocal to refer to endpoint names, as well as the dedicated
PVLEndpointName in the case where it's syntactically clear it's an endpoint...
*/
@family
case class PVLEndpointName[G](name: String)(implicit val o: Origin)
extends PVLEndpointNameImpl[G] with NodeFamily[G] {
sealed trait PVLCommunicateTarget[G]
extends NodeFamily[G] with PVLCommunicateTargetImpl[G]
final case class PVLCommTargetEndpoint[G](name: String)(implicit val o: Origin)
extends PVLCommTargetEndpointImpl[G] with PVLCommunicateTarget[G] {
var ref: Option[RefPVLEndpoint[G]] = None
}
final case class PVLCommTargetIndex[G](name: String, index: Expr[G])(
implicit val o: Origin
) extends PVLCommTargetIndexImpl[G] with PVLCommunicateTarget[G] {
var ref: Option[RefPVLEndpoint[G]] = None
}
final case class PVLCommTargetRange[G](name: String, range: RangeBinder[G])(
implicit val o: Origin
) extends PVLCommunicateTarget[G] with PVLCommTargetRangeImpl[G] {
var ref: Option[RefPVLEndpoint[G]] = None
}
// Adapter node to also put endpoint naming inline in an expression, for communicate statements.
// Only necessary for the pvlEndpointsRange rule in the PVL grammar
case class PVLCommTargetExpr[G](set: PVLCommunicateTarget[G])(
implicit val o: Origin
) extends Expr[G] with PVLCommTargetExprImpl[G]

// Resolution of invariant can depend on communicate's target/msg through \sender, \receiver, \msg. Therefore, definitions are nested like this,
// to ensure that PVLCommunicate is fully resolved before the invariant is typechecked.
Expand All @@ -3817,24 +3843,25 @@ final case class PVLCommunicateStatement[G](
inv: Option[Expr[G]],
)(implicit val o: Origin)
extends Statement[G] with PVLCommunicateStatementImpl[G]
@family
@family @scopes[Variable]
final class PVLCommunicate[G](
val receiver: Option[PVLEndpointName[G]],
val receiver: Option[PVLCommunicateTarget[G]],
val target: Expr[G],
val sender: Option[PVLEndpointName[G]],
val sender: Option[PVLCommunicateTarget[G]],
val msg: Expr[G],
)(val blame: Blame[PVLCommunicateFailure])(implicit val o: Origin)
extends Declaration[G] with PVLCommunicateImpl[G] {
var inferredSender: Option[PVLEndpoint[G]] = None
var inferredReceiver: Option[PVLEndpoint[G]] = None
var inferredSender: Option[PVLCommunicateTarget[G]] = None
var inferredReceiver: Option[PVLCommunicateTarget[G]] = None
}
@scopes[Variable]
final case class PVLEndpointStatement[G](
endpoint: Option[PVLEndpointName[G]],
endpoint: Option[PVLCommunicateTarget[G]],
inner: Statement[G],
)(val blame: Blame[ChorStatementFailure])(implicit val o: Origin)
extends Statement[G] with PVLEndpointStatementImpl[G]
final case class PVLChorPerm[G](
endpoint: PVLEndpointName[G],
endpoint: PVLCommunicateTarget[G],
loc: Location[G],
perm: Expr[G],
)(implicit val o: Origin)
Expand All @@ -3852,13 +3879,14 @@ final case class PVLMessage[G]()(implicit val o: Origin)
var ref: Option[PVLCommunicateStatement[G]] = None
}

@family
@family @scopes[Variable]
final class Endpoint[G](
val range: Option[RangeBinder[G]],
val cls: Ref[G, Class[G]],
val typeArgs: Seq[Type[G]],
val init: Expr[G],
)(implicit val o: Origin)
extends Declaration[G] with EndpointImpl[G]
extends Declaration[G] with EndpointImpl[G] with Declarator[G]
@scopes[Endpoint]
@scopes[Variable]
final class Choreography[G](
Expand All @@ -3880,20 +3908,35 @@ final case class ChorRun[G](
@family
final class Communicate[G](
val invariant: Expr[G],
val receiver: Option[Ref[G, Endpoint[G]]],
val target: Expr[G],
val sender: Option[Ref[G, Endpoint[G]]],
val receiver: Option[CommunicateTarget[G]],
val destination: Expr[G],
val sender: Option[CommunicateTarget[G]],
val msg: Expr[G],
)(val blame: Blame[CommunicateFailure])(implicit val o: Origin)
extends Declaration[G] with CommunicateImpl[G]
extends CommunicateImpl[G] with Declaration[G]
@scopes[Communicate]
final case class CommunicateStatement[G](inner: Communicate[G])(
implicit val o: Origin
) extends PurelySequentialStatement[G] with CommunicateStatementImpl[G]

final case class EndpointName[G](ref: Ref[G, Endpoint[G]])(
@family
sealed trait CommunicateTarget[G]
extends NodeFamily[G] with CommunicateTargetImpl[G]
case class CommTargetEndpoint[G](ref: Ref[G, Endpoint[G]])(
implicit val o: Origin
) extends CommunicateTarget[G] with CommTargetEndpointImpl[G]
case class CommTargetRange[G](ref: Ref[G, Endpoint[G]], range: RangeBinder[G])(
implicit val o: Origin
) extends CommunicateTarget[G] with CommTargetRangeImpl[G]
case class CommTargetIndex[G](ref: Ref[G, Endpoint[G]], index: Expr[G])(
implicit val o: Origin
) extends CommunicateTarget[G] with CommTargetIndexImpl[G]

final case class CtExpr[G](inner: CommunicateTarget[G])(implicit val o: Origin)
extends Expr[G] with CtExprImpl[G]
final case class EndpointFamilyExpr[G](ref: Ref[G, Endpoint[G]])(
implicit val o: Origin
) extends Expr[G] with EndpointNameImpl[G]
) extends Expr[G] with EndpointFamilyExprImpl[G]
final case class Sender[G](ref: Ref[G, Communicate[G]])(implicit val o: Origin)
extends Expr[G] with SenderImpl[G]
final case class Receiver[G](ref: Ref[G, Communicate[G]])(
Expand All @@ -3906,40 +3949,25 @@ final case class ChorStatement[G](inner: Statement[G])(
val blame: Blame[ChorStatementFailure]
)(implicit val o: Origin)
extends Statement[G] with ChorStatementImpl[G]
@scopes[Variable]
final case class EndpointStatement[G](
endpoint: Option[Ref[G, Endpoint[G]]],
endpoint: Option[CommunicateTarget[G]],
inner: Statement[G],
)(val blame: Blame[ChorStatementFailure])(implicit val o: Origin)
extends Statement[G] with EndpointStatementImpl[G]

final case class PVLEndpointExpr[G](
endpoint: PVLEndpointName[G],
endpoint: PVLCommunicateTarget[G],
expr: Expr[G],
)(implicit val o: Origin)
extends Expr[G] with PVLEndpointExprImpl[G]
final case class EndpointExpr[G](endpoint: Ref[G, Endpoint[G]], expr: Expr[G])(
extends Expr[G] with PVLEndpointExprImpl[G] with Declarator[G]
@scopes[Variable]
final case class EndpointExpr[G](endpoint: CommunicateTarget[G], expr: Expr[G])(
implicit val o: Origin
) extends Expr[G] with EndpointExprImpl[G]
final case class ChorExpr[G](expr: Expr[G])(implicit val o: Origin)
extends Expr[G] with ChorExprImpl[G]

final case class VeyMontAssignExpression[G](
endpoint: Ref[G, Endpoint[G]],
assign: Statement[G],
)(implicit val o: Origin)
extends Statement[G]
with ControlContainerStatement[G]
with VeyMontAssignExpressionImpl[G]
final case class CommunicateX[G](
receiver: Ref[G, Endpoint[G]],
sender: Ref[G, Endpoint[G]],
chanType: Type[G],
assign: Statement[G],
)(implicit val o: Origin)
extends Statement[G]
with ControlContainerStatement[G]
with CommunicateXImpl[G]

sealed trait SilverExpr[G] extends Expr[G] with SilverExprImpl[G]
final case class SilverDeref[G](obj: Expr[G], field: Ref[G, SilverField[G]])(
val blame: Blame[InsufficientPermission]
Expand Down
30 changes: 25 additions & 5 deletions src/col/vct/col/ast/declaration/global/ChoreographyImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import vct.col.ast.{
ChorStatement,
Choreography,
Class,
CommunicateTarget,
Declaration,
Endpoint,
EndpointName,
EndpointStatement,
Node,
}
Expand All @@ -21,13 +21,33 @@ import vct.col.ref.Ref
import scala.collection.immutable.ListSet
import vct.col.ast.ops.ChoreographyOps
import vct.col.util.AstBuildHelpers.tt
import vct.col.util.AstMatchHelpers.{EndpointIndex, EndpointName, EndpointRange}
import vct.result.VerificationError.UserError

object ChoreographyImpl {
case class OnlySingleEndpointsSupported(node: Node[_]) extends UserError {
override def code: String = "onlySingleEndpointsSupported"
override def text: String =
node.o.messageInContext(
"Only singular endpoint definitions are supported for permission generation"
)
}

// This method is _bad_ because it collects participants from a node in an unprincipled way.
// Instead, there should be a series of methods like this, that define it for nodes where it makes sense
// E.g. for a choreographies, because you can look at the endpoints directly.
// Maybe not for statements, because of unpointed expressions
// If you assume there are no unpointed expressions, and all other endpoint owner annotations are also explicit, maybe
// it can make sense to define this method.
def participants[G](node: Node[G]): ListSet[Endpoint[G]] =
ListSet.from(node.collect {
case EndpointStatement(Some(Ref(endpoint)), Assign(_, _)) => Seq(endpoint)
case EndpointName(Ref(endpoint)) => Seq(endpoint)
case c @ ChorStatement(_) => c.participants.toSeq
case node @ EndpointRange(_, _) =>
throw OnlySingleEndpointsSupported(node) // Seq(endpoint)
case node @ EndpointIndex(_, _) =>
throw OnlySingleEndpointsSupported(node)
// Seq(endpoint)
// case c @ ChorStatement(_) => c.participants.toSeq
}.flatten)
}

Expand All @@ -51,8 +71,8 @@ trait ChoreographyImpl[G]

override def enterCheckContextCurrentParticipatingEndpoints(
context: CheckContext[G]
): Option[Set[Endpoint[G]]] =
context.withCurrentParticipatingEndpoints(endpoints)
): Option[Set[CommunicateTarget[G]]] =
Some(ListSet.from(endpoints.map(_.commTarget)))

override def enterCheckContextCurrentChoreography(
context: CheckContext[G]
Expand Down
54 changes: 48 additions & 6 deletions src/col/vct/col/ast/declaration/singular/EndpointImpl.scala
Original file line number Diff line number Diff line change
@@ -1,19 +1,61 @@
package vct.col.ast.declaration.singular

import vct.col.ast.declaration.DeclarationImpl
import vct.col.ast.{Endpoint, TByReferenceClass, TClass, Type}
import vct.col.ast.{
CommTargetEndpoint,
CommTargetRange,
CommunicateTarget,
Declaration,
Endpoint,
EndpointFamilyExpr,
RangeBinder,
Size,
TByReferenceClass,
TClass,
TInt,
TSeq,
Type,
Variable,
}
import vct.col.print._
import vct.col.ast.ops.{EndpointFamilyOps, EndpointOps}
import vct.col.ast.ops.{EndpointFamilyExprOps, EndpointOps}
import vct.col.check.{CheckContext, CheckError}
import vct.col.origin.{DiagnosticOrigin, Origin}
import vct.col.util.AstBuildHelpers
import vct.col.util.AstMatchHelpers.{EndpointName, EndpointRange}
import vct.col.ast.ops.{EndpointFamilyOps, EndpointOps}

trait EndpointImpl[G]
extends EndpointOps[G] with EndpointFamilyOps[G] with DeclarationImpl[G] {
extends EndpointOps[G] with DeclarationImpl[G] with EndpointFamilyOps[G] {
this: Endpoint[G] =>
override def layout(implicit ctx: Ctx): Doc =
Group(Text("endpoint") <+> ctx.name(this) <+> "=" <+> init)
Group(
Text("endpoint") <+> ctx.name(this) <> range.map(_.show)
.getOrElse(Empty) <+> "=" <+> init <> ";"
)

def singleType: TClass[G] = cls.decl.classType(typeArgs)
def rangeType: TSeq[G] = TSeq(singleType)

def t: TClass[G] = cls.decl.classType(typeArgs)
override def declarations: Seq[Declaration[G]] =
range.map(r => Seq(r.binder)).getOrElse(Seq())

override def check(ctx: CheckContext[G]): Seq[CheckError] = super.check(ctx)
def isFamily: Boolean = range.nonEmpty
def isSingle: Boolean = !isFamily

def commTarget: CommunicateTarget[G] = {
implicit val o = DiagnosticOrigin
range match {
case None => CommTargetEndpoint(this.ref)
case Some(_) =>
CommTargetRange(
this.ref,
RangeBinder(
new Variable(TInt()),
AstBuildHelpers.const(0),
Size(EndpointFamilyExpr(this.ref)),
),
)
}
}
}
10 changes: 1 addition & 9 deletions src/col/vct/col/ast/expr/heap/read/DerefImpl.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
package vct.col.ast.expr.heap.read

import vct.col.ast.expr.ExprImpl
import vct.col.ast.{
Deref,
EndpointName,
Expr,
FieldLocation,
TClass,
Type,
Value,
}
import vct.col.ast.{Deref, FieldLocation, Type, Value}
import vct.col.check.{Check, CheckContext, CheckError, SeqProgReceivingEndpoint}
import vct.col.print.{Ctx, Doc, Group, Precedence}
import vct.col.ref.Ref
Expand Down
15 changes: 0 additions & 15 deletions src/col/vct/col/ast/expr/heap/read/EndpointNameImpl.scala

This file was deleted.

Loading
Loading