Advertisement
Guest User

Untitled

a guest
Mar 16th, 2019
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 9.36 KB | None | 0 0
  1. let nip str = String.sub str 1 ((String.length str) - 1);;
  2.  
  3. type expr = Var of string | Not of expr | And of (expr * expr) | Or of (expr * expr) | Conj of (expr * expr);;
  4.  
  5. let rec print_expr expr = match expr with
  6.     | Var a       -> a
  7.     | Not a       -> "!" ^ (print_expr a) ^ ""
  8.     | And  (a, b) -> "(" ^ (print_expr a) ^ "&" ^ (print_expr b) ^ ")"
  9.     | Or   (a, b) -> "(" ^ (print_expr a) ^ "|" ^ (print_expr b) ^ ")"
  10.     | Conj (a, b) -> "(" ^ (print_expr a) ^ "->" ^ (print_expr b) ^ ")";;
  11.  
  12. let strange = "'";;
  13.  
  14. let checkOnFence str = String.length str > 2 && str.[0] = '|' && str.[1] = '-';;
  15.  
  16. let rec make_var str have = if String.length str == 0
  17.     then (Var have, str)
  18.     else if String.length str >= String.length strange && String.sub str 0 (String.length strange) = strange
  19.     then make_var (String.sub str (String.length strange) (String.length str - String.length strange)) (have ^ strange)
  20.     else match str.[0] with
  21.     | 'A'..'Z' | '0'..'9' -> make_var (nip str) (have ^ Char.escaped str.[0])
  22.     | _                   -> (Var have, (String.trim str))
  23.  
  24. and make_nnot str = match str.[0] with
  25.     | '!'      -> let (item, str) = make_nnot (String.trim (nip str)) in (Not item, str)
  26.     | 'A'..'Z' -> let (item, str) = make_var  (nip str) (Char.escaped str.[0]) in (item, str)
  27.     | '('      -> let (item, str) = make_expr (String.trim (nip str)) in (item, (String.trim (nip str)))
  28.     | _        -> failwith "Error4"
  29.  
  30. and make_aand str = let (item, str) = make_nnot str in
  31.     let rec make_aand_internal str have =
  32.         if String.length str == 0 || checkOnFence str then (have, str)
  33.         else
  34.         match str.[0] with
  35.         | '&' -> let (item, str) = make_nnot (String.trim (nip str)) in make_aand_internal str (And (have, item))
  36.         | ')' | '|' | '-' | ',' -> (have, str)
  37.         | _   -> failwith "Error1"
  38.     in make_aand_internal str item
  39.  
  40. and make_oor str = let (item, str) = make_aand str in
  41.     let rec make_oor_internal str have =
  42.         if String.length str == 0 || checkOnFence str then (have, str)
  43.         else
  44.         match str.[0] with
  45.         | '|' -> let (item, str) = make_aand (String.trim (nip str)) in make_oor_internal str (Or (have, item))
  46.         | ')' | '-' | ',' -> (have, str)
  47.         | _   -> failwith "Error2"
  48.     in make_oor_internal str item
  49.        
  50. and make_expr str = let (item, str) = make_oor str in
  51.     if String.length str == 0 || checkOnFence str
  52.     then (item, str)
  53.     else match str.[0] with
  54.         | '-' -> let (item2, str) = make_expr (String.trim (nip (nip str))) in (Conj (item, item2), str)
  55.         | ')' | ',' -> (item, str)
  56.         | _   -> failwith "Error3";;
  57.        
  58. let parse_expr str = let (a, _) = make_expr (String.trim str) in a;;
  59.  
  60. let rec make_context str =
  61.     let (first, str) = make_expr (String.trim str) in
  62.     let str = String.trim str in
  63.     match str.[0] with
  64.         | ',' -> let (lst, str) = make_context (String.trim (nip str)) in (first :: lst, str)
  65.         | _   -> ([first], str);;
  66.  
  67. type need = Need of expr list * expr;;
  68.  
  69. let make_first_expr str =
  70.     let (context, str) =
  71.         if str.[0] = '|' then ([], str) else make_context str in
  72.     let str = String.trim (nip (nip (String.trim str))) in
  73.     let (expr, _) = make_expr str in Need (context, expr);;
  74.    
  75. let (>>=) x f = match x with
  76.     | Some a -> f a
  77.     | None   -> None;;
  78.  
  79. let takeMon x y = match x with
  80.     | Some a -> a
  81.     | None   -> y;;
  82.  
  83. let rNone x y = None;;
  84. let rNone2 a b y = None;;
  85.    
  86. let checkExpr f1 f2 f3 f4 f5 expr = match expr with
  87.     | Var a       -> f1 a
  88.     | Not a       -> f2 a
  89.     | And  (a, b) -> f3 a b
  90.     | Or   (a, b) -> f4 a b
  91.     | Conj (a, b) -> f5 a b;;
  92. let checkVar (proj, setter) expr took = match proj took with
  93.     | None   -> Some (setter took (Some expr))
  94.     | Some a -> if a = expr then Some took else None;;
  95. let checkNot  f = checkExpr rNone f rNone2 rNone2 rNone2;;
  96. let checkAnd  f = checkExpr rNone rNone f rNone2 rNone2;;
  97. let checkOr   f = checkExpr rNone rNone rNone2 f rNone2;;
  98. let checkConj f = checkExpr rNone rNone rNone2 rNone2 f;;
  99.    
  100. let l1 = (fun (a, _, _) -> a), fun (_, b, c) a -> (a, b, c);;
  101. let l2 = (fun (_, a, _) -> a), fun (a, _, c) b -> (a, b, c);;
  102. let l3 = (fun (_, _, a) -> a), fun (a, b, _) c -> (a, b, c);;
  103.                    
  104. let rec print_expr_ expr = match expr with
  105.     | Var a -> let linz = match a with
  106.         | "A" -> l1
  107.         | "B" -> l2
  108.         | _   -> l3 in checkVar linz
  109.     | Not a       -> checkNot  (print_expr_ a)
  110.     | And  (a, b) -> checkAnd  (fun left right x -> print_expr_ a left x >>= (print_expr_ b right))
  111.     | Or   (a, b) -> checkOr   (fun left right x -> print_expr_ a left x >>= (print_expr_ b right))
  112.     | Conj (a, b) -> checkConj (fun left right x -> print_expr_ a left x >>= (print_expr_ b right))
  113.  
  114. let axioms = List.map (fun x -> print_expr_ (parse_expr x))
  115. (       "A -> B -> A" ::
  116.         "(A -> B) -> (A -> B -> C) -> (A -> C)" ::
  117.         "A -> B -> A & B" ::
  118.         "A & B -> A" ::
  119.         "A & B -> B" ::
  120.         "A -> A | B" ::
  121.         "B -> A | B" ::
  122.         "(A -> B) -> (C -> B) -> (A | C -> B)" ::
  123.         "(A -> B) -> (A -> !B) -> !A" ::
  124.         "!!A -> A":: []);;
  125.        
  126. module ExprMap = Map.Make(struct type t = expr let compare = compare end);;
  127.        
  128. let list_find_opt f l = try Some (List   .find f l) with _ -> None;;
  129. let map_find_opt  k m = try Some (ExprMap.find k m) with _ -> None;;
  130.  
  131. let checkAxioms to_check = let rec func lst = match lst with
  132.     | None :: rem_ -> func rem_
  133.     | Some a :: _  -> Some a
  134.     | _            -> None in
  135.     func (List.mapi (fun ind chain -> chain to_check (None, None, None) >>= (fun _ -> Some ind)) axioms);;
  136.  
  137. type node = Axiom of (expr * int) | MP of (expr * node * node) | Context of (expr * int);;
  138.  
  139. let checkEverything context need evidence =
  140.     let contextMap = List.fold_right (fun (x, ind) mp -> ExprMap.add x ind mp) (List.mapi (fun ind x -> (x, ind)) context) ExprMap.empty in
  141.     let rec checkStepByStep alreadyHadMap possibleMap evidenceMap lst =
  142.         match lst with
  143.             | [] -> None
  144.             | now :: rem_list ->
  145.         let the_node = match map_find_opt now possibleMap with
  146.         | Some the_node -> Some the_node
  147.         | None -> match checkAxioms now with
  148.         | Some ind -> Some (Axiom (now, ind))
  149.         | None -> match map_find_opt now contextMap with
  150.         | Some ind -> Some (Context (now, ind))
  151.         | None -> None in
  152.         if now = need
  153.         then the_node
  154.         else
  155.         the_node >>= fun the_node ->
  156.             let to_add = List.map (fun (_expr, _node) -> (_expr, MP (_expr, _node, the_node))) (ExprMap.fold (fun x y have -> (x, y) :: have) (takeMon (map_find_opt now evidenceMap) ExprMap.empty) []) in
  157.             let evidenceMap = ExprMap.remove now evidenceMap in
  158.             let (smth_to_add, new_evidenceMap) = match now with
  159.                 | Conj (a, b) -> (match map_find_opt a alreadyHadMap with
  160.                     | Some the_node1 -> ([(b, MP (b, the_node, the_node1))], evidenceMap)
  161.                     | _ -> ([], ExprMap.add a (ExprMap.add b the_node (takeMon (map_find_opt a evidenceMap) ExprMap.empty)) evidenceMap))
  162.                 | _ -> ([], evidenceMap) in
  163.             let new_list = List.concat (smth_to_add :: to_add :: []) in
  164.             let new_possibleMap = List.fold_right (fun (x, y) mp -> ExprMap.add x y mp) new_list possibleMap in
  165.             let new_alreadyHadMap = ExprMap.add now the_node alreadyHadMap in
  166.             checkStepByStep new_alreadyHadMap new_possibleMap new_evidenceMap rem_list in
  167.     checkStepByStep ExprMap.empty ExprMap.empty ExprMap.empty evidence;;
  168.    
  169. let rec printNodeImpl node mp nxt = match node with
  170.     | Axiom   (expr_, num) -> (match map_find_opt expr_ mp with
  171.         | Some line -> ("", mp, line, nxt)
  172.         | None      -> ("[" ^ string_of_int nxt ^ ". Ax. sch. " ^ string_of_int (num + 1) ^ "] " ^ print_expr expr_ ^ "\n", ExprMap.add expr_ nxt mp, nxt, nxt + 1))
  173.     | Context (expr_, num) -> (match map_find_opt expr_ mp with
  174.         | Some line -> ("", mp, line, nxt)
  175.         | None      -> ("[" ^ string_of_int nxt ^ ". Hypothesis " ^ string_of_int (num + 1) ^ "] " ^ print_expr expr_ ^ "\n", ExprMap.add expr_ nxt mp, nxt, nxt + 1))
  176.     | MP (expr_, node1, node2) -> (match map_find_opt expr_ mp with
  177.         | Some line -> ("", mp, line, nxt)
  178.         | None      ->
  179.             let (result1, mp, line1, nxt) = printNodeImpl node1 mp nxt in
  180.             let (result2, mp, line2, nxt) = printNodeImpl node2 mp nxt in
  181.             (result1 ^ result2 ^ "[" ^ string_of_int(nxt) ^ ". M.P. " ^ (string_of_int line1) ^ ", " ^ (string_of_int line2) ^ "] " ^ print_expr expr_ ^ "\n", ExprMap.add expr_ nxt mp, nxt, nxt + 1));;
  182.        
  183. let printNode the_node = let (res, _, _, _) = printNodeImpl the_node ExprMap.empty 1 in res;;
  184.        
  185. let make_evidence lines = match lines with
  186.     | []                        -> failwith "Error blyat!"
  187.     | first_line :: other_lines ->
  188.         let Need (context, expr) = make_first_expr first_line in
  189.         let other_expr = List.map parse_expr other_lines in
  190.         match checkEverything context expr other_expr with
  191.             | None   -> "Proof is incorrect"
  192.             | Some a -> first_line ^ "\n" ^ printNode a;;
  193.        
  194. let rec mainImpl () =
  195.     try let cur = input_line stdin in cur :: mainImpl () with _ -> [];;
  196.    
  197. print_string (make_evidence (mainImpl ()));;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement