|
2 | 2 | import kdrag.smt as smt |
3 | 3 | import functools |
4 | 4 |
|
5 | | -_Type0 = kd.Inductive("Type0") |
6 | | -_Type0.declare("Int", ("int", smt.IntSort())) |
7 | | -_Type0.declare("Bool", ("bool", smt.BoolSort())) |
8 | | -_Type0.declare("Real", ("real", smt.RealSort())) |
9 | | -Type0 = _Type0.create() |
10 | | -_x = smt.Const("x", Type0) |
11 | | - |
12 | | -Type0Set = smt.FullSet(Type0) |
13 | | -Int0 = smt.Lambda([_x], _x.is_Int) |
14 | | -Nat0 = smt.Lambda([_x], smt.And(Int0(_x), _x.int >= 0)) |
15 | | -Bool0 = smt.Lambda([_x], _x.is_Bool) |
16 | | -Real0 = smt.Lambda([_x], _x.is_Real) |
17 | | -Unit0 = smt.Lambda([_x], smt.And(_x.is_Bool, _x.bool == smt.BoolVal(True))) |
18 | | - |
19 | | -# Polymorphic definitions |
20 | | -neg = kd.notation.neg.define( |
21 | | - [_x], |
22 | | - kd.cond( |
23 | | - (_x.is_Bool, Type0.Bool(_x.bool)), |
24 | | - (_x.is_Int, Type0.Int(-_x.int)), |
25 | | - (_x.is_Real, Type0.Real(-_x.real)), |
26 | | - ), |
27 | | -) |
28 | | - |
29 | | -""" |
30 | | -
|
31 | | -def from_dt(dt : smt.DatatypeSortRef) -> smt.ExprRef: |
32 | | - # encode x to tagged sequences |
33 | | - kd.cond( |
34 | | - *[dt.recognizer(i), smt.Concat(smt.Unit(Type0.IntVal(i)), smt.Unit(dt.accessor(i,0)(x))) for i in range(dt.num_constructors())]) |
35 | | - ) |
36 | | -def to_set(dt : smt.DatatypeSortRef) -> smt.ExprRef: |
37 | | - # set corresponding to encoding |
38 | | - # smt.Exists([z], from_dt(dt)(z) == x) |
39 | | - # but there is a more computational version. |
40 | | -kd.prove(forall([x], to_set(dt)(from_dt(dt))) # encoding is in encoding. |
41 | | -def to_dt(dt : smt.DatatypeSortRef) -> smt.ExprRef: |
42 | | - # decode tagged sequences to x |
43 | | -
|
44 | | -class OpenFuncDecl: |
45 | | - name : str |
46 | | - domains : tuple[smt.SortRef] |
47 | | - range : smt.SortRef |
48 | | - head : smt.FuncDeclRef |
49 | | - last : smt.FuncDeclRef |
50 | | - defns : list[smt.FuncDeclRef] = [] |
51 | | - undef : smt.FuncDeclRef |
52 | | - def __init__(self, name : str, *sorts : smt.SortRef): |
53 | | - self.name = name |
54 | | - self.defns = [] |
55 | | - self.undef = kd.FuncDecl(name, sorts, sorts[-1]) |
56 | | - def define(self, vs, cond, body) -> smt.FuncDeclRef: |
57 | | - assert [v.sort() == s for v,s in zip(vs, self.sorts] |
58 | | - assert body.sort() == self.range |
59 | | - newundef = smt.FreshFunction(*[v.sort() for v in vs], self.range) |
60 | | - self.defns.append(kd.define(self.last.name(), vs, smt.If(cond, body, newundef(*vs))) |
61 | | - self.undef = newundef |
62 | | - |
63 | | -
|
64 | | -def Seq(T : smt.FuncRef) -> smt.QuantifierRef: |
65 | | - x = smt.FreshConst("x", T.domain()) |
66 | | - return smt.Lambda([x], smt.And(x.is_Seq, smt.SeqFoldLeftsmt.True, T, (x.seq) |
67 | | -def Vec(n, T : smt.FuncRef) -> smt.QuantifierRef: |
68 | | - x = smt.FreshConst("x", T.domain()) |
69 | | - return smt.Lambda([x], smt.And(Seq(T)(x), smt.Length(x.seq) == n)) |
70 | | -def Id(T, x, y) -> smt.QuantifierRef: |
71 | | - p = smt.FreshConst("p", T.domain()) |
72 | | - return smt.Lambda([p], smt.And(Unit(p) , x == y)) |
73 | | -
|
74 | | -
|
75 | | -
|
76 | | -Type1 = kd.Inductive("Type1") |
77 | | -Type1.declare("Type0", ("type0", Type0)) |
78 | | -Type1.declare("Seq", ("seq", Type1)) |
79 | | -Type1Sort = smt.DatatypeSort("Type1") |
80 | | -# We could have deeper recursion at the same universe level |
81 | | -# Type1.declare( |
82 | | -# "Array", ("array", smt.ArraySort(smt.ArraySort(Type1Sort, Type0), Type1Sort)) |
83 | | -# ) |
84 | | -Type1.declare("Array", ("array", smt.ArraySort(Type0, Type1Sort))) |
85 | | -Type1 = Type1.create() |
86 | | -
|
87 | | -def Int(x : smt.ExprRef) -> smt.BoolRef: |
88 | | -
|
89 | | -
|
90 | | -def level(x : smt.ExprRef) -> smt.IntRef: |
91 | | - x.sort().name() |
92 | | -""" |
93 | | - |
94 | | - |
95 | | -def Int(l: int) -> smt.QuantifierRef: |
96 | | - """ |
97 | | - >>> Int(0) |
98 | | - Lambda(x, is(Int, x)) |
99 | | - >>> Int(1) |
100 | | - Lambda(x, And(is(Type0, x), is(Int, type0(x)))) |
101 | | - """ |
102 | | - assert l >= 0 |
103 | | - if l == 0: |
104 | | - return Int0 |
105 | | - else: |
106 | | - Typel = Type(l) |
107 | | - x = smt.Const("x", Typel) |
108 | | - return smt.Lambda( |
109 | | - [x], smt.And(Typel.recognizer(0)(x), Int(l - 1)(Typel.accessor(0, 0)(x))) |
110 | | - ) |
111 | | - |
112 | | - |
113 | | -@functools.cache |
114 | | -def Type(l: int) -> smt.DatatypeSortRef: |
115 | | - """ |
116 | | - A generic value type at universe level l. |
117 | | - >>> Type(1) |
118 | | - Type1 |
119 | | - """ |
120 | | - if l == 0: |
121 | | - return Type0 |
122 | | - else: |
123 | | - TypeN = kd.Inductive(f"Type{l}") |
124 | | - TypeN.declare(f"Type{l - 1}", (f"type{l - 1}", Type(l - 1))) |
125 | | - TypeNSort = smt.DatatypeSort(f"Type{l}") |
126 | | - TypeN.declare("Seq", ("seq", smt.SeqSort(TypeNSort))) |
127 | | - TypeN.declare("Array", ("array", smt.ArraySort(Type(l - 1), TypeNSort))) |
128 | | - return TypeN.create() |
129 | | - |
130 | 5 |
|
131 | 6 | """ |
132 | 7 | A different style using an open datatype instead |
@@ -164,3 +39,35 @@ def poly_ax(s: smt.SortRef) -> kd.Proof: |
164 | 39 | # assert positive_poly(s) |
165 | 40 | x = smt.Const("x", s) |
166 | 41 | return kd.axiom(smt.ForAll([x], cast(s, box(x)) == x, patterns=[cast(s, box(x))])) |
| 42 | + |
| 43 | + |
| 44 | +""" |
| 45 | +Specialize some to an inductive datatype so we get built in support for injectors. |
| 46 | +""" |
| 47 | + |
| 48 | +Type = kd.Inductive("Type") |
| 49 | +_Type = smt.DatatypeSort("Type") |
| 50 | +Type.declare("Bool", ("bool", smt.BoolSort())) |
| 51 | +Type.declare("Int", ("int", smt.IntSort())) |
| 52 | +Type.declare("Real", ("real", smt.RealSort())) |
| 53 | +Type.declare("Seq", ("seq", smt.SeqSort(_Type))) |
| 54 | +Type.declare("Array", ("array", smt.ArraySort(Poly, _Type))) |
| 55 | +# Maybe RFun Real -> Type |
| 56 | +# IntFun Int -> Type |
| 57 | + |
| 58 | +Type = Type.create() |
| 59 | + |
| 60 | +# Probably unsound |
| 61 | +# type_poly_ax = poly_ax(Type) |
| 62 | +_x = smt.Const("x", Type) |
| 63 | +Int = smt.Lambda([_x], _x.is_Int) |
| 64 | +Real = smt.Lambda([_x], _x.is_Real) |
| 65 | +Bool = smt.Lambda([_x], _x.is_Bool) |
| 66 | + |
| 67 | +""" |
| 68 | +S = smt.Const("S", smt.SetSort(Type)) |
| 69 | +mul = smt.Const("mul", smt.ArraySort(Type, Type, Type)) |
| 70 | +semigroup = kd.define( |
| 71 | + "semigroup", [S, mul], smt.And(kd.Closed(S, mul), kd.Assoc(mul, T=S)) |
| 72 | +) |
| 73 | +""" |
0 commit comments