caml-urm
A OCaml module for manipulating unlimited register machines
urm.mli (3566B)
1 (** Unlimited register machines 2 3 This module provides various types and functions for manipulating unlimited 4 register machines (URMs). This implementation is besed on the specification 5 provided in Ramin Naimi's URM simulator, which is in turn based on that of 6 {i Computability, An introduction to recursive function theory } by Nigel J. 7 Cutland. For example, the instruction set is given by: 8 9 - [T(n, m)] transfers the contents of the [n]-th register to [m]-th register. 10 - [Z(n)] sets the value of the [n]-th register to zero. 11 - [S(n)] increments the value of the [n]-th register. 12 - [P(n)] decrements the value of the [n]-th register. 13 - [J(n, m, i)] jumps to the [i]-th instruction if the values of the [n]-th and 14 [m]-th coincide. The instruction count starts at 1, so [i = 1] jumps to the 15 first instruction. 16 17 The register set, however, is a bit different. In Nigel's specification the 18 registers are indexed by natural numbers (starting from 1), while in this 19 implementation the registers are indexed by arbitrary integers. Also, in 20 Nigel's specification registers store natural numbers (starting from 0) and in 21 this implementation they store arbitrary integers. I have also added the [P] 22 instruction to help users handle negative integers. 23 24 @see <sites.oxy.edu/rnaimi/home/URMsim.htm> URM simulator. 25 @see <doi.org/10.1017/CBO9781139171496> Computability, An introduction to 26 recursive function theory. *) 27 28 (** The type of instructions. *) 29 type instruction = 30 | T of int * int 31 | Z of int 32 | S of int 33 | P of int 34 | J of int * int * int 35 36 (** The type of all possible states of a URM. *) 37 type t 38 39 (** An alias for {! t } *) 40 type machine = t 41 42 (** Returns a machine whose register values are given by a function. *) 43 val of_registers : (int -> int) -> machine 44 45 (** Returns a machine whose registers are given by the pairs in a list. All 46 other registers are zero initialized. *) 47 val of_list : (int * int) list -> machine 48 49 (** [register m i] returns the value of the [i]-th register of [m]. *) 50 val register : machine -> int -> int 51 52 (** A machine whose registers are all zeros. *) 53 val zeros : machine 54 55 (** [exec m program] returns a machine whose register values are given by the 56 register values of 57 [m] with updates corresponding to the execution of [program]. 58 59 This function only returns when [program] actually halts. Please use {! 60 nexec } if you don't trust [program]. 61 62 @raise Invalid_argument if [program] attempts to jump to a non-positive 63 integer. *) 64 val exec : instruction array -> machine -> machine 65 66 (** A safe version of {! exec }, where the maximum number of clock-cycles 67 allowed is controlled the first argument. Each instruction takes a single 68 clock-cycle to execute. 69 70 [nexec n program] returns [Some _] if [program] halts in at most [n] 71 clock-cycles and [None] otherwise. 72 73 @raise Invalid_argument if [program] attempts to jump to a non-positive 74 integer. @raise Invalid_argument if [n] is not a positive integer. *) 75 val nexec : int -> instruction array -> machine -> machine option 76 77 (** Exception raised when parsing fails. *) 78 exception Syntax_error of string 79 80 (** Parse a program from a string. The syntax used by the parser is based on 81 the one used by Ramin Naimi's URM simulator, but again the register indexes 82 can be arbitrary integers. 83 84 @see <sites.oxy.edu/rnaimi/home/URMsim.htm> URM simulator. 85 86 @raise Syntax_error in case any syntax error is encountered, including 87 invalid syntax and jumps to invalid addresses. *) 88 val parse : string -> instruction array