I modified the forall2.mdkal example in an effort to express transitive implication. Instead of one relation implying two other relations, one relation implies a second which implies a third.
The quantification mechanism appears to work. The second relation is correctly inferred. Then the third relation is also correctly inferred. However, there is something funky going on. Despite the relations being correctly inferred to be true individually,
their conjunction is false. Could this be by design, and, if so, how should such a transitive implication rule be expressed?
The following is the revised example:
// example with explicit forall quantification
type Int = System.Int32
relation owns(X: Int)
relation canWrite(X: Int)
relation canRead(X: Int)
relation canReadBecauseOfOwn()
relation canReadBecauseOfWrite()
relation shouldBeSentButIsNot()
p1
knows forall X: Int
owns(X) > canWrite(X)
knows forall X: Int
canWrite(X) > canRead(X)
knows owns(1)
knows canWrite(2)
if canRead(1)
do send to me: canReadBecauseOfOwn()
if canRead(2)
do send to me: canReadBecauseOfWrite()
if canRead(1) && canRead(2)
do send to me: shouldBeSentButIsNot()
The output is as follows:
C:\Program Files (x86)\DKAL\Samples\MultiMain>DkalMulti.exe revised_forall2.mdkal 100000 1000
>> From p1 to p1:
canReadBecauseOfOwn
>> From p1 to p1:
canReadBecauseOfWrite
Fixedpoint reached
