Skip to content
Snippets Groups Projects
Select Git revision
  • 0e2476f33089c4b29bf4fb128344e6f293bf9396
  • main default protected
2 results

ast.ml

Blame
  • Kylian Fontaine's avatar
    Kylian Fontaine authored
    0e2476f3
    History
    ast.ml 18.36 KiB
    (*ROBOGRAM*)
    
    type binop = 
      | Plus
      | Minus
      | Mult
      | Div
      | And
      | Or
      | Sup 
      | Inf 
      | Equal
      | Diff
    
    (*tail::head au lieu de head::tail pour optimisation mémoire, éviter les empilements inutiles
       (((vide,x),y),z)  
       pour le set x,y,z*)
    type 'a set = 
      | Vide
      | Some of ('a set) * 'a 
    
    
    (*type pour l'utilisation de point avec obs, self, les package etc
    type objet =
      | Self 
      | Obs
      | Geometry *)
    
    type expr =
      | None (*variable declaré mais non défini*)
      | Bool of bool
      | Cst of int 
      | Cstf of float
      | BinOp of expr * binop * expr
      | Not of expr
    	| Cond of expr * expr  *expr
      | Var of string (* est ce qu'on ratache un type a la variable?*)
      | Let of string * expr * expr
      | Fun of string * expr
      | App of expr * expr
      | Affectation of string * expr  (* variable deja declaré avec let et on change sa valeur*)
      | Set of expr set (* FIXME: Est ce qu'on veut vraiment un set d'expression? donc avoir des possibilités tel que : [Boucle(cond, e); Cst 1;....] *)
      | LengthSet of expr (* lors de l'interpretation qu'on checkera que l'expression donné soit bien un set*)
      | PushSet of expr * expr 
      | Point of string * string  
      | PatternMatching of expr * (expr * expr)list
      | Cons of expr *expr 
      
    
    
    
    (*DESCRIPTION DE L'ENVIRONNEMENT*)
    
    (** type syncho : 
        Fsync -> Full synchronisé
        Ssync -> Semi synchronisé
        Async -> Asynchronisé*)
    type synchro = 
      | Fsync
      | Ssync
      | Async
    
    (** type space : 
        R -> une ligne
        Rm -> un millefeuille de ligne (convoie)
        R2 -> un plan
        R2m -> millefeuille de plan (simplification de R3)
        ZnZ -> anneau prennant n -> positions congruantes
        *)
    type space =
      | R
      | Rm
      | R2 
      | R2m 
      | ZnZ of int 
    
    (* type range :
       Full    -> Full range
       Limited -> range limité a un delta
       K_rand  -> range limité a un delta + capable de voir k robots au dela de delta choisie rand
       K_enemy -> range limité a un delta + capable de voir k robots au dela de delta choisie par un ennemie*)
    type range =
      | Full
      | Limited of expr
      | K_rand of expr * expr 
      | K_enemy of expr * expr
    
    (* type multiplicite :
       No -> Pas de multiplicité
       Weak -> Multiplicité faible : sait si 1 ou plusieurs robots mais pas combien de robot
       Strong -> Multiplicité forte : connait le nombre de robot 
       Local -> robot ne connait que sur sa position
       Global -> robot connait pour toute les positions observés
       *)
    type multiplicite =
      | No 
      | Weak_Local
      | Strong_Local
      | Weak_Global
      | Strong_Global
    
    (* type light : Liste de couleurs
        Intern -> Les lumieres vu par le robot lui meme
        Extern -> Les lumieres vu par les robots autre que lui meme
        All -> Les lumieres vu par tout les robots lui meme compris 
        Vaut mieux liste de string pour chaque couleurs ou autre chose, un simple int correspondant au nombre de lumiere ?
        *)
    (*type lumiere = 
      | Interne of int
      | Externe of int
      | All of int
    *)
    type color =
      | Red
      | Blue
      | Yellow
      | Green
      | Purple
      | Orange
    
    
    type lights =
      | Intern of color list
      | Extern of color list
      | All of color list
    
    (* type memoire :
        Oblivious -> memoire reset a chaque Look-Compute-Move
        Finite -> memoire persistante entre deux Look-Compute-Move 
        Infinite -> se rappel de tout 
       *)
    (*type memory = 
      | Oblivious 
      | Finite of int 
      | Infinite
    *)
    	(* type opacity :
        Opaque -> Les robots sont opaques 
        Transparant -> Les robots sont transparant
        SemiOpaque n -> Transparant a partir  d'une distance n ? (aucune idée des decomposition possible des probleme)
       *)
    type opacity = 
    	| Opaque
    	| Transparent
    
      (*type rigidity :
        Rigide -> les robots atteignent leur destination final, ils ne sont pas interrompu pendant leur mouvement
        Flexible of float -> Les robots peuvent etre interrompu pendant leur mouvement, ils n'atteignent pas forcement leur 
                            destinations final cependant il parcourt au minimum une distance delta 
        *)
    type rigidity =
      | Rigide 
      | Flexible of expr
    
    (*type representant les fonction de degradation*)  
    type degrfunc =
      | Str of string
      | Fun of expr
    (* type sensor : regroupement des capteurs des robots *)
    type sensor = 
      | Range of range
      | Opacity of opacity
      | Multi of multiplicite
      | Custom of string * degrfunc
    
    (** type value : valeur pouvant etre utilisant dans les champs field*)
    type value = 
      | Empty  
      | Int of int 
      | Float of float
      | String of string
      | Liste of value list
      | Light of lights
    (** type field : type correspondant au champs que l'utilisateur va renseigner pour le robot*)
    type field = 
      | Private of (string * value)
      | Public of (string * value)
    
    type byzantine = 
      | Number of int
      | Id of int list
    
    type valretR =
      | Location
      | Direction
      | Str of string
    
    type share =
      | Fullcompass
      | Chirality
      | DirectionShare
      | OneAxisOrientation
    
    type information =
      | Sync of synchro
      | Rigidity of rigidity
      | Space of space
      | Byzantines of byzantine
      | Sensors of sensor list
      | Robot of field list
      | ActivelyUpdate of valretR list(*nom du champ*)
      | Roles of (int * string) list
      | Share of share
    
    (* Une description c'est 1: description de l'environnement et des capacites des robot
    	 											 2: robogram *)
    type description = Description of ((information list) * (expr list))
    
    
    (*FONCTION SUR LES SETS*)
    (** [length s] retourne la longueur du set [s]
        @param [s] 'a set dont on veut la longueur
        @return int la longueur du set*)
    let rec length_set (s:'a set): int =
      match s with
      | Vide -> 0
      | Some (s,_) -> 1 + (length_set s)
    
    (*[push s e] ajoute un element e au set s 
       @param s de type 'a set 
       @param e de type 'a 
       @return un set correspondant au set s avec l'ajout de e *)
    let push (s:'a set) (e : 'a) :'a set = Some(s,e)
    
    
    (*CONVERTION EN STRING*)
    let string_of_valretr (v : valretR) :string =
      match v with
      |Location -> "Location"
      |Direction -> "Direction"
      |Str s -> s
    let rec string_of_set (s: 'a set) (f : 'a -> string) : string =
      match s with 
      | Vide -> "Vide"
      | Some (s',e) -> "("^ string_of_set s' f ^"," ^ f e ^")"
    
    
      
    (** [string_of_expression e] Permet d'obtenir un string correspondant a l'expression [e]
        @param [e] expression dont on souhaite le string
        @return string correspondant a l'expression [e]
        *)
    let rec string_of_expression (e : expr) : string =
      match e with
      | None -> "None"
      | Bool b -> string_of_bool b
      | Cst i -> string_of_int i
      | Cstf f -> string_of_float f
      | BinOp(x,op ,y) -> (match op with
                          | Plus  -> "("^string_of_expression(x)^ " + " ^ string_of_expression(y)^")" 
                          | Minus -> "("^string_of_expression(x)^ " - " ^string_of_expression(y)^")" 
                          | Mult  -> "("^string_of_expression(x)^" * " ^string_of_expression(y)^")" 
                          | Div   -> "("^string_of_expression(x)^ " / " ^string_of_expression(y)^")" 
                          | And   -> string_of_expression(x) ^ " && " ^string_of_expression(y) 
                          | Or    -> string_of_expression(x) ^ " || " ^string_of_expression(y)
                          | Sup   -> "("^string_of_expression(x) ^ " > "^string_of_expression(y)^")" 
                          | Inf   -> "("^string_of_expression(x) ^ " < " ^string_of_expression(y)^")" 
                          | Equal -> string_of_expression(x) ^ " == " ^string_of_expression(y)
                          | Diff  -> string_of_expression(x) ^ " != " ^string_of_expression(y)
                          )
      | Not b -> "!("^string_of_expression b^")" 
      | Var v ->  v
      | Cond(c,e1,e2) -> "if (" ^string_of_expression c ^ ") then \n {" ^ string_of_expression e1 ^ "} \n else {" ^ string_of_expression e2 ^ "}"
      | Affectation(v,e) ->  v ^ " prend la valeur " ^ string_of_expression e
      | Set s -> string_of_set s string_of_expression 
      | Let (v,e1,e2) -> "Déclaration de la variable " ^ v ^ " avec definition : " ^ string_of_expression e1 ^ " dans \n(" ^string_of_expression e2 ^")"
      | Fun (s,e) -> "Fonction qui prend en parametre " ^ s ^ " et retourne (" ^ string_of_expression e ^")"
      | App (f,arg) -> "("^ string_of_expression f ^") appliqué a (" ^ string_of_expression arg ^")"
      | Point (k,v) -> "Valeur du champ " ^ v^ " de "^ k ^""
      | LengthSet s ->  (match s with
                        | Set s' ->  "Taille de "^string_of_expression s ^ " : " ^ string_of_int (length_set s') 
                        | Var _ -> "Taille du set "^string_of_expression s
                        | _ -> "Pas un set")
      | PushSet (e,s)-> (match s with
                        | Set s' ->  "Push "^string_of_expression e ^ " dans le set " ^ string_of_expression s ^ " : " ^ string_of_expression (Set(push s' e))
                        | Var _ -> "Push "^string_of_expression e ^ " dans le set " ^ string_of_expression s ^ " : " 
                        | _ -> "Pas un set")
      | PatternMatching (m,l) -> "match "^string_of_expression m^" with \n   | "^ String.concat "\n   | "(List.map (fun e -> match e with |
                                                                                e1,e2 -> string_of_expression e1 ^" => "^string_of_expression e2 ) 
                                                                                                           l)^ "\nend"
      | Cons (head,tail) -> string_of_expression head ^ " :: " ^ string_of_expression tail
    
     
    
    let string_of_synchro (s:synchro) : string = 
      match s with
      | Fsync -> "Full Synchro"
      | Ssync -> "Semi Synchro"
      | Async -> "Asynchro"
    
    let string_of_espace (e:space) : string =
    match e with  
      | R -> "R"
      | Rm -> "Rm"
      | R2 -> "R2"
      | R2m  ->"R2m"
      | ZnZ n -> "Z/"^ string_of_int n ^"Z"
      
    let string_of_color (c : color) : string =
      match c with
      | Red     -> "Red"
      | Blue    -> "Blue"
      | Yellow  -> "Yellow"
      | Green   -> "Green"
      | Purple  -> "Purple"
      | Orange  -> "Orange"
    
    let string_of_sensor (s : sensor) : string =
      match s with
      | Range r ->  (match r with 
                    | Full         -> "Range Full"
                    | Limited x    -> "Range Limité a : "          ^ string_of_expression x
                    | K_rand(x,y)  -> "Range K_rand limité a : "   ^ string_of_expression x ^ " et k = " ^ string_of_expression y
                    | K_enemy(x,y) -> "Range K_enemy limité a : "  ^ string_of_expression x ^ " et k = " ^ string_of_expression y)
      | Multi m ->  (match m with
                    | No            -> "Multiplicity Aucune multiplicité"
                    | Weak_Local    -> "Multiplicity Faible local"
                    | Strong_Local  -> "Multiplicity Forte local"
                    | Weak_Global   -> "Multiplicity Faible global"
                    | Strong_Global -> "Multiplicity Forte global")
      | Opacity o -> (match o with  
                    | Opaque      -> "Opacity Opaque"
                    | Transparent -> "Opacity Transparent")
      | Custom (s,f) -> "Fonction de degradation du champ " ^ s ^" : "^(match f with Str f' -> f'
                                                                        | Fun f' -> string_of_expression f')
    let rec string_of_value (v : value) : string =
      match v with
      | Empty -> "None"
      | Int i -> string_of_int i
      | String s -> s
      | Float f -> string_of_float f
      | Liste l -> "[" ^String.concat "; " (List.map string_of_value l) ^"]"
      | Light l -> (match l with
                    | Intern c -> "Lumiere interne avec couleur :" ^ String.concat ", " (List.map string_of_color c) 
                    | Extern c ->"Lumiere externe avec couleur :" ^ String.concat ", " (List.map string_of_color c) 
                    | All c ->"Lumiere visible par tous avec couleur :" ^ String.concat ", " (List.map string_of_color c)  
      ) 
    let string_of_field (f : field) : string = 
      match f with
      | Private (s,v)-> "Private: "^s^"->"^ string_of_value v
      | Public (s,v) -> "Public: "^s^"->"^ string_of_value v
    let string_of_byzantine (b : byzantine) : string =
      match b with
      | Number n -> "Il y a n/" ^ string_of_int n ^ " Byzantin(s)" 
      | Id l -> "Liste des byzantins : [" ^ String.concat "; " (List.map string_of_int l) ^"]"
    let string_of_role (r : int*string) : string=
      match r with
      | id,role -> "Le robot d'id " ^ string_of_int id ^" a comme role : " ^role
    
    let string_of_rigidity (r: rigidity) : string =
      match r with
      | Rigide -> "Rigide"
      | Flexible _ -> "Flexible"
    
    let rec string_of_description (desc:description) : string =
      match desc with
      | Description (infos,robogram) -> 
            "Description environnement:\n" ^String.concat "\n" (List.map string_of_information infos)
            ^"\nRobogram : \n " ^  String.concat "\n" (List.map string_of_expression robogram)
    and string_of_information (info: information) : string =
      match info with
      | Sync s   -> "Sync: "      ^ (string_of_synchro s)
      | Rigidity r ->(match r with
                      | Rigide      -> "Rigidity: Rigide"
                      | Flexible d  -> "Rigidity: Flexible d'une distance delta = " ^ string_of_expression d)
    
      | Space e -> "Espace: "    ^ (string_of_espace e)
      | Byzantines b ->  string_of_byzantine b
      | Sensors s -> "Sensors: [" ^ String.concat "; " (List.map string_of_sensor s) ^ "] "
      | Robot r -> "Robot : ["^ String.concat "; " (List.map string_of_field r) ^ "]"
      | Roles r -> "Roles :" ^ String.concat "\n " (List.map string_of_role r)
      | ActivelyUpdate a -> "Champ qui sont mise a jour par le robogram: " ^ String.concat ", " (List.map string_of_valretr a )
      | Share s ->"Share : " ^ (match s with
                    |Fullcompass -> "Fullcompass"
                    |Chirality -> "Chirality"
                    |DirectionShare -> "Direction"
                    |OneAxisOrientation ->"1-axis orientation")
                    
    (** [info_sync i] verifie qu'une information est une information sur la synchronisation
        @param i information
        @return bool *)
    let info_sync (i : information):bool = 
      match i with
      | Sync _ -> true
      | _      -> false
        
    (** [info_espace i] verifie qu'une information est une information sur l'espace
        @param i information
        @return bool *)
    let info_space (i : information):bool = 
      match i with
      | Space _ -> true
      | _        -> false
    
      
    (** [check_description d] verifie que la description [d] possède bien les informations minimales
                              attendu pour une description et que chaque type d'information soit unique
                              (deux définition de l'espace le quel choisir ?...)
        @param [d] description à vérifier
        @return true si la description repond aux critères false sinon
        TODO: A finir/ utilisation de valeur par defaut si non fourni? pourquoi pas 
        *)
    let check_description (d : description) :bool =
    			let unique f d = List.length (List.filter f d) = 1
    			in 
    			match d with 
    			| Description (d',_) -> if not(unique info_sync d')
                                      then (print_endline "Error: Problem of defining sync"; false)
    													    else (
                                      if not(unique info_space d') 
                                        then (print_endline "Error: Problem of defining space";false)
    													        else true
    														  )  ;;
    
    (**[get_sensors d] Renvoie la liste de sensors contenu dans la description [d]
        @param description 
        @return [sensor list] 
        *)
    let get_sensors (d : description) : sensor list =
      match d with 
      | Description(d', _) -> (match List.find_opt (fun x -> match x with Sensors _ -> true | _-> false) d' with 
                              Some (Sensors s) -> s 
                              | _ -> raise(Failure("Error: Not find Sensors")))
    
    (**[get_robot d] Renvoie la liste des champs robot contenu dans la descritpion [d]
        @param description
        @return [field list]*)
    let get_robot (Description(d', _) : description) : field list =
      match List.find_opt (fun x -> match x with Robot _ -> true | _-> false) d' with 
                              Some (Robot r) -> r 
                              | _ -> raise(Failure("Error: Not find Robot"))
    
    (**[get_activelyup d] Renvoie la liste des string correspondant aux champs mis à jour par le robogram
        @param description
        @return [string list] *)
    let get_activelyup (d : description) : string list = 
      match d with 
      | Description(d', _) -> (match List.find_opt (fun x -> match x with ActivelyUpdate _ -> true | _-> false) d' with 
                              Some (ActivelyUpdate a) -> List.map string_of_valretr a
                              | _ -> raise(Failure("Error: Not find ActivelyUpdate")))
    
    (** [check_sensor s r] verifie qu'un sensor [s] soit bien déclarer dans le robot [r],ou alors qu'il soit pas un sensor custom 
        @param [s] sensor à verifié
        @param [r] field list correspondant au robot dans le quel on verifie [s]
        @return true si [s] n'est pas custom ou qu'il est custom et qu'il est contenu dans [r]
    *)
    let check_sensor (s: sensor) (r:field list):bool =
        let only_public flist = List.filter (fun x -> match x with Public _ -> true| _-> false) flist in
        let field_to_pair f = List.map(fun x -> match x with Public x -> x | Private x -> x) f in
        match s with 
        | Custom (s',_)-> List.exists (fun (x,_) -> x = s') (field_to_pair (only_public r))
        | _ -> true
    
    (** [check_sensors_desc d] verifie que la liste de sensors de la description correspond a des sensors de robot
        @param d description dans la quel on verifie sa liste de sensors avec sa déclaration de robot (field list)
        @return [true] si les sensors sont custom et sont bien dans robot ou si il ne sont pas custom*)
    let check_sensors_desc (d:description) :bool =
       let res= List.find_opt (fun x -> not (check_sensor x (get_robot d))) (get_sensors d) in
        match res with 
        | Some x -> print_endline("Error : " ^(match x with |Custom (x',_)-> x' | _->"")^" is not declared public in robot"); false
        | _-> true
    
    (**[check_activelyup d] verifie que les champs renseignés dans activelyupdate soient déclarés dans robot
        @param d [description]
        @return [bool]*)
    let check_activelyup (d:description) :bool =
        let field_to_pair f = List.map(fun x -> match x with Public x -> x | Private x -> x) f in
        let aux s l = List.exists (fun (x,_) -> x = s) (field_to_pair l) in
        let res = List.find_opt (fun x -> not (aux x (get_robot d))) (get_activelyup d) in
        match res with 
        | Some x -> print_endline("Error : " ^x^" x is not declared in robot"); false
        | _-> true
      
    
    (**[check_light d] si il y a des lumiere intern on verifie qu'elle soit pas renseigné en public
                       et si extern pas dans private
        @param description [d] description du monde
        @return bool true si pas de lumiere intenre en public *)
    let check_light d : bool = 
      let rec check flist = (
        fun x -> match x with 
        | [] -> true
        | Public (_,Light(Intern _))::_ -> false
        | Private (_, Light(Extern _))::_ -> false
        | _::t-> check t
       ) flist 
      in
      check (get_robot d)