
A few words about this implementation.

What is done, in which order:

  1. the program is read with the parser in "pprog.ml4"
     the entry is Programs.program
     the result has type program = (unit, CoqAst.t) ProgAst.t

  2. variables, references and constants are distinguished with Prog_db.db_prog
     (unbound variables => error messages)

  3. typing with effects is done by Eff_inf.states
     (typing errors => error messages)
     the result has type typed_program = (ml_type_c, condition) ProgAst.t

  3b. some pre/post condition are propagated inside the program with 
     Prog_wp.propagate. (shouldn't fail)

  4. translation into a purely functional program is done by Mlise.trad
     the result belongs to an intermediate type cc_term, on which we
     can perform some eta-reduction with Prog_red.red
     (shouldn't fail)

  5. translation into a CIC term is done by Prog_cci.constr_of_prog
     (shouldn't fail)

  6. then we perform a resolution of existential variables with
     Trad.ise_resolve1_metas
     remaining ISEVAR become casted metavariables (= proof obligations)

  7. the type of the translated program is reduced to beta/iota NF
     and becomes the goal (with start_proof)

  8. the proof term is then reduced with the special purpose function
     Prog_red.red_cci, which keeps the casts and does not erase some
     proof obligations

  9. at last, this (uncomplete) proof term is given to the Refine tactic
     (see tactics/tcc/), which generates the proof obligations

