Paul Planchon
Paul Planchon

Reputation: 3

Toplevel Ocaml infinit interpretation loop

This code won't output syntax error, but wont end compiling either. When I comment the toutes_reponses function, the code will compile and execute. Is toutes_reponses running in a kind of infinit interpreter loop ?

I use ocaml and #use "code.ml" to compile.

Also, the CPU is running at 100% during this time.

#load "str.cma";;
module Code:
sig
        (** Le type d'un pion *)
        type pion = string

        (** Le type d'un code *)
        type t = pion list

        (** Le nombre de pions par code*)
        val nombre_pion : int          

        (** Le nombre de couleur et symboles possibles*)
        val couleur_possibles : pion list

        (** Compare deux codes
         *  @param code1 premier code a comparer
         *  @param code2 second  code a comparer
         *  @return 0 si les deux codes sont identiques,
                      un entier positif si [code1] est strictement plus grand que [code2]
                      un entier negatif si [code1] est strictement plus petit que [code2]       
         *)
        val compare : t -> t -> int

        (** Conversion chaine de caracteres vers code (pour saisie) 
         *  @param string chaine de caractere saisie
         *  @return le code correspondant a la saisie si la conversion est     possible
                      [None] si la conversion n'est pas possible
         *)
        val string_of_code : t -> string

        (** Conversion chaine de caracteres vers code (pour saisie)
         *  @param string chaine de caractere saisie
         *  @return le code correspondant a la saisie si la conversion est possible
                      [None] si la conversion n'est pas possible
     *)
        val code_of_string : string -> t

        (** La liste de tous les codes permis *)
        val tous : t list

        (** La liste de toutes les reponses possibles *)  
        val toutes_reponses : (int * int) list

        (** Calcule la reponse d'un code par rapport au code cache
         *  @param      code le code propose
         *  @param vrai_code le code cache
         *  @return un couple (nombre de pions bien places, nombre de pions mal places)
            [None] si la reponse ne peut etre calculee
         *)
        val reponse : t -> t -> (int * int)

        val convert : int -> int -> int -> int list -> int list

        val finirTableau : int -> int list -> int list
end = struct    
        type pion = string;;
        type t = pion list;;
        let nombre_pion = 4;;
        let couleur_possibles = ["Rouge"; "Vert"; "Bleu"; "Orange"; "Noir"; "Blanc"];;

        let compare code1 code2 =
          match (code1, code2) with
          | a::b, c::d -> (if a = c then compare b d else
                                  if a > c then 1 else -1)
          | _, _ -> 0;;

        let string_of_code code = List.fold_right (fun x y -> x ^ "_" ^ y) code "";;

        let code_of_string code = List.filter (fun x -> String.length x != 0) (Str.split_delim (Str.regexp "_") code);;

        let rec convert x b i tmp =
          if x = 0 then tmp
          else convert (x / b) b (i + 1) tmp @ [x mod b];;

        let rec finirTableau b tab =
          if (List.length tab) = b then tab
          else finirTableau b (tab @ [0]);;

        let tous =
          let n = List.length couleur_possibles and m = nombre_pion in
          let rec aux i acc =
            if i = -1 then acc else aux (i - 1) acc @ [(List.map (fun x -> (List.nth couleur_possibles x))(finirTableau m (convert i n 0 [])))];
          in aux (int_of_float ((float_of_int n) ** (float_of_int m)) - 1) [];;

        let toutes_reponses =
          let m = nombre_pion in
          let rec aux i acc =
            let array = finirTableau 2 (convert i m 0 []) in
            if i = -1 then acc else aux (i - 1) (acc @ [(List.nth array 0, List.nth array 1)]);
          in aux (nombre_pion * nombre_pion) [];;

        let reponse code secret = (1,2);;
end;;

Upvotes: 0

Views: 236

Answers (2)

The type of toutes_reponses is,

toutes_reponses : (int * int) list

Loading your file in the interpreter results in the evaluation of all declared terms, including this one. And apparently you're stuck in its evaluation. If you want to be able to load the file in the interpreter, turn it into a suspended computation,

toutes_reponses : unit -> (int * int) list

let toutes_reponses () = ...

Upvotes: 0

octachron
octachron

Reputation: 18902

Your code compiles fine, it is just running into a infinite loop in one of the functions before tous. To debug this issue, you could start by adding assert statements to document the entry condition for your recursive functions.

Note also that there is many inefficiencies in your code, you should avoid:

  • List.nth (if you need random access, the data structure that you should use is _ array)
  • appending at the end of a list (e.g. tab @ [0]). In general, the list one the left-hand side of @ should away be small.
  • calling List.length inside a recursive function

Similarly, if you want to split a string on a character, there is String.spilt_on_char in the standard library (since OCaml ≥4.04).

Upvotes: 1

Related Questions