Advertisement
Guest User

Untitled

a guest
Nov 14th, 2019
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 3.64 KB | None | 0 0
  1. open Grammar
  2. open Hashtbl
  3. open Scanf
  4. open Utils
  5. open String
  6. open List
  7.  
  8. open Grammar
  9.  
  10. module Set = Set.Make(String)
  11.  
  12. let rec print_expr expr = match expr with
  13.     | Var (Id v) -> v
  14.     | Appl (t1, t2) -> "(" ^ print_expr t1 ^ " " ^ print_expr t2 ^ ")"
  15.     | Abst (Id x, t) -> "(\\" ^ x ^ "." ^ print_expr t ^ ")"
  16.  
  17. let rec fill_set_with_vars_from_term term mySet = match term with
  18.     | Abst (Id x, t) -> fill_set_with_vars_from_term t (Set.add x mySet)
  19.     | Appl (t1, t2)  -> Set.union (fill_set_with_vars_from_term t1 mySet) (fill_set_with_vars_from_term t2 mySet)
  20.     | Var (Id v)     -> if Set.mem v mySet then Set.empty else Set.singleton v
  21.  
  22.  
  23. let beta_reduction term1 var term2 =
  24.   let filledSet = fill_set_with_vars_from_term term2 Set.empty in
  25.     let namesHashtbl = Hashtbl.create 100 in
  26.       let rec reduce tree flag = match tree with
  27.         | Appl (t1, t2)  -> Appl (reduce t1 flag, reduce t2 flag)
  28.         | Abst (Id x, t) -> if x = var then Abst (Id x, reduce t false) else
  29.                             if Set.mem x filledSet then
  30.                                 let new_name = x ^ (string_of_int (Random.int 100)) in
  31.                                  let add_to_hashtbl = Hashtbl.add namesHashtbl x new_name in
  32.                                   let new_tsubtree = ref nil in
  33.                                     add_to_hashtbl;
  34.                                     new_tsubtree := Abst (Id new_name, reduce t flag);
  35.                                     Hashtbl.remove namesHashtbl x;
  36.                                     !new_tsubtree;
  37.                             else Abst (Id x, reduce t flag)
  38.         | Var (Id v)     -> if Hashtbl.mem namesHashtbl v then
  39.                               Var (Id (Hashtbl.find namesHashtbl v))
  40.                             else if flag && v = var then term2 (* deferred substitution ?? *) else tree
  41.       in reduce term1 true
  42.  
  43. (*  let rec rect_redex tree flag = if !flag == true then tree else match tree with
  44.   | Var (Id v)                 -> tree
  45.   | Abst (Id x, t)             -> Abst (Id x, rect_redex t flag)
  46.   | Appl (Abst(Id x, t1), t2)  -> flag := true; beta_reduction t1 x t2
  47.   | Appl (Var x, t2)           -> Appl (Var x, rect_redex t2 flag)
  48.   | Appl (t1, t2)              ->
  49.     let new_tree1 = rect_redex t1 flag in
  50.         if !flag == true then Appl(new_tree1, t2) else
  51.           Appl (t1, rect_redex t2 flag) *)
  52.  
  53.  
  54. let rec rect_redex tree flag = (*if !flag == true then tree else*) match tree with
  55.   | Var (Id v)                 -> tree
  56.   | Abst (Id x, t)             -> Abst (Id x, rect_redex t flag)
  57.   | Appl (Abst(Id x, t1), t2)  -> flag := true; beta_reduction t1 x t2 (*not one...*)
  58.   | Appl (Var x, t2)           -> Appl (Var x, rect_redex t2 flag)
  59.   | Appl (t1, t2)              ->
  60.     let new_tree1 = rect_redex t1 flag in
  61.     let new_tree2 = rect_redex t2 flag in
  62.         Appl (new_tree1, new_tree2)
  63.  
  64. let rec one_step tree n k m =
  65. let flag = ref true in
  66.   if ((n mod k) = 0) then begin
  67.       print_string (print_expr tree);
  68.       print_char '\n';
  69.       flag := false;
  70.     end;
  71.   if n > m then tree else
  72.     let has_redex = ref false in
  73.     let new_tree = rect_redex tree has_redex in
  74.     if !has_redex then one_step new_tree (n + 1) k m else
  75.       if !flag then begin
  76.           print_string (print_expr tree);
  77.           print_char '\n';
  78.           tree;
  79.         end
  80.       else tree
  81. ;;
  82.  
  83. let km = split_on_char ' ' (read_line()) in
  84.   let k = match km with
  85.   | kk :: [mm] -> int_of_string kk in
  86.   let m = match km with
  87.   | kk :: [mm] -> int_of_string mm in
  88.     one_step (Parser.main Lexer.main (Lexing.from_string (read_line()))) 0 k m
  89.  
  90. (* (\x.x x x x)((\x.x)(\x.x)) *)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement