src/HOL/Tools/Predicate_Compile/code_prolog.ML
changeset 38078 2afb5f710b84
parent 38077 46ff55ace18c
child 38079 7fb011dd51de
equal deleted inserted replaced
38077:46ff55ace18c 38078:2afb5f710b84
   137   write_rel head ^ (if prem = Conj [] then "." else " :- " ^ write_prem prem ^ ".")
   137   write_rel head ^ (if prem = Conj [] then "." else " :- " ^ write_prem prem ^ ".")
   138 
   138 
   139 fun write_program p =
   139 fun write_program p =
   140   cat_lines (map write_clause p) 
   140   cat_lines (map write_clause p) 
   141 
   141 
       
   142 (** query templates **)
       
   143 
   142 fun query_first rel vnames =
   144 fun query_first rel vnames =
   143   "eval :- once("  ^ rel ^ "(" ^ space_implode ", " vnames ^ ")),\n" ^
   145   "eval :- once("  ^ rel ^ "(" ^ space_implode ", " vnames ^ ")),\n" ^
   144   "writef('" ^ implode (map (fn v => v ^ " = %w\\n") vnames) ^"', [" ^ space_implode ", " vnames ^ "]).\n"
   146   "writef('" ^ implode (map (fn v => v ^ " = %w\\n") vnames) ^"', [" ^ space_implode ", " vnames ^ "]).\n"
   145   
   147   
   146 fun query_firstn n rel vnames =
   148 fun query_firstn n rel vnames =
   159   "main :- halt(1).\n"
   161   "main :- halt(1).\n"
   160 
   162 
   161 (* parsing prolog solution *)
   163 (* parsing prolog solution *)
   162 
   164 
   163 val scan_atom =
   165 val scan_atom =
   164   Scan.repeat (Scan.one (fn s => Symbol.is_ascii_lower s orelse Symbol.is_ascii_quasi s))
   166   Scan.many1 (fn s => Symbol.is_ascii_lower s orelse Symbol.is_ascii_quasi s)
   165 
   167 
   166 val scan_var =
   168 val scan_var =
   167   Scan.repeat (Scan.one
   169   Scan.many1
   168     (fn s => Symbol.is_ascii_upper s orelse Symbol.is_ascii_digit s orelse Symbol.is_ascii_quasi s))
   170     (fn s => Symbol.is_ascii_upper s orelse Symbol.is_ascii_digit s orelse Symbol.is_ascii_quasi s)
   169 
   171 
   170 val scan_ident =
   172 val scan_ident =
   171   Scan.repeat (Scan.one
   173   Scan.repeat (Scan.one
   172     (fn s => Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s orelse Symbol.is_ascii_quasi s))
   174     (fn s => Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s orelse Symbol.is_ascii_quasi s))
   173 
   175 
   177 
   179 
   178 val is_atom_ident = forall Symbol.is_ascii_lower
   180 val is_atom_ident = forall Symbol.is_ascii_lower
   179 
   181 
   180 val is_var_ident =
   182 val is_var_ident =
   181   forall (fn s => Symbol.is_ascii_upper s orelse Symbol.is_ascii_digit s orelse Symbol.is_ascii_quasi s)
   183   forall (fn s => Symbol.is_ascii_upper s orelse Symbol.is_ascii_digit s orelse Symbol.is_ascii_quasi s)
   182 
   184 (*
       
   185 fun repeat_sep sep scan =
       
   186   let
       
   187     fun rep ys xs =
       
   188        (case (SOME (scan xs) handle FAIL _ => NONE) of
       
   189         NONE => (rev ys, xs)
       
   190       | SOME (y, xs') =>
       
   191           case (SOME (scan sep) handle FAIL _ => NONE) of
       
   192           NONE => (rev (y :: ys), xs')
       
   193         | SOME (_, xs'') => rep (y :: ys) xs'')
       
   194   in rep [] end;
       
   195 
       
   196 fun repeat_sep1 sep scan = (scan --| sep) ::: repeat_sep sep scan;
       
   197 *) 
       
   198 
       
   199 fun scan_terms xs = (((scan_term --| $$ ",") ::: scan_terms)
       
   200   || (scan_term >> single)) xs
       
   201 and scan_term xs =
       
   202   ((scan_var >> (fn s => Var (string_of s, dummyT)))
       
   203   || ((scan_atom -- ($$ "(" |-- scan_terms --| $$ ")"))
       
   204     >> (fn (f, ts) => AppF (string_of f, rev ts)))
       
   205   || (scan_atom >> (Cons o string_of))) xs
       
   206 (*  
   183 val scan_term =
   207 val scan_term =
   184   scan_ident >> (fn s => 
   208   scan_ident >> (fn s => 
   185     if is_var_ident s then (Var (string_of s, dummyT))
   209     if is_var_ident s then (Var (string_of s, dummyT))
   186     else if is_atom_ident s then
   210     else if is_atom_ident s then
   187     else   Cons (string_of s)
   211     else Cons (string_of s)
   188     else raise Fail "unexpected")
   212     else raise Fail "unexpected")
   189     
   213 *)    
   190 val parse_term = fst o Scan.finite Symbol.stopper
   214 val parse_term = fst o Scan.finite Symbol.stopper
   191     (Scan.error (!! (fn _ => raise Fail "parsing prolog output failed")) scan_term)
   215     (Scan.error (!! (fn _ => raise Fail "parsing prolog output failed")) scan_term)
   192   o explode
   216   o explode
   193   
   217   
   194 fun parse_solution sol =
   218 fun parse_solution sol =
   195   let
   219   let
   196     fun dest_eq s = case space_explode "=" s of
   220     fun dest_eq s = case space_explode "=" s of
   197         (l :: r :: []) => parse_term (unprefix " " r)
   221         (l :: r :: []) => parse_term (unprefix " " r)
   198       | _ => raise Fail "unexpected equation in prolog output")
   222       | _ => raise Fail "unexpected equation in prolog output"
   199   in
   223   in
   200     map dest_eq (fst (split_last (space_explode "\n" sol)))
   224     map dest_eq (fst (split_last (space_explode "\n" sol)))
   201   end 
   225   end 
   202   
   226   
   203 (* calling external interpreter and getting results *)
   227 (* calling external interpreter and getting results *)