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 *) |