@@ -157,8 +157,11 @@ module type CircuitInterface = sig
157
157
158
158
159
159
(* Circuits representing booleans *)
160
- val circuit_true : (cbool * (cinp list ))
161
- val circuit_false : (cbool * (cinp list ))
160
+ val circuit_true : cbool cfun
161
+ val circuit_false : cbool cfun
162
+ val circuit_and : cbool cfun -> cbool cfun -> cbool cfun
163
+ val circuit_or : cbool cfun -> cbool cfun -> cbool cfun
164
+ val circuit_not : cbool cfun -> cbool cfun
162
165
163
166
(* <=> circuit has not inputs (every input is unbound) *)
164
167
val circuit_is_free : circuit -> bool
@@ -877,6 +880,16 @@ module MakeCircuitInterfaceFromCBackend(Backend: CBackend) : CircuitInterface =
877
880
878
881
let circuit_true = `CBool Backend. true_ , []
879
882
let circuit_false = `CBool Backend. false_, []
883
+
884
+ let circuit_and (`CBool c1 , inps1 ) (`CBool c2 , inps2 ) =
885
+ `CBool (Backend. band c1 c2), merge_inputs inps1 inps2
886
+
887
+ let circuit_or (`CBool c1 , inps1 ) (`CBool c2 , inps2 ) =
888
+ `CBool (Backend. bor c1 c2), merge_inputs inps1 inps2
889
+
890
+ let circuit_not (`CBool c , inps ) =
891
+ `CBool (Backend. bnot c), inps
892
+
880
893
let circuit_is_free (f : circuit ) : bool = List. is_empty @@ snd f
881
894
882
895
let circuit_ite ~(c : cbool * (cinp list) ) ~(t : circuit ) ~(f : circuit ) : circuit =
@@ -1428,6 +1441,7 @@ module MakeCircuitInterfaceFromCBackend(Backend: CBackend) : CircuitInterface =
1428
1441
Backend. sat ~inps c
1429
1442
1430
1443
let circ_taut (c : circuit ) : bool =
1444
+ Format. eprintf " Calling circ_taut on circuit: %a@." pp_circuit c;
1431
1445
let `CBool c, inps = cbool_of_circuit ~strict: false c in
1432
1446
let inps = List. map (function
1433
1447
| { type_ = `CIBool ; id } -> (id, 1 )
@@ -1863,6 +1877,31 @@ let circuit_of_form
1863
1877
hyps, (circuit_true :> circuit )
1864
1878
| Some `False , [] ->
1865
1879
hyps, (circuit_false :> circuit )
1880
+ | Some `Imp , [f1; f2] ->
1881
+ let hyps, c1 = doit cache hyps f1 in
1882
+ let hyps, c2 = doit cache hyps f2 in
1883
+ let c1 = cbool_of_circuit ~strict: false c1 in
1884
+ let c2 = cbool_of_circuit ~strict: false c2 in
1885
+ hyps, (circuit_or (circuit_not c1) c2 :> circuit)
1886
+ | Some (`And _ ), [f1; f2] ->
1887
+ let hyps, c1 = doit cache hyps f1 in
1888
+ let hyps, c2 = doit cache hyps f2 in
1889
+ let c1 = cbool_of_circuit ~strict: false c1 in
1890
+ let c2 = cbool_of_circuit ~strict: false c2 in
1891
+ hyps, (circuit_and c1 c2 :> circuit )
1892
+ | Some (`Or _ ), [f1; f2] ->
1893
+ let hyps, c1 = doit cache hyps f1 in
1894
+ let hyps, c2 = doit cache hyps f2 in
1895
+ let c1 = cbool_of_circuit ~strict: false c1 in
1896
+ let c2 = cbool_of_circuit ~strict: false c2 in
1897
+ hyps, (circuit_or c1 c2 :> circuit )
1898
+ | Some `Iff , [f1; f2] ->
1899
+ let hyps, c1 = doit cache hyps f1 in
1900
+ let hyps, c2 = doit cache hyps f2 in
1901
+ let c1 = cbool_of_circuit ~strict: false c1 in
1902
+ let c2 = cbool_of_circuit ~strict: false c2 in
1903
+ hyps, (circuit_or (circuit_and c1 c2) (circuit_and (circuit_not c1) (circuit_not c2)) :> circuit)
1904
+ (* | Some `Not, [f] -> doit cache hyps (f_not f) *)
1866
1905
| _ -> (* recurse down into definition *)
1867
1906
let hyps, f_c = doit cache hyps f in
1868
1907
let hyps, fcs = List. fold_left_map
@@ -2150,6 +2189,47 @@ let circuit_aggregate =
2150
2189
let circuit_aggregate_inps =
2151
2190
circuit_aggregate_inputs
2152
2191
2153
-
2154
2192
let circuit_flatten (c : circuit ) =
2155
2193
(cbitstring_of_circuit ~strict: false c :> circuit )
2194
+
2195
+ (* TODO: get a better name and uniformize *)
2196
+ let circuit_of_form_with_hyps ?(pstate = empty_pstate) ?(cache = empty_cache) hyps f =
2197
+ let (pstate, cache, f), bnds = List. fold_left_map (fun (pstate , cache , goal ) (id , lk ) ->
2198
+ Format. eprintf " Processing hyp: %s@." (id.id_symb);
2199
+ match lk with
2200
+ | EcBaseLogic. LD_mem (Lmt_concrete Some {lmt_decl =decls } ) ->
2201
+ let pstate, bnds = List. fold_left_map (fun pstate {ov_name; ov_type} ->
2202
+ match ov_name with
2203
+ | Some v -> let id = create v in
2204
+ open_circ_lambda_pstate (toenv hyps) pstate [(id, ov_type)], Some (id, ov_type)
2205
+ | None -> (pstate, None )
2206
+ ) pstate decls in
2207
+ (pstate, cache, goal), List. filter_map (fun i -> i) bnds
2208
+ | EcBaseLogic. LD_var (t , Some f ) ->
2209
+ let cache = open_circ_lambda_cache (toenv hyps) cache [(id, t)] in
2210
+ begin try
2211
+ ignore (circuit_of_form ~pstate ~cache hyps f);
2212
+ (pstate, cache, (f_and goal (f_eq (f_local id t) f))), [(id, t)]
2213
+ with _ -> (pstate, cache, f_forall [(id, GTty t)] goal), [(id, t)] (* FIXME: do we still add to cache here? *)
2214
+ end
2215
+ | EcBaseLogic. LD_var (t , None) ->
2216
+ (pstate,
2217
+ open_circ_lambda_cache (toenv hyps) cache [(id, t)],
2218
+ goal), [(id, t)]
2219
+ | EcBaseLogic. LD_hyp f_hyp ->
2220
+ begin try
2221
+ ignore (circuit_of_form ~pstate ~cache hyps f_hyp);
2222
+ (pstate, cache, f_imp f_hyp goal), []
2223
+ with e ->
2224
+ Format. eprintf " Failed to convert hyp %a with error:@.%s@."
2225
+ EcPrinting. (pp_form (PPEnv. ofenv (toenv hyps))) f_hyp (Printexc. to_string e);
2226
+ (pstate, cache, goal), []
2227
+ end
2228
+
2229
+ | _ -> (pstate, cache, goal), []
2230
+ ) (pstate, cache, f) (List. rev (tohyps hyps).h_local)
2231
+ in
2232
+ let bnds = List. flatten bnds in
2233
+ Format. eprintf " Converting form %a@." EcPrinting. (pp_form (PPEnv. ofenv (toenv hyps))) f;
2234
+ close_circ_lambda (toenv hyps) bnds @@
2235
+ circuit_of_form ~pstate ~cache hyps f
0 commit comments