mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Add permissive-licensed Coq samples
BSD-2-Clause: https://github.com/jscert/jscert * JSCorrectness.v * JSInterpreterExtraction.v * JSNumber.v * JSPrettyInterm.v MIT/Expat: https://github.com/clarus/coq-atm * Computation.v * Main.v * Spec.v
This commit is contained in:
		
							
								
								
									
										85
									
								
								samples/Coq/Computation.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								samples/Coq/Computation.v
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| (** The definition of computations, used to represent interactive programs. *) | ||||
| Require Import Coq.NArith.NArith. | ||||
| Require Import ListString.All. | ||||
|  | ||||
| Local Open Scope type. | ||||
|  | ||||
| (** System calls. *) | ||||
| Module Command. | ||||
|   Inductive t := | ||||
|   | AskCard | ||||
|   | AskPIN | ||||
|   | CheckPIN (pin : N) | ||||
|   | AskAmount | ||||
|   | CheckAmount (amount : N) | ||||
|   | GiveCard | ||||
|   | GiveAmount (amount : N) | ||||
|   | ShowError (message : LString.t). | ||||
|  | ||||
|   (** The type of an answer for a command depends on the value of the command. *) | ||||
|   Definition answer (command : t) : Type := | ||||
|     match command with | ||||
|     | AskCard => bool (* If the given card seems valid. *) | ||||
|     | AskPIN => option N (* A number or cancellation. *) | ||||
|     | CheckPIN _ => bool (* If the PIN number is valid. *) | ||||
|     | AskAmount => option N (* A number or cancellation. *) | ||||
|     | CheckAmount _ => bool (* If the amount can be withdrawn. *) | ||||
|     | GiveCard => bool (* If the card was given. *) | ||||
|     | GiveAmount _ => bool (* If the money was given. *) | ||||
|     | ShowError _ => unit (* Show an error message. *) | ||||
|     end. | ||||
| End Command. | ||||
|  | ||||
| (** Computations with I/Os. *) | ||||
| Module C. | ||||
|   (** A computation can either does nothing, or do a system call and wait | ||||
|       for the answer to run another computation. *) | ||||
|   Inductive t : Type := | ||||
|   | Ret : t | ||||
|   | Call : forall (command : Command.t), (Command.answer command -> t) -> t. | ||||
|   Arguments Ret. | ||||
|   Arguments Call _ _. | ||||
|  | ||||
|   (** Some optional notations. *) | ||||
|   Module Notations. | ||||
|     (** A nicer notation for `Ret`. *) | ||||
|     Definition ret : t := | ||||
|       Ret. | ||||
|  | ||||
|     (** We define an explicit apply function so that Coq does not try to expand | ||||
|         the notations everywhere. *) | ||||
|     Definition apply {A B} (f : A -> B) (x : A) := f x. | ||||
|  | ||||
|     (** System call. *) | ||||
|     Notation "'call!' answer ':=' command 'in' X" := | ||||
|       (Call command (fun answer => X)) | ||||
|       (at level 200, answer ident, command at level 100, X at level 200). | ||||
|  | ||||
|     (** System call with typed answer. *) | ||||
|     Notation "'call!' answer : A ':=' command 'in' X" := | ||||
|       (Call command (fun (answer : A) => X)) | ||||
|       (at level 200, answer ident, command at level 100, A at level 200, X at level 200). | ||||
|  | ||||
|     (** System call ignoring the answer. *) | ||||
|     Notation "'do_call!' command 'in' X" := | ||||
|       (Call command (fun _ => X)) | ||||
|       (at level 200, command at level 100, X at level 200). | ||||
|  | ||||
|     (** This notation is useful to compose computations which wait for a | ||||
|         continuation. We do not have an explicit bind operator to simplify the | ||||
|         language and the proofs. *) | ||||
|     Notation "'let!' x ':=' X 'in' Y" := | ||||
|       (apply X (fun x => Y)) | ||||
|       (at level 200, x ident, X at level 100, Y at level 200). | ||||
|  | ||||
|     (** Let with a typed answer. *) | ||||
|     Notation "'let!' x : A ':=' X 'in' Y" := | ||||
|       (apply X (fun (x : A) => Y)) | ||||
|       (at level 200, x ident, X at level 100, A at level 200, Y at level 200). | ||||
|  | ||||
|     (** Let ignoring the answer. *) | ||||
|     Notation "'do!' X 'in' Y" := | ||||
|       (apply X (fun _ => Y)) | ||||
|       (at level 200, X at level 100, Y at level 200). | ||||
|   End Notations. | ||||
| End C. | ||||
							
								
								
									
										5944
									
								
								samples/Coq/JsCorrectness.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5944
									
								
								samples/Coq/JsCorrectness.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										249
									
								
								samples/Coq/JsInterpreterExtraction.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								samples/Coq/JsInterpreterExtraction.v
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,249 @@ | ||||
| Set Implicit Arguments. | ||||
| Require Import JsSyntax JsInterpreterMonads JsInterpreter JsInit. | ||||
| Require Import LibFix LibList. | ||||
|  | ||||
| Require Export Shared. | ||||
| Require Export LibTactics LibLogic LibReflect LibList | ||||
|   LibOperation LibStruct LibNat LibEpsilon LibFunc LibHeap. | ||||
| Require Flocq.Appli.Fappli_IEEE Flocq.Appli.Fappli_IEEE_bits. | ||||
|  | ||||
|  | ||||
|  | ||||
| (* Here stands some commands to extract relatively correctly the interpreter to Ocaml. *) | ||||
| Extraction Language Ocaml. | ||||
|  | ||||
| Require Import ExtrOcamlBasic. | ||||
| Require Import ExtrOcamlNatInt. | ||||
| Require Import ExtrOcamlString. | ||||
|  | ||||
| (* Optimal fixpoint. *) | ||||
| Extraction Inline FixFun3 FixFun3Mod FixFun4 FixFun4Mod FixFunMod curry3 uncurry3 curry4 uncurry4. | ||||
| (* As classical logic statements are now unused, they should not be extracted | ||||
|    (otherwise, useless errors will be launched). *) | ||||
| Extraction Inline epsilon epsilon_def classicT arbitrary indefinite_description Inhab_witness Fix isTrue. | ||||
|  | ||||
| (**************************************************************) | ||||
| (** ** Numerical values *) | ||||
|  | ||||
| (* number *) | ||||
|  | ||||
| Extract Inductive positive => float | ||||
| [ "(fun p -> 1. +. (2. *. p))" | ||||
|   "(fun p -> 2. *. p)" | ||||
|   "1." ] | ||||
| "(fun f2p1 f2p f1 p -> | ||||
| if p <= 1. then f1 () else if mod_float p 2. = 0. then f2p (floor (p /. 2.)) else f2p1 (floor (p /. 2.)))". | ||||
|  | ||||
| Extract Inductive Z => float [ "0." "" "(~-.)" ] | ||||
| "(fun f0 fp fn z -> if z=0. then f0 () else if z>0. then fp z else fn (~-. z))". | ||||
|  | ||||
| Extract Inductive N => float [ "0." "" ] | ||||
| "(fun f0 fp n -> if n=0. then f0 () else fp n)". | ||||
|  | ||||
| Extract Constant Z.add => "(+.)". | ||||
| Extract Constant Z.succ => "(+.) 1.". | ||||
| Extract Constant Z.pred => "(fun x -> x -. 1.)". | ||||
| Extract Constant Z.sub => "(-.)". | ||||
| Extract Constant Z.mul => "( *. )". | ||||
| Extract Constant Z.opp => "(~-.)". | ||||
| Extract Constant Z.abs => "abs_float". | ||||
| Extract Constant Z.min => "min". | ||||
| Extract Constant Z.max => "max". | ||||
| Extract Constant Z.compare => | ||||
|  "fun x y -> if x=y then Eq else if x<y then Lt else Gt". | ||||
|  | ||||
| Extract Constant Pos.add => "(+.)". | ||||
| Extract Constant Pos.succ => "(+.) 1.". | ||||
| Extract Constant Pos.pred => "(fun x -> x -. 1.)". | ||||
| Extract Constant Pos.sub => "(-.)". | ||||
| Extract Constant Pos.mul => "( *. )". | ||||
| Extract Constant Pos.min => "min". | ||||
| Extract Constant Pos.max => "max". | ||||
| Extract Constant Pos.compare => | ||||
|  "fun x y -> if x=y then Eq else if x<y then Lt else Gt". | ||||
| Extract Constant Pos.compare_cont => | ||||
|  "fun x y c -> if x=y then c else if x<y then Lt else Gt". | ||||
|  | ||||
| Extract Constant N.add => "(+.)". | ||||
| Extract Constant N.succ => "(+.) 1.". | ||||
| Extract Constant N.pred => "(fun x -> x -. 1.)". | ||||
| Extract Constant N.sub => "(-.)". | ||||
| Extract Constant N.mul => "( *. )". | ||||
| Extract Constant N.min => "min". | ||||
| Extract Constant N.max => "max". | ||||
| Extract Constant N.div => "(fun x y -> if x = 0. then 0. else floor (x /. y))". | ||||
| Extract Constant N.modulo => "mod_float". | ||||
| Extract Constant N.compare => | ||||
|  "fun x y -> if x=y then Eq else if x<y then Lt else Gt". | ||||
|  | ||||
| Extract Inductive Fappli_IEEE.binary_float => float [ | ||||
|   "(fun s -> if s then (0.) else (-0.))" | ||||
|   "(fun s -> if s then infinity else neg_infinity)" | ||||
|   "nan" | ||||
|   "(fun (s, m, e) -> failwith ""FIXME: No extraction from binary float allowed yet."")" | ||||
| ].  | ||||
|  | ||||
| Extract Constant JsNumber.of_int => "fun x -> x". | ||||
|  | ||||
| Extract Constant JsNumber.nan => "nan". | ||||
| Extract Constant JsNumber.zero => "0.". | ||||
| Extract Constant JsNumber.neg_zero => "(-0.)". | ||||
| Extract Constant JsNumber.one => "1.". | ||||
| Extract Constant JsNumber.infinity => "infinity". | ||||
| Extract Constant JsNumber.neg_infinity => "neg_infinity". | ||||
| Extract Constant JsNumber.max_value => "max_float". | ||||
| Extract Constant JsNumber.min_value => "(Int64.float_of_bits Int64.one)". | ||||
| Extract Constant JsNumber.pi => "(4. *. atan 1.)". | ||||
| Extract Constant JsNumber.e => "(exp 1.)". | ||||
| Extract Constant JsNumber.ln2 => "(log 2.)". | ||||
| Extract Constant JsNumber.floor => "floor". | ||||
| Extract Constant JsNumber.absolute => "abs_float". | ||||
|  | ||||
| Extract Constant JsNumber.from_string => | ||||
|   "(fun s -> | ||||
|     try | ||||
|       let s = (String.concat """" (List.map (String.make 1) s)) in | ||||
|       if s = """" then 0. else float_of_string s | ||||
|     with Failure ""float_of_string"" -> nan) | ||||
|    (* Note that we're using `float_of_string' there, which does not have the same | ||||
|       behavior than JavaScript.  For instance it will read ""022"" as 22 instead of | ||||
|       18, which should be the JavaScript result for it. *)". | ||||
|  | ||||
| Extract Constant JsNumber.to_string => | ||||
|   "(fun f ->  | ||||
|     prerr_string (""Warning:  JsNumber.to_string called.  This might be responsible for errors.  Argument value:  "" ^ string_of_float f ^ "".""); | ||||
|     prerr_newline(); | ||||
|     let string_of_number n = | ||||
|       let sfn = string_of_float n in | ||||
|       (if (sfn = ""inf"") then ""Infinity"" else | ||||
|        if (sfn = ""-inf"") then ""-Infinity"" else | ||||
|        if (sfn = ""nan"") then ""NaN"" else | ||||
|        let inum = int_of_float n in | ||||
|        if (float_of_int inum = n) then (string_of_int inum) else (string_of_float n)) in | ||||
|     let ret = ref [] in (* Ugly, but the API for OCaml string is not very functional... *) | ||||
|     String.iter (fun c -> ret := c :: !ret) (string_of_number f); | ||||
|     List.rev !ret) | ||||
|    (* Note that this is ugly, we should use the spec of JsNumber.to_string here (9.8.1). *)". | ||||
|  | ||||
| Extract Constant JsNumber.add => "(+.)". | ||||
| Extract Constant JsNumber.sub => "(-.)". | ||||
| Extract Constant JsNumber.mult => "( *. )". | ||||
| Extract Constant JsNumber.div => "(/.)". | ||||
| Extract Constant JsNumber.fmod => "mod_float". | ||||
| Extract Constant JsNumber.neg => "(~-.)". | ||||
| Extract Constant JsNumber.sign => "(fun f -> float_of_int (compare f 0.))". | ||||
| Extract Constant JsNumber.number_comparable => "(fun n1 n2 -> 0 = compare n1 n2)". | ||||
| Extract Constant JsNumber.lt_bool => "(<)". | ||||
|  | ||||
| Extract Constant JsNumber.to_int32 =>  | ||||
| "fun n -> | ||||
|   match classify_float n with | ||||
|   | FP_normal | FP_subnormal -> | ||||
|     let i32 = 2. ** 32. in | ||||
|     let i31 = 2. ** 31. in | ||||
|     let posint = (if n < 0. then (-1.) else 1.) *. (floor (abs_float n)) in | ||||
|     let int32bit = | ||||
|       let smod = mod_float posint i32 in | ||||
|       if smod < 0. then smod +. i32 else smod | ||||
|     in | ||||
|     (if int32bit >= i31 then int32bit -. i32 else int32bit) | ||||
|   | _ -> 0.". (* LATER:  do in Coq.  Spec is 9.5, p. 47.*) | ||||
|  | ||||
| Extract Constant JsNumber.to_uint32 => | ||||
| "fun n -> | ||||
|   match classify_float n with | ||||
|   | FP_normal | FP_subnormal -> | ||||
|     let i32 = 2. ** 32. in | ||||
|     let posint = (if n < 0. then (-1.) else 1.) *. (floor (abs_float n)) in | ||||
|     let int32bit = | ||||
|       let smod = mod_float posint i32 in | ||||
|       if smod < 0. then smod +. i32 else smod | ||||
|     in | ||||
|     int32bit | ||||
|   | _ -> 0.". (* LAER:  do in Coq.  Spec is 9.6, p47.*) | ||||
|  | ||||
| Extract Constant JsNumber.modulo_32 => "(fun x -> let r = mod_float x 32. in if x < 0. then r +. 32. else r)". | ||||
| Extract Constant JsNumber.int32_bitwise_not => "fun x -> Int32.to_float (Int32.lognot (Int32.of_float x))". | ||||
| Extract Constant JsNumber.int32_bitwise_and => "fun x y -> Int32.to_float (Int32.logand (Int32.of_float x) (Int32.of_float y))". | ||||
| Extract Constant JsNumber.int32_bitwise_or => "fun x y -> Int32.to_float (Int32.logor (Int32.of_float x) (Int32.of_float y))". | ||||
| Extract Constant JsNumber.int32_bitwise_xor => "fun x y -> Int32.to_float (Int32.logxor (Int32.of_float x) (Int32.of_float y))". | ||||
| Extract Constant JsNumber.int32_left_shift => "(fun x y -> Int32.to_float (Int32.shift_left (Int32.of_float x) (int_of_float y)))". | ||||
| Extract Constant JsNumber.int32_right_shift => "(fun x y -> Int32.to_float (Int32.shift_right (Int32.of_float x) (int_of_float y)))". | ||||
| Extract Constant JsNumber.uint32_right_shift =>  | ||||
| "(fun x y -> | ||||
|   let i31 = 2. ** 31. in | ||||
|   let i32 = 2. ** 32. in | ||||
|   let newx = if x >= i31 then x -. i32 else x in | ||||
|   let r = Int32.to_float (Int32.shift_right_logical (Int32.of_float newx) (int_of_float y)) in | ||||
|   if r < 0. then r +. i32 else r)". | ||||
|  | ||||
| Extract Constant int_of_char => "(fun c -> float_of_int (int_of_char c))". | ||||
|  | ||||
| Extract Constant ascii_comparable => "(=)". | ||||
| Extract Constant lt_int_decidable => "(<)". | ||||
| Extract Constant le_int_decidable => "(<=)". | ||||
| Extract Constant ge_nat_decidable => "(>=)". | ||||
|  | ||||
| (* TODO ARTHUR:  This TLC lemma does not extract to something computable... whereas it should! *) | ||||
| Extract Constant prop_eq_decidable => "(=)". | ||||
|  | ||||
| Extract Constant env_loc_global_env_record => "0". | ||||
|  | ||||
| (* The following functions make pattern matches with floats and shall thus be removed. *) | ||||
| Extraction Inline Fappli_IEEE.Bplus Fappli_IEEE.binary_normalize Fappli_IEEE_bits.b64_plus. | ||||
| Extraction Inline Fappli_IEEE.Bmult Fappli_IEEE.Bmult_FF Fappli_IEEE_bits.b64_mult. | ||||
| Extraction Inline Fappli_IEEE.Bdiv Fappli_IEEE_bits.b64_div. | ||||
|  | ||||
| (* New options for the interpreter to work in Coq 8.4 *) | ||||
| Set Extraction AccessOpaque. | ||||
|  | ||||
| (* These parameters are implementation-dependant according to the spec. | ||||
|    I've chosed some very simple values, but we could choose another thing for them. *) | ||||
| Extract Constant object_prealloc_global_proto => "(Coq_value_prim Coq_prim_null)". | ||||
| Extract Constant object_prealloc_global_class => "( | ||||
|   let rec aux s = function | ||||
|   | 0 -> [] | ||||
|   | n -> let n' = n - 1 in | ||||
|     s.[n'] :: aux s n' | ||||
|   in let aux2 s = | ||||
|     List.rev (aux s (String.length s)) | ||||
|   in aux2 ""GlobalClass"")". | ||||
|  | ||||
|  | ||||
| (* Parsing *) | ||||
| Extract Constant parse_pickable => "(fun s strict -> | ||||
|     let str = String.concat """" (List.map (String.make 1) s) in | ||||
|     try | ||||
|       let parserExp = Parser_main.exp_from_string ~force_strict:strict str in | ||||
|       Some (JsSyntaxInfos.add_infos_prog strict | ||||
|         (Translate_syntax.exp_to_prog parserExp)) | ||||
|     with | ||||
|     (* | Translate_syntax.CoqSyntaxDoesNotSupport _ -> assert false (* Temporary *) *) | ||||
|     | Parser.ParserFailure _ | ||||
|     | Parser.InvalidArgument -> | ||||
|       prerr_string (""Warning:  Parser error on eval.  Input string:  \"""" ^ str ^ ""\""\n""); | ||||
|       None | ||||
|   )". | ||||
|  | ||||
|  | ||||
| (* Debugging *) | ||||
| Extract Inlined Constant not_yet_implemented_because => "(fun s -> | ||||
|   print_endline (__LOC__ ^ "": Not implemented because: "" ^ Prheap.string_of_char_list s) ; | ||||
|   Coq_result_not_yet_implemented)". | ||||
| Extract Inlined Constant impossible_because => "(fun s -> | ||||
|   print_endline (__LOC__ ^ "": Stuck because: "" ^ Prheap.string_of_char_list s) ; | ||||
|   Coq_result_impossible)". | ||||
| Extract Inlined Constant impossible_with_heap_because => "(fun s message -> | ||||
|   print_endline (__LOC__ ^ "": Stuck!\nState:  "" ^ Prheap.prstate true s | ||||
|     ^ ""\nMessage:\t"" ^ Prheap.string_of_char_list message) ; | ||||
|   Coq_result_impossible)". | ||||
|  | ||||
|  | ||||
| (* Final Extraction *) | ||||
| Extraction Blacklist string list bool. | ||||
| Separate Extraction runs run_javascript. | ||||
|  | ||||
|  | ||||
|  | ||||
| (* -- LATER: extract inequality_test_string in more efficient way*) | ||||
|  | ||||
							
								
								
									
										1051
									
								
								samples/Coq/JsNumber.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1051
									
								
								samples/Coq/JsNumber.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1766
									
								
								samples/Coq/JsPrettyInterm.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1766
									
								
								samples/Coq/JsPrettyInterm.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										42
									
								
								samples/Coq/Main.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								samples/Coq/Main.v
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| Require Import FunctionNinjas.All. | ||||
| Require Import ListString.All. | ||||
| Require Import Computation. | ||||
|  | ||||
| Import C.Notations. | ||||
|  | ||||
| Definition error (message : LString.t) : C.t := | ||||
|   do_call! Command.ShowError message in | ||||
|   ret. | ||||
|  | ||||
| Definition main : C.t := | ||||
|   call! card_is_valid := Command.AskCard in | ||||
|   if card_is_valid then | ||||
|     call! pin := Command.AskPIN in | ||||
|     match pin with | ||||
|     | None => error @@ LString.s "No PIN given." | ||||
|     | Some pin => | ||||
|       call! pin_is_valid := Command.CheckPIN pin in | ||||
|       if pin_is_valid then | ||||
|         call! ask_amount := Command.AskAmount in | ||||
|         match ask_amount with | ||||
|         | None => error @@ LString.s "No amount given." | ||||
|         | Some amount => | ||||
|           call! amount_is_valid := Command.CheckAmount amount in | ||||
|           if amount_is_valid then | ||||
|             call! card_is_given := Command.GiveCard in | ||||
|             if card_is_given then | ||||
|               call! amount_is_given := Command.GiveAmount amount in | ||||
|               if amount_is_given then | ||||
|                 ret | ||||
|               else | ||||
|                 error @@ LString.s "Cannot give you the amount. Please contact your bank." | ||||
|             else | ||||
|               error @@ LString.s "Cannot give you back the card. Please contact your bank." | ||||
|           else | ||||
|             error @@ LString.s "Invalid amount." | ||||
|         end | ||||
|       else | ||||
|         error @@ LString.s "Invalid PIN." | ||||
|     end | ||||
|   else | ||||
|     error @@ LString.s "Invalid card.". | ||||
							
								
								
									
										62
									
								
								samples/Coq/Spec.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								samples/Coq/Spec.v
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| (** Specifications. *) | ||||
| Require Import Coq.Lists.List. | ||||
| Require Import Coq.Strings.Ascii. | ||||
| Require Import FunctionNinjas.All. | ||||
| Require Import ListString.All. | ||||
| Require Import Computation. | ||||
|  | ||||
| Import ListNotations. | ||||
| Local Open Scope char. | ||||
|  | ||||
| (** A run is an execution of the program with explicit answers for the | ||||
|     system calls. *) | ||||
| Module Run. | ||||
|   (** We define a run by induction on the structure of a computation. *) | ||||
|   Inductive t : C.t -> Type := | ||||
|   | Ret : t C.Ret | ||||
|   | Call : forall (command : Command.t) (answer : Command.answer command) | ||||
|     {handler : Command.answer command -> C.t}, t (handler answer) -> | ||||
|     t (C.Call command handler). | ||||
|  | ||||
|   (** The trace of a run. *) | ||||
|   Fixpoint trace {x : C.t} (run : t x) | ||||
|     : list {command : Command.t & Command.answer command} := | ||||
|     match run with | ||||
|     | Ret => [] | ||||
|     | Call command answer _ run => existT _ command answer :: trace run | ||||
|     end. | ||||
| End Run. | ||||
|  | ||||
| Module Temporal. | ||||
|   Module All. | ||||
|     Inductive t (P : Command.t -> Prop) : C.t -> Prop := | ||||
|     | Ret : t P C.Ret | ||||
|     | Call : forall (c : Command.t) (h : Command.answer c -> C.t), | ||||
|       P c -> (forall a, t P (h a)) -> | ||||
|       t P (C.Call c h). | ||||
|   End All. | ||||
|  | ||||
|   Module One. | ||||
|     Inductive t (P : Command.t -> Prop) : C.t -> Prop := | ||||
|     | CallThis : forall (c : Command.t) (h : Command.answer c -> C.t), | ||||
|       P c -> | ||||
|       t P (C.Call c h) | ||||
|     | CallOther : forall (c : Command.t) (h : Command.answer c -> C.t), | ||||
|       (forall a, t P (h a)) -> | ||||
|       t P (C.Call c h). | ||||
|   End One. | ||||
|  | ||||
|   Module Then. | ||||
|     Inductive t (P1 P2 : Command.t -> Prop) : C.t -> Prop := | ||||
|     | Ret : t P1 P2 C.Ret | ||||
|     | Call : forall (c : Command.t) (h : Command.answer c -> C.t), | ||||
|       (forall a, t P1 P2 (h a)) -> | ||||
|       t P1 P2 (C.Call c h) | ||||
|     | CallThen : forall (c : Command.t) (h : Command.answer c -> C.t), | ||||
|       P1 c -> (forall a, One.t P2 (h a)) -> | ||||
|       t P1 P2 (C.Call c h). | ||||
|   End Then. | ||||
| End Temporal. | ||||
|  | ||||
| Module CardBeforeMoney. | ||||
| End CardBeforeMoney. | ||||
		Reference in New Issue
	
	Block a user