Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions AVM/Class/Label.lean
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ def Label.dummy : Label where
methodsRepr := inferInstanceAs (Repr PUnit)
methodsBEq := inferInstanceAs (BEq PUnit)

def Label.logicRef (lab : Label) : Anoma.LogicRef :=
⟨"class-logic-" ++ lab.name⟩

inductive Label.MemberId (lab : Class.Label) where
| constructorId (constrId : lab.ConstructorId) : MemberId lab
| destructorId (destructorId : lab.DestructorId) : MemberId lab
Expand Down
71 changes: 28 additions & 43 deletions AVM/Class/Translation/Logics.lean
Original file line number Diff line number Diff line change
Expand Up @@ -85,31 +85,44 @@ private def Upgrade.Message.logicFun
&& selfRes.isPersistent
&& upgradedRes.isPersistent

/-- The class logic checks if all consumed messages in the action correspond to
class members, the single consumed object is the receiver, and there is
at least one message. -/
/-- The class logic checks if the message consumed in the action is associated
with the same ecosystem, the `self` object is among the message recipients
and the number of recipients is equal to the number of consumed object
resources. The class logic also checks the class invariant for `self`. -/
private def logicFun
{lab : Ecosystem.Label}
{classId : lab.ClassId}
(cl : Class classId)
(consumedMessageResources consumedObjectResources : List Anoma.Resource)
(args : Logic.Args)
: Bool :=
let try self : Object classId := Object.fromResource args.self
check cl.invariant self args
match args.status with
| Created => true
| Consumed =>
let nMessages := consumedMessageResources.length
let! [consumedObjectResource] : List Anoma.Resource := consumedObjectResources
let try consumedObject : Object classId := Object.fromResource consumedObjectResource
-- NOTE: consumedObject == self by definition of Logic.Args; we only check
-- that there are no other consumed objects
nMessages + 1 == (Logic.filterOutDummy args.consumed).length
&& consumedMessageResources.all fun res =>
let try msg : Message lab := Message.fromResource res
let! [recipient] := msg.recipients.toList
consumedObject.uid == recipient
let consumedObjectResources : List Anoma.Resource := Logic.selectObjectResources args.consumed
let! [consumedMessageResource] := Logic.selectMessageResources args.consumed
let try msg : Message lab := Message.fromResource consumedMessageResource
let recipients := msg.recipients.toList
self.uid ∈ recipients
&& recipients.length == consumedObjectResources.length
-- Note that the message logics already check if the consumed object
-- resources have the right form, i.e., correspond to the self / selves. We
-- only need to check that the number of recipients is equal to the number
-- of consumed object resources, i.e., there are no extra recipients. The
-- class logic will be run for each consumed object, with `self` set to that
-- object, so it will be checked if every consumed object is among the
-- recipients.

/-- The class logic that is the Resource Logic of each resource corresponding to
an object of this class. -/
def logic
{lab : Ecosystem.Label}
{classId : lab.ClassId}
(cl : Class classId)
: Anoma.Logic :=
{ reference := classId.label.logicRef,
function := logicFun cl }

def Constructor.Message.logic
{lab : Ecosystem.Label}
Expand Down Expand Up @@ -207,32 +220,4 @@ def MultiMethod.Message.logic
{ reference := ⟨s!"AVM.MultiMethod.{@repr _ lab.multiMethodsRepr multiId}"⟩,
function args := MultiMethod.Message.logicFun method args data }

/-- The multiMethod logic checks that all consumed messages in the action correspond
to members in the ecosystem and the consumed objects are the receivers. -/
private def logicFun
{lab : Ecosystem.Label}
(eco : Ecosystem lab)
(args : Logic.Args)
: Bool :=
match args.status with
| Created => true
| Consumed =>
let consumedMessageResources : List Anoma.Resource := Logic.selectMessageResources args.consumed
let nMessages := consumedMessageResources.length
let consumedObjectResources : List Anoma.Resource := Logic.selectObjectResources args.consumed
nMessages >= 1
&& consumedMessageResources.all fun res =>
let try msg : Message lab := Message.fromResource res
match msg.id with
| .classMember (classId := cl) _ => AVM.Class.logicFun (eco.classes cl) consumedMessageResources consumedObjectResources args
| .multiMethodId multiId =>
let try selves : multiId.Selves := multiId.ConsumedToSelves consumedObjectResources
nMessages + multiId.numObjectArgs == (Logic.filterOutDummy args.consumed).length
&& Label.MultiMethodId.SelvesToVector selves (fun o => o.uid) ≍? msg.recipients

def logic
{lab : Ecosystem.Label}
(eco : Ecosystem lab)
: Anoma.Logic :=
{ reference := lab.logicRef,
function := logicFun eco }
end AVM.Ecosystem
4 changes: 1 addition & 3 deletions AVM/Ecosystem/Label/Base.lean
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ def Fin.classId

namespace AVM.Ecosystem.Label

def logicRef (lab : Label) : Anoma.LogicRef :=
⟨"logic-of-ecosystem-" ++ lab.name⟩

/-- Singleton ecosystem: An ecosystem with a single class, no multiMethods and no intents -/
def singleton (l : Class.Label) : Ecosystem.Label where
name := l.name
Expand Down Expand Up @@ -101,6 +98,7 @@ def ObjectArgNames {lab : Ecosystem.Label} (multiId : lab.MultiMethodId) : Type

def ObjectArgNamesEnum {lab : Ecosystem.Label} (multiId : lab.MultiMethodId) : FinEnum (lab.MultiMethodObjectArgNames multiId) := lab.ObjectArgNamesEnum multiId

/-- The number of selves in a multi-method. -/
def numObjectArgs {lab : Ecosystem.Label} {multiId : lab.MultiMethodId} : Nat :=
(lab.ObjectArgNamesEnum multiId).card

Expand Down
2 changes: 1 addition & 1 deletion AVM/Logic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def checkResourceValues (objectValues : List ObjectValue) (resources : List Anom
where
resourceValueEq (sdata : ObjectValue) (res : Anoma.Resource) : Bool :=
sdata.label === res.label &&
sdata.label.logicRef == res.logicRef &&
sdata.classId.label.logicRef == res.logicRef &&
sdata.data.quantity == res.quantity &&
let try resVal : Object.Resource.Value sdata.classId := tryCast res.value
resVal.privateFields == sdata.data.privateFields &&
Expand Down
4 changes: 2 additions & 2 deletions AVM/Object.lean
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def SomeObject.toResource
{ label
classId
dynamicLabel := clab.DynamicLabel.mkDynamicLabel obj.data.privateFields }
logicRef := label.logicRef,
logicRef := classId.label.logicRef,
quantity := obj.data.quantity,
Val := ⟨Object.Resource.Value classId⟩,
value := ⟨obj.uid, obj.data.privateFields⟩,
Expand All @@ -126,7 +126,7 @@ def Object.fromResource
let try resLab : AVM.Resource.Label := tryCast res.label
let try objLab := Resource.Label.getObjectResourceLabel resLab
check (objLab.label == lab)
check (res.logicRef == lab.logicRef)
check (res.logicRef == c.label.logicRef)
let try value : Object.Resource.Value c := tryCast res.value
some { uid := value.uid,
data := ⟨res.quantity, value.privateFields⟩,
Expand Down