-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlambda.k
65 lines (51 loc) · 2.32 KB
/
lambda.k
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Copyright (c) Runtime Verification, Inc. All Rights Reserved.
module LAMBDA-SYNTAX
imports DOMAINS-SYNTAX
imports ID-SYNTAX
syntax Val ::= Id
| "lambda" Id "." Exp [latex(\lambda{#1}.{#2})]
syntax Exp ::= Val
| Exp Exp [strict, left]
| "(" Exp ")" [bracket]
syntax Val ::= Int | Bool
syntax Exp ::= "-" Int
> Exp "*" Exp [strict, left]
| Exp "/" Exp [strict]
> Exp "+" Exp [strict, left]
> Exp "<=" Exp [strict]
endmodule
module LAMBDA
imports LAMBDA-SYNTAX
imports DOMAINS
syntax Set ::= freeVars( Exp ) [function]
rule freeVars( _ ) => .Set [owise]
rule freeVars( V:Id ) => SetItem(V)
rule freeVars( lambda X . E ) => freeVars( E ) -Set SetItem(X)
rule freeVars( E1 E2 ) => freeVars(E1) freeVars(E2)
rule freeVars( E1 * E2 ) => freeVars(E1) freeVars(E2)
rule freeVars( E1 / E2 ) => freeVars(E1) freeVars(E2)
rule freeVars( E1 + E2 ) => freeVars(E1) freeVars(E2)
rule freeVars( E1 <= E2 ) => freeVars(E1) freeVars(E2)
syntax Id ::= freshVar(Id, Int, Set) [function]
rule freshVar(V, I, S) => #let X = String2Id(Id2String(V) +String Int2String(I)) #in #if X in S #then freshVar(V, I +Int 1, S) #else X #fi
syntax Exp ::= Exp "[" Exp "/" Id "]" [function]
rule X:Exp [_ / _] => X [owise]
rule X [V / X] => V
rule (lambda Y . E) [_ / Y] => lambda Y . E
rule (lambda Y . E) [V / X] => lambda Y . (E[V / X]) requires Y =/=K X andBool notBool (Y in freeVars(V))
rule (lambda Y . E) [V / X] => #let Z = freshVar(Y, 0, freeVars(E) freeVars(V)) #in lambda Z . (E[Z / Y] [V / X])
requires Y =/=K X andBool Y in freeVars(V)
rule (E1:Exp E2:Exp) [V / X] => E1[V / X] (E2[V / X])
rule (E1:Exp * E2:Exp) [V / X] => E1[V / X] * (E2[V / X])
rule (E1:Exp / E2:Exp) [V / X] => E1[V / X] / (E2[V / X])
rule (E1:Exp + E2:Exp) [V / X] => E1[V / X] + (E2[V / X])
rule (E1:Exp <= E2:Exp) [V / X] => E1[V / X] <= (E2[V / X])
syntax KResult ::= Val
rule (lambda X:Id . E:Exp) V:Val => E[V / X]
rule - I => 0 -Int I
rule I1 * I2 => I1 *Int I2
rule I1 / I2 => I1 /Int I2
// rule I1 / I2 => I1 /Int I2 requires I2 =/=Int 0
rule I1 + I2 => I1 +Int I2
rule I1 <= I2 => I1 <=Int I2
endmodule