Advertisement
Guest User

ti hui blia

a guest
Jan 4th, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 19.58 KB | None | 0 0
  1. open Tree;;
  2.  
  3. let rec  write_to_string expression =
  4.     let token = expression in
  5.         match token with
  6.             | Application (a,b) ->      "(" ^ (write_to_string a) ^ " " ^ (write_to_string b) ^ ")"
  7.  
  8.             | Abstraction (a,b) ->      (String.concat "" ["(\\";a;"."]) ^ (write_to_string b) ^ ")"
  9.  
  10.             | Variable(a)       ->      a;;
  11.  
  12. module AlgebraMap = Map.Make(String);;
  13.  
  14. module AbstractVar = Map.Make(String);;
  15.  
  16. type algebra =  Var of string (* constant *)
  17.             |   Func of string * algebra * algebra (* for expression like -> smth smth *);;
  18.  
  19. type tmp_derivation =   BuildTypeVar of algebra
  20.                         | BuildTypeAbstr of algebra * algebra * tmp_derivation
  21.                         | BuildTypeAppl of algebra * algebra * algebra * tmp_derivation * tmp_derivation ;;
  22.  
  23. let common_variable = "a";;
  24.  
  25. let custom_merge a b = List.rev_append a b;;
  26.  
  27. let rec algebra_to_string expression =
  28.     let token = expression in
  29.         match token with
  30.             | Var(a) -> a
  31.             | Func(a, b , c) -> String.concat "" ["(" ; (algebra_to_string b) ; a ; (algebra_to_string c); ")"];;
  32.  
  33.  
  34.  
  35. let update_variable var =
  36.     let last = (String.length var) - 1 in
  37.         let symb = String.get var last in
  38.             match symb with
  39.                 | 'z'   ->   var ^ "a"
  40.                 | _     ->   let new_var = String.sub var 0 last  in
  41.                                 let new_var = new_var ^ Char.escaped (Char.chr ((Char.code symb) + 1) ) in
  42.                                     new_var;;
  43.  
  44.  let rec build_system expression free_var abstaction_name unbound_names =
  45.     let token = expression in
  46.         match token with
  47.             | Application (a, b) ->  let union_a, term_a, last_map_a, last_unbound_map_a, last_var_a, derivation_a =  build_system a free_var abstaction_name unbound_names in
  48.                                         let  union_b, term_b, last_map_b, last_unbound_map_b, last_var_b, derivation_b = build_system b last_var_a abstaction_name last_unbound_map_a in
  49.                                             let new_var = update_variable last_var_b in
  50.                                                 let merged_equation = custom_merge union_a union_b in
  51.                                                     let merged_map = AbstractVar.fold AbstractVar.add last_map_a last_map_b in
  52.                                                         let algebra_type = Func ("->", term_b, Var(new_var)) in
  53.                                                             let derivation = BuildTypeAppl(term_a, term_b, Var new_var, derivation_a, derivation_b) in
  54.                                                                 let added_equation = merged_equation @ [(term_a, algebra_type)] in
  55.                                                                     (added_equation, Var(new_var), merged_map, last_unbound_map_b, new_var, derivation)
  56.  
  57.             | Abstraction (a, b) ->     let new_free_var = update_variable free_var in
  58.                                             let updated_map = AbstractVar.add a new_free_var abstaction_name in
  59.                                                 let union_b, term_b, last_map_b, last_unbound_map_b, last_var_b, deriavtion_b = build_system b new_free_var updated_map unbound_names in
  60.                                                     let new_var = update_variable last_var_b in
  61.                                                         let algebra_type = Func ("->", Var new_free_var, term_b) in
  62.                                                             let derivation = BuildTypeAbstr(Var new_free_var, term_b, deriavtion_b) in
  63.                                                                 (union_b, algebra_type, last_map_b, last_unbound_map_b, new_var, derivation)
  64.  
  65.             | Variable (a)       ->     let contains_variable = AbstractVar.mem a abstaction_name in
  66.                                             if contains_variable then
  67.                                                 let variable_name = AbstractVar.find a abstaction_name in
  68.                                                     let algebra_type = Var(variable_name) in
  69.                                                         ([], algebra_type, abstaction_name, unbound_names, free_var, BuildTypeVar algebra_type)
  70.                                             else
  71.                                                 let unbound_var = AbstractVar.mem a unbound_names in
  72.                                                     match unbound_var with
  73.                                                     | true -> let var_name = AbstractVar.find a unbound_names in
  74.                                                                 let algebra_type = Var var_name in
  75.                                                                     ([], algebra_type, abstaction_name, unbound_names, free_var, BuildTypeVar algebra_type)
  76.                                                     | false -> let new_var = update_variable free_var in
  77.                                                                     let added_bound_names = AbstractVar.add a new_var unbound_names in
  78.                                                                             let algebra_type = Var(new_var) in
  79.                                                                                 ([], algebra_type, abstaction_name, added_bound_names, new_var, BuildTypeVar algebra_type);;
  80.  
  81. let encure_array eq_system =
  82.     let double_list = List.map (fun x-> (x,(fst x, snd x))) eq_system in
  83.         let la, lb = List.split double_list in
  84.             List.rev_append la lb;;
  85.  
  86. let is_var equation =
  87.     match  equation with
  88.         | Var(a) -> true
  89.         | _ -> false;;
  90.  
  91. let second_action item =
  92.     if (not (is_var (fst item))) && (not (is_var (snd item))) then
  93.         match item with
  94.         | Func(a, b, c), Func(d, e, f) ->   [(b, e); (c, f)]
  95.         | _ -> []
  96.     else
  97.         [item];;
  98.  
  99. let rec num_of_vars equation map_of_vars =
  100.     match equation with
  101.     | Var(a) -> if AbstractVar.mem a map_of_vars then
  102.                             let num  = AbstractVar.find a map_of_vars in
  103.                                     AbstractVar.add a (num + 1) map_of_vars
  104.                         else AbstractVar.add a 1 map_of_vars
  105.     | Func(a, b, c) -> let left_map = num_of_vars b map_of_vars in
  106.                             let right_map = num_of_vars c left_map in
  107.                                 right_map;;
  108. let available_map equations =
  109.     List.filter (fun x -> let left, right  = x in
  110.                     match left with
  111.                     | Var(a) -> true
  112.                     | _ -> false) equations;;
  113.  
  114. let rec replace_var_in_expression expression variable template =
  115.     match expression with
  116.     | Var(a) -> if Var (a) = variable then template else Var(a)
  117.     | Func(a,b,c) -> let left_replace = if b = variable then template else replace_var_in_expression b variable template in
  118.                         let right_replace = if c = variable then template else replace_var_in_expression c variable template in
  119.                                Func(a,left_replace,right_replace)
  120.                                ;;
  121.  
  122. let rec check_exist_recursion variable equations =
  123.     match equations with
  124.     | Var(a) -> Var(a) = variable
  125.     | Func(a,b,c) -> let left = check_exist_recursion variable b in
  126.                         let right = check_exist_recursion variable c in
  127.                             left || right;;
  128.  
  129. let rec check_same_derivation equations =
  130.     match equations with
  131.     | [] -> true
  132.     | _ -> let left,right = List.hd equations in
  133.                 let tail = List.tl equations in
  134.                     match left with
  135.                     | Var(a) -> let result = check_exist_recursion (Var a) right in
  136.                                     if  result then false else check_same_derivation tail
  137.                     | _ -> check_same_derivation tail;;
  138.  
  139. let rec help_delete_repeat left right equations =
  140.     match equations with
  141.     | [] -> []
  142.     | _ -> let head_left, head_right =  List.hd equations in
  143.                 let tail = List.tl equations in
  144.                     if head_left = left && head_right = right then
  145.                         help_delete_repeat left right tail
  146.                     else
  147.                         [(head_left, head_right)] @ (help_delete_repeat left right tail);;
  148.  
  149. let rec delete_repeat equations =
  150.     match equations with
  151.     | [] -> []
  152.     | _ -> let head_left, head_right =  List.hd equations in
  153.                 let tail = List.tl equations in
  154.                     let result_delete = help_delete_repeat head_left head_right tail in
  155.                         [(head_left, head_right)] @ (delete_repeat result_delete);;
  156.  
  157. let fourth_action_replace variable template equations =
  158.     List.map (fun item ->
  159.                     let left, right = item in
  160.                         if left = variable && right = template then
  161.                             item
  162.                         else
  163.                             (replace_var_in_expression left variable template,
  164.                              replace_var_in_expression right variable template)
  165.              ) equations;;
  166.  
  167. let fourth_action equations =
  168.     let current_map = AbstractVar.empty in
  169.         let tmp_map_list = List.map (fun item ->
  170.                                         let em_map = AbstractVar.empty in
  171.                                             let left_map = num_of_vars (fst item) em_map in
  172.                                                 let right_map = num_of_vars (snd item) left_map in
  173.                                                         right_map
  174.                                     ) equations in
  175.                 let result_map = List.fold_left (fun a b -> AbstractVar.merge (fun _ k1 k2 -> match k1, k2 with
  176.                                                                                 | Some v, Some u -> Some(u + v)
  177.                                                                                 | None, None -> None
  178.                                                                                 | None, k2 -> k2
  179.                                                                                 | k1, None -> k1
  180.                                                                               ) a b) (AbstractVar.empty) tmp_map_list in
  181.                     let filtered_map = AbstractVar.filter (fun k v -> v > 1) result_map in
  182.                         let list_of_vars_term = available_map equations in
  183.                             let filtered_list = List.filter (fun item -> let lft, rght = item in
  184.                                                                 match lft with
  185.                                                                 | Var(a) -> AbstractVar.mem a filtered_map
  186.                                                                 | _ -> false
  187.                                                             ) list_of_vars_term in
  188.                                             let num_of_can_vars = List.length filtered_list in
  189.                                                 match num_of_can_vars with
  190.                                                 | 0 -> equations
  191.                                                 | _ -> let var, template = List.hd filtered_list in
  192.                                                             fourth_action_replace var template equations;;
  193.  
  194. let rec help_calculate_num_of_vars expr mp =
  195.     match expr with
  196.     | Var(a) -> if AbstractVar.mem a mp then
  197.                     let num = AbstractVar.find a mp in
  198.                         AbstractVar.add a (num + 1) mp
  199.                 else
  200.                     AbstractVar.add a 1 mp
  201.     | Func(a, b, c) -> let result_b = help_calculate_num_of_vars b mp in
  202.                             let result_c = help_calculate_num_of_vars c result_b in
  203.                                 result_c;;
  204.  
  205.  
  206. let rec help_is_solved_form expression right_var =
  207.     match expression with
  208.     | Var(a) -> AbstractVar.add a 1 right_var
  209.     | Func(a, b, c) -> let left = help_is_solved_form b right_var in
  210.                             let right = help_is_solved_form c left in
  211.                                 right;;
  212.  
  213. let rec is_solved_form equations var_map num_of_var_in_right =
  214.     match equations with
  215.     | [] -> true
  216.     | _  -> let head = List.hd equations in
  217.                 let  tail = List.tl equations in
  218.                     let left, right = head in
  219.                         let calc_right_var = help_is_solved_form right num_of_var_in_right in
  220.                             match left with
  221.                             | Var(a) -> let contains = AbstractVar.mem a var_map in
  222.                                             if contains then
  223.                                                 false
  224.                                             else
  225.                                                 let exist_in_right = AbstractVar.mem a calc_right_var in
  226.                                                     if exist_in_right then
  227.                                                         false
  228.                                                     else
  229.                                                         is_solved_form tail (AbstractVar.add a 1 var_map) calc_right_var
  230.                             | Func(a, b, c) -> false;;
  231.  
  232. let rec solve_equations equations =
  233.     (*term = var -> var = term*)
  234.     let first = List.map (fun item -> if (not (is_var (fst item))) && (is_var (snd item)) then ((snd item), (fst item)) else item) equations in
  235.         (*term = term -> [equiv_1..equiv_n]*)
  236.         let second = List.fold_left (fun a b -> a @ b) [] (List.map second_action first) in
  237.             (* if Var(a) = Var(b) -> remove them *)
  238.             let delete_equal = List.filter
  239.                 (
  240.                     fun item -> match item with
  241.                         | Var(a), Var(b) -> if a=b then false else true
  242.                         | _ -> true
  243.                 ) second in
  244.                     (* replace all occur variable more than one time*)
  245.                     let exist_recursion = check_same_derivation delete_equal in
  246.                         if not exist_recursion then
  247.                             (false, delete_equal)
  248.                         else
  249.                             let deleted_repeat = delete_repeat delete_equal in
  250.                             let fourth = fourth_action deleted_repeat in
  251.                                 let compare = is_solved_form fourth (AbstractVar.empty) (AbstractVar.empty) in
  252.                                     match compare with
  253.                                         | false ->  solve_equations fourth
  254.                                         | true ->   (true, fourth);;
  255.  
  256. let make_map_from_list solved_equations =
  257.     List.fold_left (fun mp it->
  258.                     let left, right = it in
  259.                     match left with
  260.                     | Var(a) -> AbstractVar.add a right mp
  261.                    ) AbstractVar.empty solved_equations;;
  262.  
  263. let rec replace_in_type map_solved_equations expression_type =
  264.     match expression_type with
  265.     | Var(a) -> if AbstractVar.mem a map_solved_equations then
  266.                     AbstractVar.find a map_solved_equations
  267.                 else
  268.                     Var a
  269.     | Func(a, b, c) -> let left = replace_in_type map_solved_equations b in
  270.                             let right = replace_in_type map_solved_equations c in
  271.                                 Func (a, left, right);;
  272.  
  273. let repeat_stars n =
  274.     String.concat "" (Array.to_list (Array.make n "*   "));;
  275.  
  276.  
  277. let rec constuct_type map_solved_equations unbounded_names expression derivation bounded_names depth =
  278.     let unbounded = AbstractVar.fold (fun k v lst -> lst @ [(k ^ " : " ^ (algebra_to_string v))] ) unbounded_names [] in
  279.     let bounded = AbstractVar.fold (fun k v lst -> lst @ [(k ^ " : " ^ (algebra_to_string v))] ) bounded_names unbounded in
  280.     let list_of_left = String.concat ", " bounded in
  281.         print_string (repeat_stars depth);
  282.         print_string list_of_left;
  283.         print_string " |- ";
  284.         match expression, derivation with
  285.         | Variable(a), BuildTypeVar(tp) -> (let exist = AbstractVar.mem a unbounded_names in
  286.                                                 match exist with
  287.                                                 | true ->   let right = AbstractVar.find a unbounded_names in
  288.                                                     print_string (a ^ " : " ^ (algebra_to_string right));
  289.                                                 | false ->  let right = replace_in_type map_solved_equations tp in
  290.                                                     print_string (a ^ " : " ^ (algebra_to_string right));
  291.                                             );
  292.                                             print_string " [rule #1]\n"
  293.  
  294.         | Abstraction(a, b), BuildTypeAbstr(tp_a, tp_b, tp_inner) -> let tp_a_repl = replace_in_type map_solved_equations tp_a in
  295.                                                                         let tp_b_repl = replace_in_type map_solved_equations tp_b in
  296.                                                                             let abstraction = Func("->",tp_a_repl, tp_b_repl) in
  297.                                                                                 let abst_string = write_to_string (Abstraction(a,b)) in
  298.                                                                                     print_string (abst_string ^ " : " ^ (algebra_to_string abstraction));
  299.                                                                                     print_string " [rule #3]\n";
  300.                                                                                     constuct_type map_solved_equations unbounded_names b tp_inner (AbstractVar.add a tp_a_repl bounded_names) (depth + 1)
  301.         | Application(a, b), BuildTypeAppl(tp_a, tp_b, tp_c, tp_in_a, tp_in_b)  -> let tp_a_repl = replace_in_type map_solved_equations tp_a in
  302.                                                                                         let tp_b_repl = replace_in_type map_solved_equations tp_b in
  303.                                                                                             let tp_c_repl = replace_in_type map_solved_equations tp_c in
  304.                                                                                                 let appl_string = write_to_string (Application (a,b)) in
  305.                                                                                                     print_string (appl_string ^ " : " ^ (algebra_to_string tp_c_repl));
  306.                                                                                                     print_string " [rule #2]\n";
  307.                                                                                                     constuct_type map_solved_equations unbounded_names a tp_in_a bounded_names (depth + 1);
  308.                                                                                                     constuct_type map_solved_equations unbounded_names b tp_in_b bounded_names (depth + 1);;
  309.  
  310. let e = Lexing.from_channel stdin;;
  311. let d = (Parser.lambdaParser Lexer.main)  e;;
  312.  
  313.  
  314. let empty_bounded_names = AbstractVar.empty;;
  315. let emplty_unbounded_names = AbstractVar.empty;;
  316. let my_equitatins, lambda_type, bounded_names, unbounded_names, last_free_name, result_derivation = build_system d common_variable empty_bounded_names emplty_unbounded_names;;
  317.  
  318. let ok,eq =  solve_equations my_equitatins;;
  319.  
  320. match ok with
  321.     | true ->
  322.                  let maped_eq = make_map_from_list eq in
  323.                  let solved_unbound_variabes = AbstractVar.map (fun v -> replace_in_type maped_eq (Var v))  unbounded_names in
  324.                     constuct_type maped_eq solved_unbound_variabes d result_derivation (AbstractVar.empty) 0
  325.  
  326.     | false ->  Printf.printf "Expression has no type\n"
  327. ;;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement