Ajout de True et de la tactique exact.
This commit is contained in:
parent
0f7a24ae49
commit
d8f791328d
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
_build
|
_build
|
||||||
pieuvre
|
pieuvre
|
||||||
main.native
|
main.native
|
||||||
|
log.8pus
|
||||||
|
|
||||||
*.kate-swp
|
*.kate-swp
|
||||||
|
|||||||
12
README.md
12
README.md
@ -42,7 +42,11 @@ L'option `alpha` vérifie si deux lambda-termes sont alpha-équivalents. Elle s'
|
|||||||
- Option `typecheck`
|
- Option `typecheck`
|
||||||
|
|
||||||
### Samy
|
### Samy
|
||||||
Fonctions de manipulation des λ-termes (pieuvre.ml)
|
- Fonctions de manipulation des λ-termes (`pieuvre.ml`)
|
||||||
Typecheck
|
- Typecheck
|
||||||
Erreurs lors des tactiques.
|
- Erreurs lors des tactiques.
|
||||||
\/ et /\
|
- `\/` et `/\`
|
||||||
|
- Parsing des λ-termes
|
||||||
|
- `True` et `exact`
|
||||||
|
- Option `-computetype`
|
||||||
|
|
||||||
|
|||||||
@ -22,8 +22,10 @@ rule token = parse
|
|||||||
| "split" { SPLIT }
|
| "split" { SPLIT }
|
||||||
| "left" { LEFT }
|
| "left" { LEFT }
|
||||||
| "right" { RIGHT }
|
| "right" { RIGHT }
|
||||||
|
| "exact" { EXACT }
|
||||||
|
|
||||||
| "False" { FALSE }
|
| "False" { FALSE }
|
||||||
|
| "True" { TRUE }
|
||||||
|
|
||||||
| "fun" { FUN }
|
| "fun" { FUN }
|
||||||
| "=>" { MAPS_TO }
|
| "=>" { MAPS_TO }
|
||||||
@ -34,6 +36,7 @@ rule token = parse
|
|||||||
| "ig" { IG }
|
| "ig" { IG }
|
||||||
| "id" { ID }
|
| "id" { ID }
|
||||||
| "case" { CASE }
|
| "case" { CASE }
|
||||||
|
| 'I' { I }
|
||||||
|
|
||||||
| '&' { AMPERSAND }
|
| '&' { AMPERSAND }
|
||||||
|
|
||||||
|
|||||||
30
main.ml
30
main.ml
@ -16,11 +16,13 @@ let filename = ref "" in
|
|||||||
let reduce_option = ref false in
|
let reduce_option = ref false in
|
||||||
let alpha_option = ref false in
|
let alpha_option = ref false in
|
||||||
let typecheck_option = ref false in
|
let typecheck_option = ref false in
|
||||||
|
let computetype_option = ref false in
|
||||||
|
|
||||||
Arg.parse
|
Arg.parse
|
||||||
[("-reduce", Arg.Set reduce_option, "Show the step-by-step reduction of a lambda-term");
|
[("-reduce", Arg.Set reduce_option, "Show the step-by-step reduction of a lambda-term");
|
||||||
("-alpha", Arg.Set alpha_option, "Check is two lambda-terms separated by '&' are alpha-convertible");
|
("-alpha", Arg.Set alpha_option, "Check is two lambda-terms separated by '&' are alpha-convertible");
|
||||||
("-typecheck", Arg.Set typecheck_option, "Check if a lambda term has a given type")]
|
("-typecheck", Arg.Set typecheck_option, "Check if a lambda term has a given type");
|
||||||
|
("-computetype", Arg.Set computetype_option, "Computes the type of the input λ-term")]
|
||||||
(fun s -> filename := s)
|
(fun s -> filename := s)
|
||||||
"The available options are:";
|
"The available options are:";
|
||||||
|
|
||||||
@ -96,6 +98,28 @@ if !typecheck_option then (
|
|||||||
exit 0
|
exit 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if !computetype_option then (
|
||||||
|
let lexbuf = Lexing.from_channel (match file with
|
||||||
|
| None -> stdin
|
||||||
|
| Some file -> file
|
||||||
|
)
|
||||||
|
in
|
||||||
|
let lambda_term =
|
||||||
|
try
|
||||||
|
Parser.main_lambda Lexer.token lexbuf
|
||||||
|
with e -> (
|
||||||
|
Printf.printf "Can't read lambda term\n";
|
||||||
|
raise e
|
||||||
|
)
|
||||||
|
in
|
||||||
|
begin
|
||||||
|
match (computeType [] lambda_term) with
|
||||||
|
| Some t -> Printf.printf "The type of %s is %s\n" (string_of_lam lambda_term) (string_of_ty t)
|
||||||
|
| None -> Printf.printf "λ-term %s cannot be typed ! (Therfore, it has to be either wrong or not closed)\n" (string_of_lam lambda_term)
|
||||||
|
end;
|
||||||
|
exit 0
|
||||||
|
);
|
||||||
|
|
||||||
(* Affiche un message si l'entrée est lue sur stdin *)
|
(* Affiche un message si l'entrée est lue sur stdin *)
|
||||||
let show s = match file with
|
let show s = match file with
|
||||||
| None -> Printf.printf "%s" s
|
| None -> Printf.printf "%s" s
|
||||||
@ -266,6 +290,10 @@ while !subgoals <> [] do
|
|||||||
)
|
)
|
||||||
| _ -> raise (TacticException(tactic,"Cannot prove right as the goal is no \\/ clause"))
|
| _ -> raise (TacticException(tactic,"Cannot prove right as the goal is no \\/ clause"))
|
||||||
)
|
)
|
||||||
|
| Exact l -> (
|
||||||
|
if not (typecheck hyps l ty) then raise (TacticException(tactic,"λ-term "^(string_of_lam l)^" cannot be typed with "^(string_of_ty ty)^" as its type is "^(match (computeType [] l) with None -> "None" | Some t -> string_of_ty t)))
|
||||||
|
else fill_holes := fun holes -> f (l::holes)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
in
|
in
|
||||||
|
|
||||||
|
|||||||
13
parser.mly
13
parser.mly
@ -10,7 +10,7 @@
|
|||||||
%token <string> VAR_NAME
|
%token <string> VAR_NAME
|
||||||
%token <string> TYPE_NAME
|
%token <string> TYPE_NAME
|
||||||
|
|
||||||
%token DOT INTRO ASSUMPTION APPLY ELIM CUT SPLIT LEFT RIGHT FST SND IG ID CASE
|
%token DOT INTRO ASSUMPTION APPLY ELIM CUT SPLIT LEFT RIGHT EXACT FST SND IG ID CASE I
|
||||||
%token FUN MAPS_TO COLON EXF
|
%token FUN MAPS_TO COLON EXF
|
||||||
|
|
||||||
%token AMPERSAND
|
%token AMPERSAND
|
||||||
@ -73,10 +73,20 @@ tactic:
|
|||||||
| SPLIT DOT { Split }
|
| SPLIT DOT { Split }
|
||||||
| LEFT DOT { Left }
|
| LEFT DOT { Left }
|
||||||
| RIGHT DOT { Right }
|
| RIGHT DOT { Right }
|
||||||
|
| EXACT lambda DOT { Exact $2 }
|
||||||
|
|
||||||
/* Lambda-termes */
|
/* Lambda-termes */
|
||||||
lambda_arg: /* Expression pouvant être en argument d'une fonction */
|
lambda_arg: /* Expression pouvant être en argument d'une fonction */
|
||||||
| VAR_NAME { LVar $1 }
|
| VAR_NAME { LVar $1 }
|
||||||
|
| EXF LPAREN lambda COLON ty RPAREN { LExf ($3, $5) }
|
||||||
|
| FST LPAREN lambda RPAREN { LFst ($3) }
|
||||||
|
| SND LPAREN lambda RPAREN { LSnd ($3) }
|
||||||
|
| IG LPAREN lambda COMMA ty RPAREN { LIg ($3, $5) }
|
||||||
|
| ID LPAREN lambda COMMA ty RPAREN { LId ($3, $5) }
|
||||||
|
| CASE LPAREN lambda COMMA lambda COMMA lambda RPAREN
|
||||||
|
{ LCase ($3, $5,$7) }
|
||||||
|
| I { LI }
|
||||||
|
| LPAREN lambda COMMA lambda RPAREN { LCouple($2, $4) }
|
||||||
| LPAREN lambda RPAREN { $2 }
|
| LPAREN lambda RPAREN { $2 }
|
||||||
|
|
||||||
/* Application d'une fonction */
|
/* Application d'une fonction */
|
||||||
@ -89,4 +99,3 @@ lambda:
|
|||||||
| FUN VAR_NAME COLON ty MAPS_TO lambda { LFun ($2, $4, $6) }
|
| FUN VAR_NAME COLON ty MAPS_TO lambda { LFun ($2, $4, $6) }
|
||||||
| FUN LPAREN VAR_NAME COLON ty RPAREN MAPS_TO lambda
|
| FUN LPAREN VAR_NAME COLON ty RPAREN MAPS_TO lambda
|
||||||
{ LFun ($3, $5, $8) }
|
{ LFun ($3, $5, $8) }
|
||||||
| EXF LPAREN VAR_NAME COLON ty RPAREN { LExf (LVar $3, $5) }
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ let rec string_of_ty (t: ty) : string =
|
|||||||
|
|
||||||
(* Affiche un λ-terme avec la même syntaxe qu’en entrée *)
|
(* Affiche un λ-terme avec la même syntaxe qu’en entrée *)
|
||||||
let rec string_of_lam (l: lam) : string = match l with
|
let rec string_of_lam (l: lam) : string = match l with
|
||||||
| LFun(v,t,l') -> "λ"^v^":"^(string_of_ty t)^" . "^(string_of_lam l')
|
| LFun(v,t,l') -> "(fun "^v^":"^(string_of_ty t)^" => "^(string_of_lam l')^")"
|
||||||
| LApp(l1, l2) -> "("^(string_of_lam l1)^" "^(string_of_lam l2)^")"
|
| LApp(l1, l2) -> "("^(string_of_lam l1)^" "^(string_of_lam l2)^")"
|
||||||
| LVar(v) -> v
|
| LVar(v) -> v
|
||||||
| LExf(l',t) -> "exf("^(string_of_lam l')^" : "^(string_of_ty t)^")"
|
| LExf(l',t) -> "exf("^(string_of_lam l')^" : "^(string_of_ty t)^")"
|
||||||
@ -35,6 +35,7 @@ let rec string_of_lam (l: lam) : string = match l with
|
|||||||
| LIg(ll,t) -> "ig("^(string_of_lam ll)^","^(string_of_ty t)^")"
|
| LIg(ll,t) -> "ig("^(string_of_lam ll)^","^(string_of_ty t)^")"
|
||||||
| LId(ll,t) -> "id("^(string_of_lam ll)^","^(string_of_ty t)^")"
|
| LId(ll,t) -> "id("^(string_of_lam ll)^","^(string_of_ty t)^")"
|
||||||
| LCase(ll,lg,ld) -> "case("^(string_of_lam ll)^","^(string_of_lam lg)^","^(string_of_lam ld)^")"
|
| LCase(ll,lg,ld) -> "case("^(string_of_lam ll)^","^(string_of_lam lg)^","^(string_of_lam ld)^")"
|
||||||
|
| LI -> "I"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let split, tsplit =
|
let split, tsplit =
|
||||||
@ -64,6 +65,7 @@ let findFreeName (l: lam) (x: var) =
|
|||||||
| LIg(l',t) -> finder l'
|
| LIg(l',t) -> finder l'
|
||||||
| LId(l',t) -> finder l'
|
| LId(l',t) -> finder l'
|
||||||
| LCase(ll,lg,ld) -> (finder ll; finder lg; finder ld)
|
| LCase(ll,lg,ld) -> (finder ll; finder lg; finder ld)
|
||||||
|
| LI -> ()
|
||||||
|
|
||||||
in
|
in
|
||||||
finder l;
|
finder l;
|
||||||
@ -121,6 +123,7 @@ let rec replace (l: lam) (x: var) (s: lam) = match l with
|
|||||||
| LIg(l',t) -> LIg(replace l' x s, t)
|
| LIg(l',t) -> LIg(replace l' x s, t)
|
||||||
| LId(l',t) -> LId(replace l' x s, t)
|
| LId(l',t) -> LId(replace l' x s, t)
|
||||||
| LCase(l',lg,ld) -> LCase(replace l' x s, replace lg x s, replace ld x s)
|
| LCase(l',lg,ld) -> LCase(replace l' x s, replace lg x s, replace ld x s)
|
||||||
|
| LI -> LI
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@ -140,6 +143,7 @@ let rec alpha (l1: lam) (l2: lam) : bool =
|
|||||||
| (LIg(l1,t1),LIg(l2,t2)) -> t1=t2 && alpha l1 l2
|
| (LIg(l1,t1),LIg(l2,t2)) -> t1=t2 && alpha l1 l2
|
||||||
| (LId(l1,t1),LId(l2,t2)) -> t1=t2 && alpha l1 l2
|
| (LId(l1,t1),LId(l2,t2)) -> t1=t2 && alpha l1 l2
|
||||||
| (LCase(l1,lg1,ld1),LCase(l2,lg2,ld2)) -> (alpha l1 l2) && (alpha lg1 lg2) && (alpha ld1 ld2)
|
| (LCase(l1,lg1,ld1),LCase(l2,lg2,ld2)) -> (alpha l1 l2) && (alpha lg1 lg2) && (alpha ld1 ld2)
|
||||||
|
| (LI,LI) -> true
|
||||||
|
|
||||||
| _ -> false (* Les deux formules n'ont pas la même structure *)
|
| _ -> false (* Les deux formules n'ont pas la même structure *)
|
||||||
;;
|
;;
|
||||||
@ -183,6 +187,7 @@ let rec betastep (l: lam) : lam option = match l with
|
|||||||
| (LId(_,_),None) -> Some ld
|
| (LId(_,_),None) -> Some ld
|
||||||
| (_,None) -> None
|
| (_,None) -> None
|
||||||
end
|
end
|
||||||
|
| LI -> None
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@ -230,7 +235,7 @@ let rec computeType (env: gam) (l: lam) : ty option =
|
|||||||
| (Some TOr(t1a,t1b),Some TImpl(t2a,t2c),Some TImpl(t3b,t3c)) when t1a=t2a && t1b=t3b && t2c=t3c -> Some t3c
|
| (Some TOr(t1a,t1b),Some TImpl(t2a,t2c),Some TImpl(t3b,t3c)) when t1a=t2a && t1b=t3b && t2c=t3c -> Some t3c
|
||||||
| _ -> None
|
| _ -> None
|
||||||
end
|
end
|
||||||
|
| LI -> Some TTrue
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(* Vérifie que le λ-terme l sous l'environnement env a bien le type t *)
|
(* Vérifie que le λ-terme l sous l'environnement env a bien le type t *)
|
||||||
|
|||||||
@ -29,7 +29,8 @@ type lam =
|
|||||||
| LSnd of lam
|
| LSnd of lam
|
||||||
| LIg of lam * ty
|
| LIg of lam * ty
|
||||||
| LId of lam * ty
|
| LId of lam * ty
|
||||||
| LCase of lam * lam * lam;;
|
| LCase of lam * lam * lam
|
||||||
|
| LI;;
|
||||||
|
|
||||||
(* Environnement de typage *)
|
(* Environnement de typage *)
|
||||||
type gam = (var_type * ty) list;;
|
type gam = (var_type * ty) list;;
|
||||||
|
|||||||
@ -8,4 +8,5 @@ type tactic =
|
|||||||
| Cut of ty
|
| Cut of ty
|
||||||
| Split
|
| Split
|
||||||
| Left
|
| Left
|
||||||
| Right;;
|
| Right
|
||||||
|
| Exact of lam;;
|
||||||
|
|||||||
8
tests/vrai-pas-faux.8pus
Normal file
8
tests/vrai-pas-faux.8pus
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
(True \/ False) /\ (~(False /\ True))
|
||||||
|
split.
|
||||||
|
left.
|
||||||
|
exact I.
|
||||||
|
intro x.
|
||||||
|
elim x.
|
||||||
|
intro a.
|
||||||
|
elim a.
|
||||||
Loading…
x
Reference in New Issue
Block a user