comparison src/iflow.sml @ 1249:7c6fc92f6c31

Complain about DValRec; optimizations for unit-valued ECase and forgetting of path conditions across ESeq
author Adam Chlipala <adamc@hcoop.net>
date Thu, 29 Apr 2010 11:47:24 -0400
parents cf9a636f9b15
children e80582b927f2
comparison
equal deleted inserted replaced
1248:cf9a636f9b15 1249:7c6fc92f6c31
1203 1203
1204 type stashed 1204 type stashed
1205 val stash : unit -> stashed 1205 val stash : unit -> stashed
1206 val reinstate : stashed -> unit 1206 val reinstate : stashed -> unit
1207 1207
1208 type stashedPath
1209 val stashPath : unit -> stashedPath
1210 val reinstatePath : stashedPath -> unit
1211
1208 val nextVar : unit -> int 1212 val nextVar : unit -> int
1209 1213
1210 val assert : atom list -> unit 1214 val assert : atom list -> unit
1211 1215
1212 val addPath : check -> unit 1216 val addPath : check -> unit
1332 fun stash () = (!nvar, !path, (#1 (!hyps), #2 (!hyps))) 1336 fun stash () = (!nvar, !path, (#1 (!hyps), #2 (!hyps)))
1333 fun reinstate (nv, p, h) = 1337 fun reinstate (nv, p, h) =
1334 (nvar := nv; 1338 (nvar := nv;
1335 path := p; 1339 path := p;
1336 setHyps h) 1340 setHyps h)
1341
1342 type stashedPath = ((int * atom list) * check) option ref list
1343 fun stashPath () = !path
1344 fun reinstatePath p = path := p
1337 1345
1338 fun nextVar () = 1346 fun nextVar () =
1339 let 1347 let
1340 val n = !nvar 1348 val n = !nvar
1341 in 1349 in
1910 evalExp env e (fn e => St.send true (e, loc)) 1918 evalExp env e (fn e => St.send true (e, loc))
1911 | EWrite e => 1919 | EWrite e =>
1912 evalExp env e (fn e => (St.send true (e, loc); 1920 evalExp env e (fn e => (St.send true (e, loc);
1913 k (Recd []))) 1921 k (Recd [])))
1914 | ESeq (e1, e2) => 1922 | ESeq (e1, e2) =>
1915 evalExp env e1 (fn _ => evalExp env e2 k) 1923 let
1924 val path = St.stashPath ()
1925 in
1926 evalExp env e1 (fn _ => (St.reinstatePath path; evalExp env e2 k))
1927 end
1916 | ELet (_, _, e1, e2) => 1928 | ELet (_, _, e1, e2) =>
1917 evalExp env e1 (fn e1 => evalExp (e1 :: env) e2 k) 1929 evalExp env e1 (fn e1 => evalExp (e1 :: env) e2 k)
1918 | EClosure (n, es) => 1930 | EClosure (n, es) =>
1919 let 1931 let
1920 fun doArgs (es, acc) = 1932 fun doArgs (es, acc) =
1927 end 1939 end
1928 1940
1929 | EQuery {query = q, body = b, initial = i, state = state, ...} => 1941 | EQuery {query = q, body = b, initial = i, state = state, ...} =>
1930 evalExp env i (fn i => 1942 evalExp env i (fn i =>
1931 let 1943 let
1932 val saved = St.stash ()
1933
1934 val () = (k i)
1935 handle Cc.Contradiction => ()
1936 val () = St.reinstate saved
1937
1938 val r = Var (St.nextVar ()) 1944 val r = Var (St.nextVar ())
1939 val acc = Var (St.nextVar ()) 1945 val acc = Var (St.nextVar ())
1940 1946
1941 val touched = MonoUtil.Exp.fold {typ = fn (_, touched) => touched, 1947 val (ts, cs) = MonoUtil.Exp.fold {typ = fn (_, st) => st,
1942 exp = fn (e, touched) => 1948 exp = fn (e, st as (cs, ts)) =>
1943 case e of 1949 case e of
1944 EDml e => 1950 EDml e =>
1945 (case parse dml e of 1951 (case parse dml e of
1946 NONE => touched 1952 NONE => st
1947 | SOME c => 1953 | SOME c =>
1948 case c of 1954 case c of
1949 Insert _ => touched 1955 Insert _ => st
1950 | Delete (tab, _) => 1956 | Delete (tab, _) =>
1951 SS.add (touched, tab) 1957 (cs, SS.add (ts, tab))
1952 | Update (tab, _, _) => 1958 | Update (tab, _, _) =>
1953 SS.add (touched, tab)) 1959 (cs, SS.add (ts, tab)))
1954 | _ => touched} 1960 | EFfiApp ("Basis", "set_cookie",
1955 SS.empty b 1961 [_, (EPrim (Prim.String cname), _),
1962 _, _, _]) =>
1963 (SS.add (cs, cname), ts)
1964 | _ => st}
1965 (SS.empty, SS.empty) b
1956 in 1966 in
1957 SS.app (St.havocReln o Sql) touched; 1967 case (#1 state, SS.isEmpty ts, SS.isEmpty cs) of
1968 (TRecord [], true, true) => ()
1969 | _ =>
1970 let
1971 val saved = St.stash ()
1972 in
1973 (k i)
1974 handle Cc.Contradiction => ();
1975 St.reinstate saved
1976 end;
1977
1978 SS.app (St.havocReln o Sql) ts;
1979 SS.app St.havocCookie cs;
1958 1980
1959 doQuery {Env = env, 1981 doQuery {Env = env,
1960 NextVar = Var o St.nextVar, 1982 NextVar = Var o St.nextVar,
1961 Add = fn a => St.assert [a], 1983 Add = fn a => St.assert [a],
1962 Save = St.stash, 1984 Save = St.stash,
2108 val exptd = foldl (fn ((d, _), exptd) => 2130 val exptd = foldl (fn ((d, _), exptd) =>
2109 case d of 2131 case d of
2110 DExport (_, _, n, _, _, _) => IS.add (exptd, n) 2132 DExport (_, _, n, _, _, _) => IS.add (exptd, n)
2111 | _ => exptd) IS.empty file 2133 | _ => exptd) IS.empty file
2112 2134
2113 fun decl (d, _) = 2135 fun decl (d, loc) =
2114 case d of 2136 case d of
2115 DTable (tab, fs, pk, _) => 2137 DTable (tab, fs, pk, _) =>
2116 let 2138 let
2117 val ks = 2139 val ks =
2118 case #1 pk of 2140 case #1 pk of
2156 in 2178 in
2157 St.assert ps; 2179 St.assert ps;
2158 (evalExp env e (fn _ => ()) handle Cc.Contradiction => ()); 2180 (evalExp env e (fn _ => ()) handle Cc.Contradiction => ());
2159 St.reinstate saved 2181 St.reinstate saved
2160 end 2182 end
2183
2184 | DValRec _ => ErrorMsg.errorAt loc "Iflow can't check recursive functions."
2161 2185
2162 | DPolicy pol => 2186 | DPolicy pol =>
2163 let 2187 let
2164 val rvN = ref 0 2188 val rvN = ref 0
2165 fun rv () = 2189 fun rv () =