1% ---------------------------------------------------------------------- 2% BEGIN LICENSE BLOCK 3% Version: CMPL 1.1 4% 5% The contents of this file are subject to the Cisco-style Mozilla Public 6% License Version 1.1 (the "License"); you may not use this file except 7% in compliance with the License. You may obtain a copy of the License 8% at www.eclipse-clp.org/license. 9% 10% Software distributed under the License is distributed on an "AS IS" 11% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 12% the License for the specific language governing rights and limitations 13% under the License. 14% 15% The Original Code is The ECLiPSe Constraint Logic Programming System. 16% The Initial Developer of the Original Code is Cisco Systems, Inc. 17% Portions created by the Initial Developer are 18% Copyright (C) 1989-2006 Cisco Systems, Inc. All Rights Reserved. 19% 20% Contributor(s): ECRC GmbH 21% Contributor(s): IC-Parc, Imperal College London 22% 23% END LICENSE BLOCK 24% 25% System: ECLiPSe Constraint Logic Programming System 26% Version: $Id: cprolog.pl,v 1.10 2013/06/16 02:21:27 jschimpf Exp $ 27% ---------------------------------------------------------------------- 28 29/* 30 * SEPIA PROLOG SOURCE MODULE 31 */ 32 33/* 34 * IDENTIFICATION: cprolog.pl 35 * 36 * DESCRIPTION: C-Prolog compatibility package. 37 * This is also the basis for the 38 * Quintus and SICStus packages. 39 * 40 * CONTENTS: 41 * 42 */ 43 44:- module(cprolog). 45 46:- comment(categories, ["Compatibility"]). 47:- comment(summary, 'C-Prolog compatibility package'). 48:- comment(author, 'Various, ECRC Munich'). 49:- comment(copyright, 'Cisco Systems, Inc'). 50:- comment(date, '$Date: 2013/06/16 02:21:27 $'). 51:- comment(desc, html(' 52 One of the requirements during the development of ECLiPSe has been the 53 aim of minimising the work required to port traditional Prolog 54 programs to ECLiPSe. A de-facto standard for many years was the 55 C-Prolog dialect, often referred to as Edinburgh Prolog. Therefore, 56 many of the non standard predicates in C-Prolog have also been 57 included in ECLiPSe. It is of course impossible to achieve total 58 compatibility between the two systems. To assist in making the 59 changes necessary to run a C-Prolog program on the current version of 60 ECLiPSe, we describve here the predicates available in the 61 C-Prolog compatibility library and summarise the principal 62 differences between ECLiPSe Prolog and C-Prolog. 63 <P> 64 Most of the C-Prolog predicates are also ECLiPSe built-in predicates 65 and so they can be always accessed. 66 <P> 67 Please note that this text does not detail the functionality of 68 C-Prolog, refer to the C-Prolog documentation for this information. 69 <P> 70 The effect of the compatibility library is local to the module where 71 it is loaded. For maximum compatibility, a C-Prolog program should 72 be wrapped in a separate module starting with a directive like 73 <PRE> 74 :- module(mymodule, [], cprolog). 75 </PRE> 76 In this case, Eclipse-specific language constructs will not be available. 77 <P> 78 If the compatibility package is loaded into a standard module, e.g. like 79 <PRE> 80 :- module(mymixedmdule). 81 :- use_module(library(cprolog)). 82 </PRE> 83 then C-Prolog and Eclipse language features can be used together. 84 However, ambiguities must be resolved explicitly and confusion may 85 arise from the different meaning of quotes in Eclipse vs C-Prolog. 86 <P> 87 Note that the C-Prolog compatibility package includes the <EM>cio</EM> 88 library (for see/1, seeing/1, seen/0, skip/1, tab/1, tell/1, telling/1, 89 told/0). 90 <P> 91 The following C-Prolog predicates are not available in ECLiPSe, or 92 the corresponding predicates have a different semantics: 93 <DL> 94 <DT>assert/2, asserta/2, assertz/2, clause/3 95 <DD>ECLiPSe does not support database references for clauses. 96 <DT>expand_term/2 97 <DD>This is not supported. ECLiPSe provides the macro facility 98 for transforming input terms (see chapter 13). 99 <DT>'LC'/0, 'NOLC'/0 100 <DD>These are not supported in ECLiPSe. 101 </DL> 102 <P> 103 The following differences remain even with the compatibility package: 104 <DL> 105 <DT>Database References 106 <DD>ECLiPSe provides database references only for terms in the indexed database, not for program clauses. 107 <DT>Numbers 108 <DD>C-Prolog has a tendency to "prefer" integers over real 109 numbers. For instance, under C-Prolog when the call X is 110 4.0/2.0 is made, X is instantiated to an integer. This 111 behaviour does not occur in ECLiPSe. The order of integers 112 and reals in the standard order is different. 113 <DT>Operators 114 <DD>In C-Prolog there is a bug regarding the operator not -- it 115 binds closer than its precedence declaration. 116 <DT>Strings 117 <DD>Strings are simulated in C-Prolog by lists. Under C-Prolog 118 mode, ECLiPSe provides this functionality -- double-quoted 119 strings are parsed as lists of integers. This can cause 120 confusion when pure ECLiPSe predicates are used in C-Prolog 121 mode, e.g. substring/3 will not accept double-quoted items, 122 since they are lists, not ECLiPSe strings. The built-in 123 string_list/2 converts between both representations. 124 <DT>consult/1, reconsult/1 125 <DD>These are implemented by simply calling the ECLiPSe predicate 126 compile/1. By default all compiled procedures are static. 127 Procedures on which assert/1 etc. will be applied, have to be 128 declared as dynamic using dynamic/1. The notation [-File] for 129 reconsult/1 is not supported. 130 <DT>get/1 131 <DD>This is similar to the ECLiPSe predicate get/1, but 132 control characters and blank spaces are skipped. 133 <DT>put/1 134 <DD>This is similar to the ECLiPSe predicate put/1, but it 135 first applies arithmetic evaluation to its argument. 136 <DT>heapused/1 137 <DD>Needed for evaluating heapused in arithmetic expressions. 138 It returns the sum of code heap and general heap usage. 139 <DT>instance/2 140 <DD>Note that this compatibility predicate redefines the 141 ECLiPSe builtin of the same name but different meaning (which 142 is no longer available in C-Prolog mode). It is implemented 143 using the ECLiPSe predicate referenced_record/2. 144 <DT>log/2, log10/2 145 <DD>These are not predicates in C-Prolog (arithmetic 146 functors), but in ECLiPSe they are needed for evaluating log/1 147 and log10/1 in arithmetic expressions. 148 <DT>ttyput/1 149 <DD>corresponds to the DEC-10 Prolog predicate 150 </DL> 151 The list below describes the syntax differences between ECLiPSe 152 and C-Prolog. The following C-Prolog properties are simulated by 153 the compatibility package: 154 <UL> 155 <LI>single (resp. double) quote must be doubled between single (resp. double) quotes. 156 <LI>$ is a normal character. 157 <LI>the symbol | is not an atom. 158 </UL> 159 The following properties of original C-Prolog are not simulated by 160 the compatibility package: 161 <UL> 162 <LI>a clause can not be ended by end of file. 163 <LI>based integers are not accepted. 164 <LI>comments are not a delimiter (just ignored). 165 <LI>{} is not an atom. 166 <LI>[] can not be a functor. 167 </UL> 168 ')). 169:- comment(see_also, [library(cio),library(quintus)]). 170 171 172:- reexport cio. 173 174% suppress deprecation warnings for reexported builtins 175:- pragma(deprecated_warnings(not_reexports)). 176 177:- reexport eclipse_language except 178 179 get/1, % redefined predicates 180 put/1, 181 instance/2, 182 (abolish)/1, 183 arg/3, 184 185% op(_, xfx, (of)), % don't provide these 186% op(_, xfx, (with)), 187% op(_, xfy, (do)), 188% op(_, xfx, (@)), 189% op(_, fx, (-?->)), 190% macro((with)/2, _, _), 191% macro((of)/2, _, _), 192 193 macro((if)/2,_,_). 194 195:- export % temporary, while op/macros still global 196 op(0, xfx, (of)), 197 op(0, xfx, (with)), 198 op(0, xfy, (do)), 199 op(0, xfx, (@)), 200 op(0, fx, (-?->)), 201 macro((with)/2, (=)/2, []), 202 macro((of)/2, (=)/2, []). 203 204:- local 205 op(1100, xfy, (do)), 206 op(650, xfx, (@)). 207 208:- export 209 syntax_option(nl_in_quotes), 210 syntax_option(no_blanks), 211 syntax_option(no_array_subscripts), 212 syntax_option(limit_arg_precedence), 213 syntax_option(doubled_quote_is_quote), 214 syntax_option(bar_is_no_atom), 215 syntax_option(bar_is_semicolon), 216 syntax_option(no_attributes), 217 syntax_option(no_curly_arguments), 218 syntax_option(blanks_after_sign), 219 220 chtab(0'$, lower_case), 221 chtab(0'\, symbol), % disable escape sequences 222 chtab(128, string_quote), % there must be some string_quote 223 chtab(0'", list_quote), 224 225 op(300, xfx, mod), 226 op(500, fx, (+)), 227 op(500, fx, (-)), 228 op(900, fy, (spy)), 229 op(900, fy, (nospy)). 230 231:- export 232 (.)/3, % to evaluate lists in arithmetic expressions 233 (abolish)/2, 234 arg/3, 235 consult/1, 236 current_functor/2, 237 current_predicate/2, 238 db_reference/1, 239 erased/1, 240 fileerrors/0, 241 get/1, 242 get0/1, 243 heapused/1, 244 instance/2, 245 leash/1, 246 log10/2, 247 log/2, 248 nofileerrors/0, 249 primitive/1, 250 prompt/2, 251 put/1, 252 reconsult/1, 253 sh/0. 254 255:- skipped 256 (abolish)/2, 257 consult/1, 258 current_functor/2, 259 erased/1, 260 fileerrors/0, 261 get/1, 262 get0/1, 263 instance/2, 264 log10/2, 265 nofileerrors/0, 266 primitive/1, 267 prompt/2, 268 put/1, 269 reconsult/1. 270 271:- import 272 current_predicate_body / 2, 273 error_handler / 2, 274 get_flag_body/4, 275 set_default_error_handler/2, 276 system_error_handler / 4, 277 undef_dynamic_handler / 3 278 from sepia_kernel. 279 280:- system. % compiler directive to add the SYSTEM flag 281 282 283/* 284 * OTHER DIRECTIVES 285 */ 286 287 288:- tool((abolish)/2, abolish_body/3), 289 tool(consult/1, consult_/2), 290 tool(reconsult/1, reconsult_/2), 291 tool(current_predicate/2, current_predicate_body/3). 292 293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 294% 295% EVENT HANDLERS 296% 297%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 298 299% This simulates Quintus' behaviour 300cp_undef_dynamic_handler(_, retract_all(_), _) :- !. 301cp_undef_dynamic_handler(_, retractall(_), _) :- !. 302cp_undef_dynamic_handler(_, listing(_), _) :- !. 303cp_undef_dynamic_handler(_, retract(_), _) :- !, fail. 304cp_undef_dynamic_handler(_, clause(_), _) :- !, fail. 305cp_undef_dynamic_handler(_, clause(_, _), _) :- !, fail. 306cp_undef_dynamic_handler(E, G, M) :- 307 undef_dynamic_handler(E, G, M). 308 309cp_access_undefined(_, abolish(_)) :- 310 !. 311cp_access_undefined(X,Y) :- 312 error_handler(X,Y). 313 314nofileerrors_handler(_, open(_, _, _), _, _) :- !, fail. 315nofileerrors_handler(N, Goal, CM, LM) :- 316 system_error_handler(N, Goal, CM, LM). 317 318fileerrors :- 319 set_default_error_handler(170, system_error_handler/4), 320 set_default_error_handler(171, error_handler/2), 321 reset_event_handler(170), 322 reset_event_handler(171). 323 324nofileerrors :- 325 set_default_error_handler(170, nofileerrors_handler/4), 326 set_default_error_handler(171, fail/0), 327 reset_event_handler(170), 328 reset_event_handler(171). 329 330:- 331 % we may change the default handlers, because we can't switch back 332 set_default_error_handler(60, cp_access_undefined/2), 333 reset_event_handler(60), 334 set_default_error_handler(70, cp_undef_dynamic_handler/3), 335 reset_event_handler(70), 336 set_default_error_handler(100, cp_undef_dynamic_handler/3), 337 reset_event_handler(100). 338 339 340%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 341% 342% NEW PREDICATES 343% 344%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 345 346sh :- 347 getenv('SHELL', X), 348 sh(X). 349 350primitive(X) :- atom(X), !, fail. 351primitive(X) :- atomic(X). 352 353db_reference(X) :- type_of(X, handle). 354 355get0(X):- get(input, X). 356 357leash(Ports) :- 358 set_leash(_, print), 359 set_leash(Ports, stop). 360 361 362heapused(X) :- X is statistics(general_heap_used) + statistics(code_heap_used). 363 364prompt(Old, New) :- 365 get_stream_info(input, prompt, Old), 366 set_stream_property(input, prompt, New). 367 368ttyput(Char) :- 369 N is Char, 370 put(stdout, N). 371 372current_functor(F, T) :- 373 current_functor(F/A), 374 functor(T, F, A). 375 376abolish_body(N, A, M) :- 377 sepia_kernel:abolish(N/A)@M. 378 379consult_(File, Module) :- 380 compile(File)@Module. 381 382reconsult_(File, Module) :- 383 compile(File)@Module. 384 385erased(Ref) :- 386 \+referenced_record(Ref, _). 387 388% ARITHMETIC 389 390log10(Y,X):- X is ln(Y)/ln(10.0). 391 392log(Y,X) :- X is ln(Y). 393 394.(X,_,X). 395 396% allow expressions built at runtime without an eval wrapper to be evaluated 397 398:- set_event_handler(24, eval_expr/2). 399 400eval_expr(N, ArithGoal) :- 401 functor(ArithGoal, Op, A), 402 NewA is A - 1, 403 functor(Expr, Op, NewA), 404 ( sepia_kernel:arith_builtin(Expr) -> 405 ( foreacharg(X,Expr,I), param(ArithGoal) do 406 eclipse_language:arg(I, ArithGoal, X) 407 ), 408 eclipse_language:arg(A, ArithGoal, Res), 409 Res is Expr 410 ; 411 error(default(N), ArithGoal) 412 ). 413 414 415%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 416% 417% REDEFINED PREDICATES 418% 419%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 420 421get(X):- repeat, get(input, X), X > 32, X < 127, !. 422 423put(X):- N is X, put(output,N). 424 425instance(Ref, Term) :- 426 referenced_record(Ref, Term). 427 428current_predicate_body(F, T, M) :- 429 current_predicate_body(F/A, M), 430 functor(T, F, A), 431 get_flag_body(F/A, definition_module, M, M). 432 433arg(N, S, X) :- 434 nonvar(S), 435 integer(N), 436 1 =< N, N =< arity(S), 437 eclipse_language:arg(N, S, X). 438 439