├── .atom └── ide-reason.json ├── .gitignore ├── .ocp-indent ├── Makefile ├── OCalc.opam ├── README.md ├── assets ├── 404.html ├── Roboto-Regular.ttf ├── camel.png ├── drapeau_eng.png ├── drapeau_fr.png ├── dune ├── gl-matrix-min.js ├── gl-matrix-min.js-old ├── include.math ├── index.html ├── index.js ├── logo.png └── pi.png ├── create-release.sh ├── dune ├── dune-project ├── equation.ml ├── equation0.equ ├── equation1.equ ├── equation2.equ ├── equation3.equ ├── equation4.equ ├── equation5.equ ├── equation6.equ ├── matrix.ml ├── package.json └── src ├── interfaces ├── commune.ml ├── dune ├── topCmd.ml ├── topCmd.mli ├── topFichiers.ml ├── topFichiers.mli ├── topGui.ml ├── topGui.mli ├── topServeur.ml ├── topServeur.mli ├── topTest.ml └── topTest.mli ├── modules ├── I18n.ml ├── I18n.mli ├── dune ├── grandEntier_off.ml ├── grandEntier_off.mli ├── grandEntier_on.ml ├── grandEntier_on.mli ├── grandNum_on.ml ├── grandNum_on.mli ├── grandRationnel_on.ml ├── grandReel_on.ml ├── grandReel_on.mli ├── matrix.ml └── matrix.mli └── noyau ├── ancien_moteur.ml ├── ancien_moteur.mli ├── dune ├── lexer.ml ├── lexer.mli ├── lien.ml ├── moteur.ml ├── moteur.mli ├── nouveau_lexer.ml ├── nouveau_lexer.mli ├── nouveau_parser.ml ├── nouveau_parser.mli ├── nouveau_type.ml ├── parser.ml ├── parser.mli ├── type.ml ├── type.mli ├── utils.ml └── utils.mli /.atom/ide-reason.json: -------------------------------------------------------------------------------- 1 | { 2 | "server": { 3 | "tool": "rls" 4 | }, 5 | "rls": { 6 | "refmt": "", 7 | "lispRefmt": "", 8 | "format_width": 80, 9 | "autoRebuild": true 10 | }, 11 | "ols": { 12 | "codelens": { 13 | "enabled": true, 14 | "unicode": true 15 | }, 16 | "debounce": { 17 | "linter": 500 18 | }, 19 | "diagnostics": { 20 | "merlinPerfLogging": false, 21 | "tools": [ 22 | "merlin" 23 | ] 24 | }, 25 | "format": { 26 | "width": null 27 | }, 28 | "path": { 29 | "bsb": "./node_modules/bs-platform/lib/bsb.exe", 30 | "env": "env", 31 | "esy": "esy", 32 | "ocamlfind": "ocamlfind", 33 | "ocamlmerlin": "ocamlmerlin", 34 | "ocpindent": "ocp-indent", 35 | "opam": "opam", 36 | "rebuild": "rebuild", 37 | "refmt": "refmt", 38 | "refmterr": "refmterr", 39 | "rtop": "rtop" 40 | }, 41 | "server": { 42 | "languages": [ 43 | "ocaml", 44 | "reason" 45 | ] 46 | } 47 | }, 48 | "autocompleteResultsFirst": true 49 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | test 3 | *.cm* 4 | *~ 5 | src2 6 | obj/lien.ml 7 | bin 8 | a.out 9 | esy.lock 10 | _esy 11 | node_modules 12 | .o 13 | .a 14 | .exe 15 | .merlin 16 | OCalc.install 17 | -------------------------------------------------------------------------------- /.ocp-indent: -------------------------------------------------------------------------------- 1 | normal 2 | with=0 3 | syntax=lwt mll 4 | max_indent=2 5 | ppx_stritem_ext=0 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SRC=type.ml utils.ml lexer.ml parser.ml grandEntier.mli grandEntier.ml 2 | SRC_TEST=$(SRC) test.ml 3 | SRC_BUILD=$(SRC) toplevel.ml 4 | SRC_INTERPRETE=$(SRC) interprete.ml 5 | 6 | build: $(SRC_BUILD) 7 | ocamlc $^ -o $@ 8 | ./$@ 9 | rm $@ 10 | 11 | test: $(SRC_TEST) 12 | ocamlc $^ -o $@ 13 | ./$@ 14 | rm $@ 15 | 16 | #-u -s option may speed up a little 17 | 18 | interprete: 19 | (sed -r 's/open (.*)/;;\n#use "\L\1.ml";;/g' $(SRC_INTERPRETE); echo \;\;; cat -) | ocaml 20 | 21 | eval: 22 | (sed -r 's/open (.*)/;;\n#use "\L\1.ml";;/g' $(SRC_INTERPRETE); echo \;\;) | ocaml 23 | 24 | clean: 25 | rm -f *.cm* *.html 26 | #*.css we will have our special stylesheet so don't remove it 27 | 28 | doc_build: build 29 | ocamldoc -html -all-params -colorize-code -charset utf-8 $(SRC_BUILD) 30 | -------------------------------------------------------------------------------- /OCalc.opam: -------------------------------------------------------------------------------- 1 | opam-version: "2.0" 2 | version: "dev" 3 | maintainer: [ 4 | "elie.brami@epita.fr" 5 | "alexandre.mourgues@epita.fr" 6 | "gautier.habermann@epita.fr" 7 | "quentin.feugueur@epita.fr" 8 | ] 9 | author: [ 10 | "elie.brami" 11 | "alexandre.mourgues" 12 | "gautier.habermann" 13 | "quentin.feugueur" 14 | ] 15 | build: [ 16 | 17 | ] 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ocalc 2 | 3 | This project is a formal calculator made in OCaml 4 | 5 | ## How to install on Windows 6 | 7 | 1. Download as a zip and unzip or clone the repository 8 | 2. Execute `install_deps.bat` (It will install the cygwin dependencies, only choose the mirror and then next ... next) 9 | 3. Execute `compile.bat` (It will compile the project) 10 | 4. Launch by executing `launch.bat` 11 | -------------------------------------------------------------------------------- /assets/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page non trouvé 7 | 15 | 16 | 17 | 18 |

Page non trouvé

19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /assets/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/Roboto-Regular.ttf -------------------------------------------------------------------------------- /assets/camel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/camel.png -------------------------------------------------------------------------------- /assets/drapeau_eng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/drapeau_eng.png -------------------------------------------------------------------------------- /assets/drapeau_fr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/drapeau_fr.png -------------------------------------------------------------------------------- /assets/dune: -------------------------------------------------------------------------------- 1 | (install 2 | (section bin) 3 | (package OCalc) 4 | (files 5 | Roboto-Regular.ttf 6 | logo.png 7 | pi.png 8 | camel.png 9 | drapeau_fr.png 10 | drapeau_eng.png 11 | index.html 12 | 404.html 13 | index.js 14 | include.math 15 | (../src/interfaces/topGui.bc.js as OCalc.bc.js) 16 | gl-matrix-min.js)) 17 | -------------------------------------------------------------------------------- /assets/gl-matrix-min.js-old: -------------------------------------------------------------------------------- 1 | /*! 2 | @fileoverview gl-matrix - High performance matrix and vector operations 3 | @author Brandon Jones 4 | @author Colin MacKenzie IV 5 | @version 3.0.0 6 | 7 | Copyright (c) 2015-2019, Brandon Jones, Colin MacKenzie IV. 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | THE SOFTWARE. 26 | 27 | */ 28 | !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t=t||self).glMatrix={})}(this,function(t){"use strict";var n=1e-6,a="undefined"!=typeof Float32Array?Float32Array:Array,r=Math.random;var u=Math.PI/180;Math.hypot||(Math.hypot=function(){for(var t=0,n=arguments.length;n--;)t+=arguments[n]*arguments[n];return Math.sqrt(t)});var e=Object.freeze({EPSILON:n,get ARRAY_TYPE(){return a},RANDOM:r,setMatrixArrayType:function(t){a=t},toRadian:function(t){return t*u},equals:function(t,a){return Math.abs(t-a)<=n*Math.max(1,Math.abs(t),Math.abs(a))}});function o(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=a[0],c=a[1],h=a[2],s=a[3];return t[0]=r*i+e*c,t[1]=u*i+o*c,t[2]=r*h+e*s,t[3]=u*h+o*s,t}function i(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t[3]=n[3]-a[3],t}var c=o,h=i,s=Object.freeze({create:function(){var t=new a(4);return a!=Float32Array&&(t[1]=0,t[2]=0),t[0]=1,t[3]=1,t},clone:function(t){var n=new a(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},copy:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},identity:function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},fromValues:function(t,n,r,u){var e=new a(4);return e[0]=t,e[1]=n,e[2]=r,e[3]=u,e},set:function(t,n,a,r,u){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t},transpose:function(t,n){if(t===n){var a=n[1];t[1]=n[2],t[2]=a}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},invert:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=a*e-u*r;return o?(o=1/o,t[0]=e*o,t[1]=-r*o,t[2]=-u*o,t[3]=a*o,t):null},adjoint:function(t,n){var a=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=a,t},determinant:function(t){return t[0]*t[3]-t[2]*t[1]},multiply:o,rotate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=Math.sin(a),c=Math.cos(a);return t[0]=r*c+e*i,t[1]=u*c+o*i,t[2]=r*-i+e*c,t[3]=u*-i+o*c,t},scale:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=a[0],c=a[1];return t[0]=r*i,t[1]=u*i,t[2]=e*c,t[3]=o*c,t},fromRotation:function(t,n){var a=Math.sin(n),r=Math.cos(n);return t[0]=r,t[1]=a,t[2]=-a,t[3]=r,t},fromScaling:function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},str:function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},frob:function(t){return Math.hypot(t[0],t[1],t[2],t[3])},LDU:function(t,n,a,r){return t[2]=r[2]/r[0],a[0]=r[0],a[1]=r[1],a[3]=r[3]-t[2]*a[1],[t,n,a]},add:function(t,n,a){return t[0]=n[0]+a[0],t[1]=n[1]+a[1],t[2]=n[2]+a[2],t[3]=n[3]+a[3],t},subtract:i,exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=a[0],c=a[1],h=a[2],s=a[3];return Math.abs(r-i)<=n*Math.max(1,Math.abs(r),Math.abs(i))&&Math.abs(u-c)<=n*Math.max(1,Math.abs(u),Math.abs(c))&&Math.abs(e-h)<=n*Math.max(1,Math.abs(e),Math.abs(h))&&Math.abs(o-s)<=n*Math.max(1,Math.abs(o),Math.abs(s))},multiplyScalar:function(t,n,a){return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t},multiplyScalarAndAdd:function(t,n,a,r){return t[0]=n[0]+a[0]*r,t[1]=n[1]+a[1]*r,t[2]=n[2]+a[2]*r,t[3]=n[3]+a[3]*r,t},mul:c,sub:h});function M(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=a[0],s=a[1],M=a[2],f=a[3],l=a[4],v=a[5];return t[0]=r*h+e*s,t[1]=u*h+o*s,t[2]=r*M+e*f,t[3]=u*M+o*f,t[4]=r*l+e*v+i,t[5]=u*l+o*v+c,t}function f(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t[3]=n[3]-a[3],t[4]=n[4]-a[4],t[5]=n[5]-a[5],t}var l=M,v=f,b=Object.freeze({create:function(){var t=new a(6);return a!=Float32Array&&(t[1]=0,t[2]=0,t[4]=0,t[5]=0),t[0]=1,t[3]=1,t},clone:function(t){var n=new a(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},copy:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},identity:function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},fromValues:function(t,n,r,u,e,o){var i=new a(6);return i[0]=t,i[1]=n,i[2]=r,i[3]=u,i[4]=e,i[5]=o,i},set:function(t,n,a,r,u,e,o){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t[4]=e,t[5]=o,t},invert:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=a*e-r*u;return c?(c=1/c,t[0]=e*c,t[1]=-r*c,t[2]=-u*c,t[3]=a*c,t[4]=(u*i-e*o)*c,t[5]=(r*o-a*i)*c,t):null},determinant:function(t){return t[0]*t[3]-t[1]*t[2]},multiply:M,rotate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=Math.sin(a),s=Math.cos(a);return t[0]=r*s+e*h,t[1]=u*s+o*h,t[2]=r*-h+e*s,t[3]=u*-h+o*s,t[4]=i,t[5]=c,t},scale:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=a[0],s=a[1];return t[0]=r*h,t[1]=u*h,t[2]=e*s,t[3]=o*s,t[4]=i,t[5]=c,t},translate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=a[0],s=a[1];return t[0]=r,t[1]=u,t[2]=e,t[3]=o,t[4]=r*h+e*s+i,t[5]=u*h+o*s+c,t},fromRotation:function(t,n){var a=Math.sin(n),r=Math.cos(n);return t[0]=r,t[1]=a,t[2]=-a,t[3]=r,t[4]=0,t[5]=0,t},fromScaling:function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},fromTranslation:function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},str:function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},frob:function(t){return Math.hypot(t[0],t[1],t[2],t[3],t[4],t[5],1)},add:function(t,n,a){return t[0]=n[0]+a[0],t[1]=n[1]+a[1],t[2]=n[2]+a[2],t[3]=n[3]+a[3],t[4]=n[4]+a[4],t[5]=n[5]+a[5],t},subtract:f,multiplyScalar:function(t,n,a){return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*a,t[5]=n[5]*a,t},multiplyScalarAndAdd:function(t,n,a,r){return t[0]=n[0]+a[0]*r,t[1]=n[1]+a[1]*r,t[2]=n[2]+a[2]*r,t[3]=n[3]+a[3]*r,t[4]=n[4]+a[4]*r,t[5]=n[5]+a[5]*r,t},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=t[4],c=t[5],h=a[0],s=a[1],M=a[2],f=a[3],l=a[4],v=a[5];return Math.abs(r-h)<=n*Math.max(1,Math.abs(r),Math.abs(h))&&Math.abs(u-s)<=n*Math.max(1,Math.abs(u),Math.abs(s))&&Math.abs(e-M)<=n*Math.max(1,Math.abs(e),Math.abs(M))&&Math.abs(o-f)<=n*Math.max(1,Math.abs(o),Math.abs(f))&&Math.abs(i-l)<=n*Math.max(1,Math.abs(i),Math.abs(l))&&Math.abs(c-v)<=n*Math.max(1,Math.abs(c),Math.abs(v))},mul:l,sub:v});function m(){var t=new a(9);return a!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[5]=0,t[6]=0,t[7]=0),t[0]=1,t[4]=1,t[8]=1,t}function d(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=n[8],f=a[0],l=a[1],v=a[2],b=a[3],m=a[4],d=a[5],x=a[6],p=a[7],y=a[8];return t[0]=f*r+l*o+v*h,t[1]=f*u+l*i+v*s,t[2]=f*e+l*c+v*M,t[3]=b*r+m*o+d*h,t[4]=b*u+m*i+d*s,t[5]=b*e+m*c+d*M,t[6]=x*r+p*o+y*h,t[7]=x*u+p*i+y*s,t[8]=x*e+p*c+y*M,t}function x(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t[3]=n[3]-a[3],t[4]=n[4]-a[4],t[5]=n[5]-a[5],t[6]=n[6]-a[6],t[7]=n[7]-a[7],t[8]=n[8]-a[8],t}var p=d,y=x,q=Object.freeze({create:m,fromMat4:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},clone:function(t){var n=new a(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},copy:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},fromValues:function(t,n,r,u,e,o,i,c,h){var s=new a(9);return s[0]=t,s[1]=n,s[2]=r,s[3]=u,s[4]=e,s[5]=o,s[6]=i,s[7]=c,s[8]=h,s},set:function(t,n,a,r,u,e,o,i,c,h){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t[4]=e,t[5]=o,t[6]=i,t[7]=c,t[8]=h,t},identity:function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},transpose:function(t,n){if(t===n){var a=n[1],r=n[2],u=n[5];t[1]=n[3],t[2]=n[6],t[3]=a,t[5]=n[7],t[6]=r,t[7]=u}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},invert:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=n[6],h=n[7],s=n[8],M=s*o-i*h,f=-s*e+i*c,l=h*e-o*c,v=a*M+r*f+u*l;return v?(v=1/v,t[0]=M*v,t[1]=(-s*r+u*h)*v,t[2]=(i*r-u*o)*v,t[3]=f*v,t[4]=(s*a-u*c)*v,t[5]=(-i*a+u*e)*v,t[6]=l*v,t[7]=(-h*a+r*c)*v,t[8]=(o*a-r*e)*v,t):null},adjoint:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=n[6],h=n[7],s=n[8];return t[0]=o*s-i*h,t[1]=u*h-r*s,t[2]=r*i-u*o,t[3]=i*c-e*s,t[4]=a*s-u*c,t[5]=u*e-a*i,t[6]=e*h-o*c,t[7]=r*c-a*h,t[8]=a*o-r*e,t},determinant:function(t){var n=t[0],a=t[1],r=t[2],u=t[3],e=t[4],o=t[5],i=t[6],c=t[7],h=t[8];return n*(h*e-o*c)+a*(-h*u+o*i)+r*(c*u-e*i)},multiply:d,translate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=n[8],f=a[0],l=a[1];return t[0]=r,t[1]=u,t[2]=e,t[3]=o,t[4]=i,t[5]=c,t[6]=f*r+l*o+h,t[7]=f*u+l*i+s,t[8]=f*e+l*c+M,t},rotate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=n[8],f=Math.sin(a),l=Math.cos(a);return t[0]=l*r+f*o,t[1]=l*u+f*i,t[2]=l*e+f*c,t[3]=l*o-f*r,t[4]=l*i-f*u,t[5]=l*c-f*e,t[6]=h,t[7]=s,t[8]=M,t},scale:function(t,n,a){var r=a[0],u=a[1];return t[0]=r*n[0],t[1]=r*n[1],t[2]=r*n[2],t[3]=u*n[3],t[4]=u*n[4],t[5]=u*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},fromTranslation:function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},fromRotation:function(t,n){var a=Math.sin(n),r=Math.cos(n);return t[0]=r,t[1]=a,t[2]=0,t[3]=-a,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},fromScaling:function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},fromMat2d:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},fromQuat:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=a+a,i=r+r,c=u+u,h=a*o,s=r*o,M=r*i,f=u*o,l=u*i,v=u*c,b=e*o,m=e*i,d=e*c;return t[0]=1-M-v,t[3]=s-d,t[6]=f+m,t[1]=s+d,t[4]=1-h-v,t[7]=l-b,t[2]=f-m,t[5]=l+b,t[8]=1-h-M,t},normalFromMat4:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=n[6],h=n[7],s=n[8],M=n[9],f=n[10],l=n[11],v=n[12],b=n[13],m=n[14],d=n[15],x=a*i-r*o,p=a*c-u*o,y=a*h-e*o,q=r*c-u*i,g=r*h-e*i,A=u*h-e*c,w=s*b-M*v,R=s*m-f*v,z=s*d-l*v,P=M*m-f*b,j=M*d-l*b,I=f*d-l*m,S=x*I-p*j+y*P+q*z-g*R+A*w;return S?(S=1/S,t[0]=(i*I-c*j+h*P)*S,t[1]=(c*z-o*I-h*R)*S,t[2]=(o*j-i*z+h*w)*S,t[3]=(u*j-r*I-e*P)*S,t[4]=(a*I-u*z+e*R)*S,t[5]=(r*z-a*j-e*w)*S,t[6]=(b*A-m*g+d*q)*S,t[7]=(m*y-v*A-d*p)*S,t[8]=(v*g-b*y+d*x)*S,t):null},projection:function(t,n,a){return t[0]=2/n,t[1]=0,t[2]=0,t[3]=0,t[4]=-2/a,t[5]=0,t[6]=-1,t[7]=1,t[8]=1,t},str:function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},frob:function(t){return Math.hypot(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},add:function(t,n,a){return t[0]=n[0]+a[0],t[1]=n[1]+a[1],t[2]=n[2]+a[2],t[3]=n[3]+a[3],t[4]=n[4]+a[4],t[5]=n[5]+a[5],t[6]=n[6]+a[6],t[7]=n[7]+a[7],t[8]=n[8]+a[8],t},subtract:x,multiplyScalar:function(t,n,a){return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*a,t[5]=n[5]*a,t[6]=n[6]*a,t[7]=n[7]*a,t[8]=n[8]*a,t},multiplyScalarAndAdd:function(t,n,a,r){return t[0]=n[0]+a[0]*r,t[1]=n[1]+a[1]*r,t[2]=n[2]+a[2]*r,t[3]=n[3]+a[3]*r,t[4]=n[4]+a[4]*r,t[5]=n[5]+a[5]*r,t[6]=n[6]+a[6]*r,t[7]=n[7]+a[7]*r,t[8]=n[8]+a[8]*r,t},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]&&t[6]===n[6]&&t[7]===n[7]&&t[8]===n[8]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=t[4],c=t[5],h=t[6],s=t[7],M=t[8],f=a[0],l=a[1],v=a[2],b=a[3],m=a[4],d=a[5],x=a[6],p=a[7],y=a[8];return Math.abs(r-f)<=n*Math.max(1,Math.abs(r),Math.abs(f))&&Math.abs(u-l)<=n*Math.max(1,Math.abs(u),Math.abs(l))&&Math.abs(e-v)<=n*Math.max(1,Math.abs(e),Math.abs(v))&&Math.abs(o-b)<=n*Math.max(1,Math.abs(o),Math.abs(b))&&Math.abs(i-m)<=n*Math.max(1,Math.abs(i),Math.abs(m))&&Math.abs(c-d)<=n*Math.max(1,Math.abs(c),Math.abs(d))&&Math.abs(h-x)<=n*Math.max(1,Math.abs(h),Math.abs(x))&&Math.abs(s-p)<=n*Math.max(1,Math.abs(s),Math.abs(p))&&Math.abs(M-y)<=n*Math.max(1,Math.abs(M),Math.abs(y))},mul:p,sub:y});function g(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}function A(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=n[8],f=n[9],l=n[10],v=n[11],b=n[12],m=n[13],d=n[14],x=n[15],p=a[0],y=a[1],q=a[2],g=a[3];return t[0]=p*r+y*i+q*M+g*b,t[1]=p*u+y*c+q*f+g*m,t[2]=p*e+y*h+q*l+g*d,t[3]=p*o+y*s+q*v+g*x,p=a[4],y=a[5],q=a[6],g=a[7],t[4]=p*r+y*i+q*M+g*b,t[5]=p*u+y*c+q*f+g*m,t[6]=p*e+y*h+q*l+g*d,t[7]=p*o+y*s+q*v+g*x,p=a[8],y=a[9],q=a[10],g=a[11],t[8]=p*r+y*i+q*M+g*b,t[9]=p*u+y*c+q*f+g*m,t[10]=p*e+y*h+q*l+g*d,t[11]=p*o+y*s+q*v+g*x,p=a[12],y=a[13],q=a[14],g=a[15],t[12]=p*r+y*i+q*M+g*b,t[13]=p*u+y*c+q*f+g*m,t[14]=p*e+y*h+q*l+g*d,t[15]=p*o+y*s+q*v+g*x,t}function w(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=r+r,c=u+u,h=e+e,s=r*i,M=r*c,f=r*h,l=u*c,v=u*h,b=e*h,m=o*i,d=o*c,x=o*h;return t[0]=1-(l+b),t[1]=M+x,t[2]=f-d,t[3]=0,t[4]=M-x,t[5]=1-(s+b),t[6]=v+m,t[7]=0,t[8]=f+d,t[9]=v-m,t[10]=1-(s+l),t[11]=0,t[12]=a[0],t[13]=a[1],t[14]=a[2],t[15]=1,t}function R(t,n){return t[0]=n[12],t[1]=n[13],t[2]=n[14],t}function z(t,n){var a=n[0],r=n[1],u=n[2],e=n[4],o=n[5],i=n[6],c=n[8],h=n[9],s=n[10];return t[0]=Math.hypot(a,r,u),t[1]=Math.hypot(e,o,i),t[2]=Math.hypot(c,h,s),t}function P(t,n){var r=new a(3);z(r,n);var u=1/r[0],e=1/r[1],o=1/r[2],i=n[0]*u,c=n[1]*e,h=n[2]*o,s=n[4]*u,M=n[5]*e,f=n[6]*o,l=n[8]*u,v=n[9]*e,b=n[10]*o,m=i+M+b,d=0;return m>0?(d=2*Math.sqrt(m+1),t[3]=.25*d,t[0]=(f-v)/d,t[1]=(l-h)/d,t[2]=(c-s)/d):i>M&&i>b?(d=2*Math.sqrt(1+i-M-b),t[3]=(f-v)/d,t[0]=.25*d,t[1]=(c+s)/d,t[2]=(l+h)/d):M>b?(d=2*Math.sqrt(1+M-i-b),t[3]=(l-h)/d,t[0]=(c+s)/d,t[1]=.25*d,t[2]=(f+v)/d):(d=2*Math.sqrt(1+b-i-M),t[3]=(c-s)/d,t[0]=(l+h)/d,t[1]=(f+v)/d,t[2]=.25*d),t}function j(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t[3]=n[3]-a[3],t[4]=n[4]-a[4],t[5]=n[5]-a[5],t[6]=n[6]-a[6],t[7]=n[7]-a[7],t[8]=n[8]-a[8],t[9]=n[9]-a[9],t[10]=n[10]-a[10],t[11]=n[11]-a[11],t[12]=n[12]-a[12],t[13]=n[13]-a[13],t[14]=n[14]-a[14],t[15]=n[15]-a[15],t}var I=A,S=j,E=Object.freeze({create:function(){var t=new a(16);return a!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0),t[0]=1,t[5]=1,t[10]=1,t[15]=1,t},clone:function(t){var n=new a(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},copy:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},fromValues:function(t,n,r,u,e,o,i,c,h,s,M,f,l,v,b,m){var d=new a(16);return d[0]=t,d[1]=n,d[2]=r,d[3]=u,d[4]=e,d[5]=o,d[6]=i,d[7]=c,d[8]=h,d[9]=s,d[10]=M,d[11]=f,d[12]=l,d[13]=v,d[14]=b,d[15]=m,d},set:function(t,n,a,r,u,e,o,i,c,h,s,M,f,l,v,b,m){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t[4]=e,t[5]=o,t[6]=i,t[7]=c,t[8]=h,t[9]=s,t[10]=M,t[11]=f,t[12]=l,t[13]=v,t[14]=b,t[15]=m,t},identity:g,transpose:function(t,n){if(t===n){var a=n[1],r=n[2],u=n[3],e=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=a,t[6]=n[9],t[7]=n[13],t[8]=r,t[9]=e,t[11]=n[14],t[12]=u,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},invert:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=n[6],h=n[7],s=n[8],M=n[9],f=n[10],l=n[11],v=n[12],b=n[13],m=n[14],d=n[15],x=a*i-r*o,p=a*c-u*o,y=a*h-e*o,q=r*c-u*i,g=r*h-e*i,A=u*h-e*c,w=s*b-M*v,R=s*m-f*v,z=s*d-l*v,P=M*m-f*b,j=M*d-l*b,I=f*d-l*m,S=x*I-p*j+y*P+q*z-g*R+A*w;return S?(S=1/S,t[0]=(i*I-c*j+h*P)*S,t[1]=(u*j-r*I-e*P)*S,t[2]=(b*A-m*g+d*q)*S,t[3]=(f*g-M*A-l*q)*S,t[4]=(c*z-o*I-h*R)*S,t[5]=(a*I-u*z+e*R)*S,t[6]=(m*y-v*A-d*p)*S,t[7]=(s*A-f*y+l*p)*S,t[8]=(o*j-i*z+h*w)*S,t[9]=(r*z-a*j-e*w)*S,t[10]=(v*g-b*y+d*x)*S,t[11]=(M*y-s*g-l*x)*S,t[12]=(i*R-o*P-c*w)*S,t[13]=(a*P-r*R+u*w)*S,t[14]=(b*p-v*q-m*x)*S,t[15]=(s*q-M*p+f*x)*S,t):null},adjoint:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=n[6],h=n[7],s=n[8],M=n[9],f=n[10],l=n[11],v=n[12],b=n[13],m=n[14],d=n[15];return t[0]=i*(f*d-l*m)-M*(c*d-h*m)+b*(c*l-h*f),t[1]=-(r*(f*d-l*m)-M*(u*d-e*m)+b*(u*l-e*f)),t[2]=r*(c*d-h*m)-i*(u*d-e*m)+b*(u*h-e*c),t[3]=-(r*(c*l-h*f)-i*(u*l-e*f)+M*(u*h-e*c)),t[4]=-(o*(f*d-l*m)-s*(c*d-h*m)+v*(c*l-h*f)),t[5]=a*(f*d-l*m)-s*(u*d-e*m)+v*(u*l-e*f),t[6]=-(a*(c*d-h*m)-o*(u*d-e*m)+v*(u*h-e*c)),t[7]=a*(c*l-h*f)-o*(u*l-e*f)+s*(u*h-e*c),t[8]=o*(M*d-l*b)-s*(i*d-h*b)+v*(i*l-h*M),t[9]=-(a*(M*d-l*b)-s*(r*d-e*b)+v*(r*l-e*M)),t[10]=a*(i*d-h*b)-o*(r*d-e*b)+v*(r*h-e*i),t[11]=-(a*(i*l-h*M)-o*(r*l-e*M)+s*(r*h-e*i)),t[12]=-(o*(M*m-f*b)-s*(i*m-c*b)+v*(i*f-c*M)),t[13]=a*(M*m-f*b)-s*(r*m-u*b)+v*(r*f-u*M),t[14]=-(a*(i*m-c*b)-o*(r*m-u*b)+v*(r*c-u*i)),t[15]=a*(i*f-c*M)-o*(r*f-u*M)+s*(r*c-u*i),t},determinant:function(t){var n=t[0],a=t[1],r=t[2],u=t[3],e=t[4],o=t[5],i=t[6],c=t[7],h=t[8],s=t[9],M=t[10],f=t[11],l=t[12],v=t[13],b=t[14],m=t[15];return(n*o-a*e)*(M*m-f*b)-(n*i-r*e)*(s*m-f*v)+(n*c-u*e)*(s*b-M*v)+(a*i-r*o)*(h*m-f*l)-(a*c-u*o)*(h*b-M*l)+(r*c-u*i)*(h*v-s*l)},multiply:A,translate:function(t,n,a){var r,u,e,o,i,c,h,s,M,f,l,v,b=a[0],m=a[1],d=a[2];return n===t?(t[12]=n[0]*b+n[4]*m+n[8]*d+n[12],t[13]=n[1]*b+n[5]*m+n[9]*d+n[13],t[14]=n[2]*b+n[6]*m+n[10]*d+n[14],t[15]=n[3]*b+n[7]*m+n[11]*d+n[15]):(r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=n[8],f=n[9],l=n[10],v=n[11],t[0]=r,t[1]=u,t[2]=e,t[3]=o,t[4]=i,t[5]=c,t[6]=h,t[7]=s,t[8]=M,t[9]=f,t[10]=l,t[11]=v,t[12]=r*b+i*m+M*d+n[12],t[13]=u*b+c*m+f*d+n[13],t[14]=e*b+h*m+l*d+n[14],t[15]=o*b+s*m+v*d+n[15]),t},scale:function(t,n,a){var r=a[0],u=a[1],e=a[2];return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t[4]=n[4]*u,t[5]=n[5]*u,t[6]=n[6]*u,t[7]=n[7]*u,t[8]=n[8]*e,t[9]=n[9]*e,t[10]=n[10]*e,t[11]=n[11]*e,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},rotate:function(t,a,r,u){var e,o,i,c,h,s,M,f,l,v,b,m,d,x,p,y,q,g,A,w,R,z,P,j,I=u[0],S=u[1],E=u[2],O=Math.hypot(I,S,E);return O0?(r[0]=2*(c*i+M*u+h*o-s*e)/f,r[1]=2*(h*i+M*e+s*u-c*o)/f,r[2]=2*(s*i+M*o+c*e-h*u)/f):(r[0]=2*(c*i+M*u+h*o-s*e),r[1]=2*(h*i+M*e+s*u-c*o),r[2]=2*(s*i+M*o+c*e-h*u)),w(t,n,r),t},getTranslation:R,getScaling:z,getRotation:P,fromRotationTranslationScale:function(t,n,a,r){var u=n[0],e=n[1],o=n[2],i=n[3],c=u+u,h=e+e,s=o+o,M=u*c,f=u*h,l=u*s,v=e*h,b=e*s,m=o*s,d=i*c,x=i*h,p=i*s,y=r[0],q=r[1],g=r[2];return t[0]=(1-(v+m))*y,t[1]=(f+p)*y,t[2]=(l-x)*y,t[3]=0,t[4]=(f-p)*q,t[5]=(1-(M+m))*q,t[6]=(b+d)*q,t[7]=0,t[8]=(l+x)*g,t[9]=(b-d)*g,t[10]=(1-(M+v))*g,t[11]=0,t[12]=a[0],t[13]=a[1],t[14]=a[2],t[15]=1,t},fromRotationTranslationScaleOrigin:function(t,n,a,r,u){var e=n[0],o=n[1],i=n[2],c=n[3],h=e+e,s=o+o,M=i+i,f=e*h,l=e*s,v=e*M,b=o*s,m=o*M,d=i*M,x=c*h,p=c*s,y=c*M,q=r[0],g=r[1],A=r[2],w=u[0],R=u[1],z=u[2],P=(1-(b+d))*q,j=(l+y)*q,I=(v-p)*q,S=(l-y)*g,E=(1-(f+d))*g,O=(m+x)*g,T=(v+p)*A,D=(m-x)*A,F=(1-(f+b))*A;return t[0]=P,t[1]=j,t[2]=I,t[3]=0,t[4]=S,t[5]=E,t[6]=O,t[7]=0,t[8]=T,t[9]=D,t[10]=F,t[11]=0,t[12]=a[0]+w-(P*w+S*R+T*z),t[13]=a[1]+R-(j*w+E*R+D*z),t[14]=a[2]+z-(I*w+O*R+F*z),t[15]=1,t},fromQuat:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=a+a,i=r+r,c=u+u,h=a*o,s=r*o,M=r*i,f=u*o,l=u*i,v=u*c,b=e*o,m=e*i,d=e*c;return t[0]=1-M-v,t[1]=s+d,t[2]=f-m,t[3]=0,t[4]=s-d,t[5]=1-h-v,t[6]=l+b,t[7]=0,t[8]=f+m,t[9]=l-b,t[10]=1-h-M,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},frustum:function(t,n,a,r,u,e,o){var i=1/(a-n),c=1/(u-r),h=1/(e-o);return t[0]=2*e*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*e*c,t[6]=0,t[7]=0,t[8]=(a+n)*i,t[9]=(u+r)*c,t[10]=(o+e)*h,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*e*2*h,t[15]=0,t},perspective:function(t,n,a,r,u){var e,o=1/Math.tan(n/2);return t[0]=o/a,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=o,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=-1,t[12]=0,t[13]=0,t[15]=0,null!=u&&u!==1/0?(e=1/(r-u),t[10]=(u+r)*e,t[14]=2*u*r*e):(t[10]=-1,t[14]=-2*r),t},perspectiveFromFieldOfView:function(t,n,a,r){var u=Math.tan(n.upDegrees*Math.PI/180),e=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),h=2/(u+e);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=h,t[6]=0,t[7]=0,t[8]=-(o-i)*c*.5,t[9]=(u-e)*h*.5,t[10]=r/(a-r),t[11]=-1,t[12]=0,t[13]=0,t[14]=r*a/(a-r),t[15]=0,t},ortho:function(t,n,a,r,u,e,o){var i=1/(n-a),c=1/(r-u),h=1/(e-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*h,t[11]=0,t[12]=(n+a)*i,t[13]=(u+r)*c,t[14]=(o+e)*h,t[15]=1,t},lookAt:function(t,a,r,u){var e,o,i,c,h,s,M,f,l,v,b=a[0],m=a[1],d=a[2],x=u[0],p=u[1],y=u[2],q=r[0],A=r[1],w=r[2];return Math.abs(b-q)0&&(s*=l=1/Math.sqrt(l),M*=l,f*=l);var v=c*f-h*M,b=h*s-i*f,m=i*M-c*s;return(l=v*v+b*b+m*m)>0&&(v*=l=1/Math.sqrt(l),b*=l,m*=l),t[0]=v,t[1]=b,t[2]=m,t[3]=0,t[4]=M*m-f*b,t[5]=f*v-s*m,t[6]=s*b-M*v,t[7]=0,t[8]=s,t[9]=M,t[10]=f,t[11]=0,t[12]=u,t[13]=e,t[14]=o,t[15]=1,t},str:function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},frob:function(t){return Math.hypot(t[0],t[1],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},add:function(t,n,a){return t[0]=n[0]+a[0],t[1]=n[1]+a[1],t[2]=n[2]+a[2],t[3]=n[3]+a[3],t[4]=n[4]+a[4],t[5]=n[5]+a[5],t[6]=n[6]+a[6],t[7]=n[7]+a[7],t[8]=n[8]+a[8],t[9]=n[9]+a[9],t[10]=n[10]+a[10],t[11]=n[11]+a[11],t[12]=n[12]+a[12],t[13]=n[13]+a[13],t[14]=n[14]+a[14],t[15]=n[15]+a[15],t},subtract:j,multiplyScalar:function(t,n,a){return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*a,t[5]=n[5]*a,t[6]=n[6]*a,t[7]=n[7]*a,t[8]=n[8]*a,t[9]=n[9]*a,t[10]=n[10]*a,t[11]=n[11]*a,t[12]=n[12]*a,t[13]=n[13]*a,t[14]=n[14]*a,t[15]=n[15]*a,t},multiplyScalarAndAdd:function(t,n,a,r){return t[0]=n[0]+a[0]*r,t[1]=n[1]+a[1]*r,t[2]=n[2]+a[2]*r,t[3]=n[3]+a[3]*r,t[4]=n[4]+a[4]*r,t[5]=n[5]+a[5]*r,t[6]=n[6]+a[6]*r,t[7]=n[7]+a[7]*r,t[8]=n[8]+a[8]*r,t[9]=n[9]+a[9]*r,t[10]=n[10]+a[10]*r,t[11]=n[11]+a[11]*r,t[12]=n[12]+a[12]*r,t[13]=n[13]+a[13]*r,t[14]=n[14]+a[14]*r,t[15]=n[15]+a[15]*r,t},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]&&t[6]===n[6]&&t[7]===n[7]&&t[8]===n[8]&&t[9]===n[9]&&t[10]===n[10]&&t[11]===n[11]&&t[12]===n[12]&&t[13]===n[13]&&t[14]===n[14]&&t[15]===n[15]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=t[4],c=t[5],h=t[6],s=t[7],M=t[8],f=t[9],l=t[10],v=t[11],b=t[12],m=t[13],d=t[14],x=t[15],p=a[0],y=a[1],q=a[2],g=a[3],A=a[4],w=a[5],R=a[6],z=a[7],P=a[8],j=a[9],I=a[10],S=a[11],E=a[12],O=a[13],T=a[14],D=a[15];return Math.abs(r-p)<=n*Math.max(1,Math.abs(r),Math.abs(p))&&Math.abs(u-y)<=n*Math.max(1,Math.abs(u),Math.abs(y))&&Math.abs(e-q)<=n*Math.max(1,Math.abs(e),Math.abs(q))&&Math.abs(o-g)<=n*Math.max(1,Math.abs(o),Math.abs(g))&&Math.abs(i-A)<=n*Math.max(1,Math.abs(i),Math.abs(A))&&Math.abs(c-w)<=n*Math.max(1,Math.abs(c),Math.abs(w))&&Math.abs(h-R)<=n*Math.max(1,Math.abs(h),Math.abs(R))&&Math.abs(s-z)<=n*Math.max(1,Math.abs(s),Math.abs(z))&&Math.abs(M-P)<=n*Math.max(1,Math.abs(M),Math.abs(P))&&Math.abs(f-j)<=n*Math.max(1,Math.abs(f),Math.abs(j))&&Math.abs(l-I)<=n*Math.max(1,Math.abs(l),Math.abs(I))&&Math.abs(v-S)<=n*Math.max(1,Math.abs(v),Math.abs(S))&&Math.abs(b-E)<=n*Math.max(1,Math.abs(b),Math.abs(E))&&Math.abs(m-O)<=n*Math.max(1,Math.abs(m),Math.abs(O))&&Math.abs(d-T)<=n*Math.max(1,Math.abs(d),Math.abs(T))&&Math.abs(x-D)<=n*Math.max(1,Math.abs(x),Math.abs(D))},mul:I,sub:S});function O(){var t=new a(3);return a!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}function T(t){var n=t[0],a=t[1],r=t[2];return Math.hypot(n,a,r)}function D(t,n,r){var u=new a(3);return u[0]=t,u[1]=n,u[2]=r,u}function F(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t}function L(t,n,a){return t[0]=n[0]*a[0],t[1]=n[1]*a[1],t[2]=n[2]*a[2],t}function V(t,n,a){return t[0]=n[0]/a[0],t[1]=n[1]/a[1],t[2]=n[2]/a[2],t}function Q(t,n){var a=n[0]-t[0],r=n[1]-t[1],u=n[2]-t[2];return Math.hypot(a,r,u)}function Y(t,n){var a=n[0]-t[0],r=n[1]-t[1],u=n[2]-t[2];return a*a+r*r+u*u}function X(t){var n=t[0],a=t[1],r=t[2];return n*n+a*a+r*r}function Z(t,n){var a=n[0],r=n[1],u=n[2],e=a*a+r*r+u*u;return e>0&&(e=1/Math.sqrt(e)),t[0]=n[0]*e,t[1]=n[1]*e,t[2]=n[2]*e,t}function _(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]}function B(t,n,a){var r=n[0],u=n[1],e=n[2],o=a[0],i=a[1],c=a[2];return t[0]=u*c-e*i,t[1]=e*o-r*c,t[2]=r*i-u*o,t}var N,k=F,U=L,W=V,C=Q,G=Y,H=T,J=X,K=(N=O(),function(t,n,a,r,u,e){var o,i;for(n||(n=3),a||(a=0),i=r?Math.min(r*n+a,t.length):t.length,o=a;o1?0:u<-1?Math.PI:Math.acos(u)},zero:function(t){return t[0]=0,t[1]=0,t[2]=0,t},str:function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=a[0],i=a[1],c=a[2];return Math.abs(r-o)<=n*Math.max(1,Math.abs(r),Math.abs(o))&&Math.abs(u-i)<=n*Math.max(1,Math.abs(u),Math.abs(i))&&Math.abs(e-c)<=n*Math.max(1,Math.abs(e),Math.abs(c))},sub:k,mul:U,div:W,dist:C,sqrDist:G,len:H,sqrLen:J,forEach:K});function tt(){var t=new a(4);return a!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0,t[3]=0),t}function nt(t){var n=new a(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n}function at(t,n,r,u){var e=new a(4);return e[0]=t,e[1]=n,e[2]=r,e[3]=u,e}function rt(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t}function ut(t,n,a,r,u){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t}function et(t,n,a){return t[0]=n[0]+a[0],t[1]=n[1]+a[1],t[2]=n[2]+a[2],t[3]=n[3]+a[3],t}function ot(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t[3]=n[3]-a[3],t}function it(t,n,a){return t[0]=n[0]*a[0],t[1]=n[1]*a[1],t[2]=n[2]*a[2],t[3]=n[3]*a[3],t}function ct(t,n,a){return t[0]=n[0]/a[0],t[1]=n[1]/a[1],t[2]=n[2]/a[2],t[3]=n[3]/a[3],t}function ht(t,n,a){return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t}function st(t,n){var a=n[0]-t[0],r=n[1]-t[1],u=n[2]-t[2],e=n[3]-t[3];return Math.hypot(a,r,u,e)}function Mt(t,n){var a=n[0]-t[0],r=n[1]-t[1],u=n[2]-t[2],e=n[3]-t[3];return a*a+r*r+u*u+e*e}function ft(t){var n=t[0],a=t[1],r=t[2],u=t[3];return Math.hypot(n,a,r,u)}function lt(t){var n=t[0],a=t[1],r=t[2],u=t[3];return n*n+a*a+r*r+u*u}function vt(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=a*a+r*r+u*u+e*e;return o>0&&(o=1/Math.sqrt(o)),t[0]=a*o,t[1]=r*o,t[2]=u*o,t[3]=e*o,t}function bt(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]}function mt(t,n,a,r){var u=n[0],e=n[1],o=n[2],i=n[3];return t[0]=u+r*(a[0]-u),t[1]=e+r*(a[1]-e),t[2]=o+r*(a[2]-o),t[3]=i+r*(a[3]-i),t}function dt(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]}function xt(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=a[0],c=a[1],h=a[2],s=a[3];return Math.abs(r-i)<=n*Math.max(1,Math.abs(r),Math.abs(i))&&Math.abs(u-c)<=n*Math.max(1,Math.abs(u),Math.abs(c))&&Math.abs(e-h)<=n*Math.max(1,Math.abs(e),Math.abs(h))&&Math.abs(o-s)<=n*Math.max(1,Math.abs(o),Math.abs(s))}var pt=ot,yt=it,qt=ct,gt=st,At=Mt,wt=ft,Rt=lt,zt=function(){var t=tt();return function(n,a,r,u,e,o){var i,c;for(a||(a=4),r||(r=0),c=u?Math.min(u*a+r,n.length):n.length,i=r;i=1);do{c=(e=2*r()-1)*e+(o=2*r()-1)*o}while(c>=1);var h=Math.sqrt((1-i)/c);return t[0]=n*a,t[1]=n*u,t[2]=n*e*h,t[3]=n*o*h,t},transformMat4:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3];return t[0]=a[0]*r+a[4]*u+a[8]*e+a[12]*o,t[1]=a[1]*r+a[5]*u+a[9]*e+a[13]*o,t[2]=a[2]*r+a[6]*u+a[10]*e+a[14]*o,t[3]=a[3]*r+a[7]*u+a[11]*e+a[15]*o,t},transformQuat:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=a[0],i=a[1],c=a[2],h=a[3],s=h*r+i*e-c*u,M=h*u+c*r-o*e,f=h*e+o*u-i*r,l=-o*r-i*u-c*e;return t[0]=s*h+l*-o+M*-c-f*-i,t[1]=M*h+l*-i+f*-o-s*-c,t[2]=f*h+l*-c+s*-i-M*-o,t[3]=n[3],t},zero:function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},str:function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},exactEquals:dt,equals:xt,sub:pt,mul:yt,div:qt,dist:gt,sqrDist:At,len:wt,sqrLen:Rt,forEach:zt});function jt(){var t=new a(4);return a!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t[3]=1,t}function It(t,n,a){a*=.5;var r=Math.sin(a);return t[0]=r*n[0],t[1]=r*n[1],t[2]=r*n[2],t[3]=Math.cos(a),t}function St(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=a[0],c=a[1],h=a[2],s=a[3];return t[0]=r*s+o*i+u*h-e*c,t[1]=u*s+o*c+e*i-r*h,t[2]=e*s+o*h+r*c-u*i,t[3]=o*s-r*i-u*c-e*h,t}function Et(t,n,a){a*=.5;var r=n[0],u=n[1],e=n[2],o=n[3],i=Math.sin(a),c=Math.cos(a);return t[0]=r*c+o*i,t[1]=u*c+e*i,t[2]=e*c-u*i,t[3]=o*c-r*i,t}function Ot(t,n,a){a*=.5;var r=n[0],u=n[1],e=n[2],o=n[3],i=Math.sin(a),c=Math.cos(a);return t[0]=r*c-e*i,t[1]=u*c+o*i,t[2]=e*c+r*i,t[3]=o*c-u*i,t}function Tt(t,n,a){a*=.5;var r=n[0],u=n[1],e=n[2],o=n[3],i=Math.sin(a),c=Math.cos(a);return t[0]=r*c+u*i,t[1]=u*c-r*i,t[2]=e*c+o*i,t[3]=o*c-e*i,t}function Dt(t,a,r,u){var e,o,i,c,h,s=a[0],M=a[1],f=a[2],l=a[3],v=r[0],b=r[1],m=r[2],d=r[3];return(o=s*v+M*b+f*m+l*d)<0&&(o=-o,v=-v,b=-b,m=-m,d=-d),1-o>n?(e=Math.acos(o),i=Math.sin(e),c=Math.sin((1-u)*e)/i,h=Math.sin(u*e)/i):(c=1-u,h=u),t[0]=c*s+h*v,t[1]=c*M+h*b,t[2]=c*f+h*m,t[3]=c*l+h*d,t}function Ft(t,n){var a,r=n[0]+n[4]+n[8];if(r>0)a=Math.sqrt(r+1),t[3]=.5*a,a=.5/a,t[0]=(n[5]-n[7])*a,t[1]=(n[6]-n[2])*a,t[2]=(n[1]-n[3])*a;else{var u=0;n[4]>n[0]&&(u=1),n[8]>n[3*u+u]&&(u=2);var e=(u+1)%3,o=(u+2)%3;a=Math.sqrt(n[3*u+u]-n[3*e+e]-n[3*o+o]+1),t[u]=.5*a,a=.5/a,t[3]=(n[3*e+o]-n[3*o+e])*a,t[e]=(n[3*e+u]+n[3*u+e])*a,t[o]=(n[3*o+u]+n[3*u+o])*a}return t}var Lt,Vt,Qt,Yt,Xt,Zt,_t=nt,Bt=at,Nt=rt,kt=ut,Ut=et,Wt=St,Ct=ht,Gt=bt,Ht=mt,Jt=ft,Kt=Jt,$t=lt,tn=$t,nn=vt,an=dt,rn=xt,un=(Lt=O(),Vt=D(1,0,0),Qt=D(0,1,0),function(t,n,a){var r=_(n,a);return r<-.999999?(B(Lt,Vt,n),H(Lt)<1e-6&&B(Lt,Qt,n),Z(Lt,Lt),It(t,Lt,Math.PI),t):r>.999999?(t[0]=0,t[1]=0,t[2]=0,t[3]=1,t):(B(Lt,n,a),t[0]=Lt[0],t[1]=Lt[1],t[2]=Lt[2],t[3]=1+r,nn(t,t))}),en=(Yt=jt(),Xt=jt(),function(t,n,a,r,u,e){return Dt(Yt,n,u,e),Dt(Xt,a,r,e),Dt(t,Yt,Xt,2*e*(1-e)),t}),on=(Zt=m(),function(t,n,a,r){return Zt[0]=a[0],Zt[3]=a[1],Zt[6]=a[2],Zt[1]=r[0],Zt[4]=r[1],Zt[7]=r[2],Zt[2]=-n[0],Zt[5]=-n[1],Zt[8]=-n[2],nn(t,Ft(t,Zt))}),cn=Object.freeze({create:jt,identity:function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},setAxisAngle:It,getAxisAngle:function(t,a){var r=2*Math.acos(a[3]),u=Math.sin(r/2);return u>n?(t[0]=a[0]/u,t[1]=a[1]/u,t[2]=a[2]/u):(t[0]=1,t[1]=0,t[2]=0),r},multiply:St,rotateX:Et,rotateY:Ot,rotateZ:Tt,calculateW:function(t,n){var a=n[0],r=n[1],u=n[2];return t[0]=a,t[1]=r,t[2]=u,t[3]=Math.sqrt(Math.abs(1-a*a-r*r-u*u)),t},slerp:Dt,random:function(t){var n=r(),a=r(),u=r(),e=Math.sqrt(1-n),o=Math.sqrt(n);return t[0]=e*Math.sin(2*Math.PI*a),t[1]=e*Math.cos(2*Math.PI*a),t[2]=o*Math.sin(2*Math.PI*u),t[3]=o*Math.cos(2*Math.PI*u),t},invert:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=a*a+r*r+u*u+e*e,i=o?1/o:0;return t[0]=-a*i,t[1]=-r*i,t[2]=-u*i,t[3]=e*i,t},conjugate:function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},fromMat3:Ft,fromEuler:function(t,n,a,r){var u=.5*Math.PI/180;n*=u,a*=u,r*=u;var e=Math.sin(n),o=Math.cos(n),i=Math.sin(a),c=Math.cos(a),h=Math.sin(r),s=Math.cos(r);return t[0]=e*c*s-o*i*h,t[1]=o*i*s+e*c*h,t[2]=o*c*h-e*i*s,t[3]=o*c*s+e*i*h,t},str:function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},clone:_t,fromValues:Bt,copy:Nt,set:kt,add:Ut,mul:Wt,scale:Ct,dot:Gt,lerp:Ht,length:Jt,len:Kt,squaredLength:$t,sqrLen:tn,normalize:nn,exactEquals:an,equals:rn,rotationTo:un,sqlerp:en,setAxes:on});function hn(t,n,a){var r=.5*a[0],u=.5*a[1],e=.5*a[2],o=n[0],i=n[1],c=n[2],h=n[3];return t[0]=o,t[1]=i,t[2]=c,t[3]=h,t[4]=r*h+u*c-e*i,t[5]=u*h+e*o-r*c,t[6]=e*h+r*i-u*o,t[7]=-r*o-u*i-e*c,t}function sn(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t}var Mn=Nt;var fn=Nt;function ln(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=a[4],c=a[5],h=a[6],s=a[7],M=n[4],f=n[5],l=n[6],v=n[7],b=a[0],m=a[1],d=a[2],x=a[3];return t[0]=r*x+o*b+u*d-e*m,t[1]=u*x+o*m+e*b-r*d,t[2]=e*x+o*d+r*m-u*b,t[3]=o*x-r*b-u*m-e*d,t[4]=r*s+o*i+u*h-e*c+M*x+v*b+f*d-l*m,t[5]=u*s+o*c+e*i-r*h+f*x+v*m+l*b-M*d,t[6]=e*s+o*h+r*c-u*i+l*x+v*d+M*m-f*b,t[7]=o*s-r*i-u*c-e*h+v*x-M*b-f*m-l*d,t}var vn=ln;var bn=Gt;var mn=Jt,dn=mn,xn=$t,pn=xn;var yn=Object.freeze({create:function(){var t=new a(8);return a!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0,t[4]=0,t[5]=0,t[6]=0,t[7]=0),t[3]=1,t},clone:function(t){var n=new a(8);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n},fromValues:function(t,n,r,u,e,o,i,c){var h=new a(8);return h[0]=t,h[1]=n,h[2]=r,h[3]=u,h[4]=e,h[5]=o,h[6]=i,h[7]=c,h},fromRotationTranslationValues:function(t,n,r,u,e,o,i){var c=new a(8);c[0]=t,c[1]=n,c[2]=r,c[3]=u;var h=.5*e,s=.5*o,M=.5*i;return c[4]=h*u+s*r-M*n,c[5]=s*u+M*t-h*r,c[6]=M*u+h*n-s*t,c[7]=-h*t-s*n-M*r,c},fromRotationTranslation:hn,fromTranslation:function(t,n){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t[4]=.5*n[0],t[5]=.5*n[1],t[6]=.5*n[2],t[7]=0,t},fromRotation:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=0,t[5]=0,t[6]=0,t[7]=0,t},fromMat4:function(t,n){var r=jt();P(r,n);var u=new a(3);return R(u,n),hn(t,r,u),t},copy:sn,identity:function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t[6]=0,t[7]=0,t},set:function(t,n,a,r,u,e,o,i,c){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t[4]=e,t[5]=o,t[6]=i,t[7]=c,t},getReal:Mn,getDual:function(t,n){return t[0]=n[4],t[1]=n[5],t[2]=n[6],t[3]=n[7],t},setReal:fn,setDual:function(t,n){return t[4]=n[0],t[5]=n[1],t[6]=n[2],t[7]=n[3],t},getTranslation:function(t,n){var a=n[4],r=n[5],u=n[6],e=n[7],o=-n[0],i=-n[1],c=-n[2],h=n[3];return t[0]=2*(a*h+e*o+r*c-u*i),t[1]=2*(r*h+e*i+u*o-a*c),t[2]=2*(u*h+e*c+a*i-r*o),t},translate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=.5*a[0],c=.5*a[1],h=.5*a[2],s=n[4],M=n[5],f=n[6],l=n[7];return t[0]=r,t[1]=u,t[2]=e,t[3]=o,t[4]=o*i+u*h-e*c+s,t[5]=o*c+e*i-r*h+M,t[6]=o*h+r*c-u*i+f,t[7]=-r*i-u*c-e*h+l,t},rotateX:function(t,n,a){var r=-n[0],u=-n[1],e=-n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=i*o+s*r+c*e-h*u,f=c*o+s*u+h*r-i*e,l=h*o+s*e+i*u-c*r,v=s*o-i*r-c*u-h*e;return Et(t,n,a),r=t[0],u=t[1],e=t[2],o=t[3],t[4]=M*o+v*r+f*e-l*u,t[5]=f*o+v*u+l*r-M*e,t[6]=l*o+v*e+M*u-f*r,t[7]=v*o-M*r-f*u-l*e,t},rotateY:function(t,n,a){var r=-n[0],u=-n[1],e=-n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=i*o+s*r+c*e-h*u,f=c*o+s*u+h*r-i*e,l=h*o+s*e+i*u-c*r,v=s*o-i*r-c*u-h*e;return Ot(t,n,a),r=t[0],u=t[1],e=t[2],o=t[3],t[4]=M*o+v*r+f*e-l*u,t[5]=f*o+v*u+l*r-M*e,t[6]=l*o+v*e+M*u-f*r,t[7]=v*o-M*r-f*u-l*e,t},rotateZ:function(t,n,a){var r=-n[0],u=-n[1],e=-n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=i*o+s*r+c*e-h*u,f=c*o+s*u+h*r-i*e,l=h*o+s*e+i*u-c*r,v=s*o-i*r-c*u-h*e;return Tt(t,n,a),r=t[0],u=t[1],e=t[2],o=t[3],t[4]=M*o+v*r+f*e-l*u,t[5]=f*o+v*u+l*r-M*e,t[6]=l*o+v*e+M*u-f*r,t[7]=v*o-M*r-f*u-l*e,t},rotateByQuatAppend:function(t,n,a){var r=a[0],u=a[1],e=a[2],o=a[3],i=n[0],c=n[1],h=n[2],s=n[3];return t[0]=i*o+s*r+c*e-h*u,t[1]=c*o+s*u+h*r-i*e,t[2]=h*o+s*e+i*u-c*r,t[3]=s*o-i*r-c*u-h*e,i=n[4],c=n[5],h=n[6],s=n[7],t[4]=i*o+s*r+c*e-h*u,t[5]=c*o+s*u+h*r-i*e,t[6]=h*o+s*e+i*u-c*r,t[7]=s*o-i*r-c*u-h*e,t},rotateByQuatPrepend:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=a[0],c=a[1],h=a[2],s=a[3];return t[0]=r*s+o*i+u*h-e*c,t[1]=u*s+o*c+e*i-r*h,t[2]=e*s+o*h+r*c-u*i,t[3]=o*s-r*i-u*c-e*h,i=a[4],c=a[5],h=a[6],s=a[7],t[4]=r*s+o*i+u*h-e*c,t[5]=u*s+o*c+e*i-r*h,t[6]=e*s+o*h+r*c-u*i,t[7]=o*s-r*i-u*c-e*h,t},rotateAroundAxis:function(t,a,r,u){if(Math.abs(u)0){a=Math.sqrt(a);var r=n[0]/a,u=n[1]/a,e=n[2]/a,o=n[3]/a,i=n[4],c=n[5],h=n[6],s=n[7],M=r*i+u*c+e*h+o*s;t[0]=r,t[1]=u,t[2]=e,t[3]=o,t[4]=(i-r*M)/a,t[5]=(c-u*M)/a,t[6]=(h-e*M)/a,t[7]=(s-o*M)/a}return t},str:function(t){return"quat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+")"},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]&&t[6]===n[6]&&t[7]===n[7]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=t[4],c=t[5],h=t[6],s=t[7],M=a[0],f=a[1],l=a[2],v=a[3],b=a[4],m=a[5],d=a[6],x=a[7];return Math.abs(r-M)<=n*Math.max(1,Math.abs(r),Math.abs(M))&&Math.abs(u-f)<=n*Math.max(1,Math.abs(u),Math.abs(f))&&Math.abs(e-l)<=n*Math.max(1,Math.abs(e),Math.abs(l))&&Math.abs(o-v)<=n*Math.max(1,Math.abs(o),Math.abs(v))&&Math.abs(i-b)<=n*Math.max(1,Math.abs(i),Math.abs(b))&&Math.abs(c-m)<=n*Math.max(1,Math.abs(c),Math.abs(m))&&Math.abs(h-d)<=n*Math.max(1,Math.abs(h),Math.abs(d))&&Math.abs(s-x)<=n*Math.max(1,Math.abs(s),Math.abs(x))}});function qn(){var t=new a(2);return a!=Float32Array&&(t[0]=0,t[1]=0),t}function gn(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t}function An(t,n,a){return t[0]=n[0]*a[0],t[1]=n[1]*a[1],t}function wn(t,n,a){return t[0]=n[0]/a[0],t[1]=n[1]/a[1],t}function Rn(t,n){var a=n[0]-t[0],r=n[1]-t[1];return Math.hypot(a,r)}function zn(t,n){var a=n[0]-t[0],r=n[1]-t[1];return a*a+r*r}function Pn(t){var n=t[0],a=t[1];return Math.hypot(n,a)}function jn(t){var n=t[0],a=t[1];return n*n+a*a}var In=Pn,Sn=gn,En=An,On=wn,Tn=Rn,Dn=zn,Fn=jn,Ln=function(){var t=qn();return function(n,a,r,u,e,o){var i,c;for(a||(a=2),r||(r=0),c=u?Math.min(u*a+r,n.length):n.length,i=r;i0&&(u=1/Math.sqrt(u)),t[0]=n[0]*u,t[1]=n[1]*u,t},dot:function(t,n){return t[0]*n[0]+t[1]*n[1]},cross:function(t,n,a){var r=n[0]*a[1]-n[1]*a[0];return t[0]=t[1]=0,t[2]=r,t},lerp:function(t,n,a,r){var u=n[0],e=n[1];return t[0]=u+r*(a[0]-u),t[1]=e+r*(a[1]-e),t},random:function(t,n){n=n||1;var a=2*r()*Math.PI;return t[0]=Math.cos(a)*n,t[1]=Math.sin(a)*n,t},transformMat2:function(t,n,a){var r=n[0],u=n[1];return t[0]=a[0]*r+a[2]*u,t[1]=a[1]*r+a[3]*u,t},transformMat2d:function(t,n,a){var r=n[0],u=n[1];return t[0]=a[0]*r+a[2]*u+a[4],t[1]=a[1]*r+a[3]*u+a[5],t},transformMat3:function(t,n,a){var r=n[0],u=n[1];return t[0]=a[0]*r+a[3]*u+a[6],t[1]=a[1]*r+a[4]*u+a[7],t},transformMat4:function(t,n,a){var r=n[0],u=n[1];return t[0]=a[0]*r+a[4]*u+a[12],t[1]=a[1]*r+a[5]*u+a[13],t},rotate:function(t,n,a,r){var u=n[0]-a[0],e=n[1]-a[1],o=Math.sin(r),i=Math.cos(r);return t[0]=u*i-e*o+a[0],t[1]=u*o+e*i+a[1],t},angle:function(t,n){var a=t[0],r=t[1],u=n[0],e=n[1],o=a*a+r*r;o>0&&(o=1/Math.sqrt(o));var i=u*u+e*e;i>0&&(i=1/Math.sqrt(i));var c=(a*u+r*e)*o*i;return c>1?0:c<-1?Math.PI:Math.acos(c)},zero:function(t){return t[0]=0,t[1]=0,t},str:function(t){return"vec2("+t[0]+", "+t[1]+")"},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]},equals:function(t,a){var r=t[0],u=t[1],e=a[0],o=a[1];return Math.abs(r-e)<=n*Math.max(1,Math.abs(r),Math.abs(e))&&Math.abs(u-o)<=n*Math.max(1,Math.abs(u),Math.abs(o))},len:In,sub:Sn,mul:En,div:On,dist:Tn,sqrDist:Dn,sqrLen:Fn,forEach:Ln});t.glMatrix=e,t.mat2=s,t.mat2d=b,t.mat3=q,t.mat4=E,t.quat=cn,t.quat2=yn,t.vec2=Vn,t.vec3=$,t.vec4=Pt,Object.defineProperty(t,"__esModule",{value:!0})}); 29 | -------------------------------------------------------------------------------- /assets/include.math: -------------------------------------------------------------------------------- 1 | 123+46 x (456 + 4 * 4 + 5) 2 | y := x 3 | x := 5 4 | ( a ; b ) := ( 1 ; 2 ) 5 | (b;a) := (a;b) 6 | 123+46 x (456 + 4 * 4 + 5) 7 | -------------------------------------------------------------------------------- /assets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | OCalc 7 | 15 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /assets/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const http = require('http'); 3 | const url = require('url'); 4 | const v = require("./package.json").version; 5 | 6 | let serve_file = res => file => fs.open(file, 'r', 0o444, function(err, fd) { 7 | if (err) { 8 | res.writeHead(404); 9 | fs.createReadStream("404.html").pipe(res); 10 | } else { 11 | res.writeHead(200); 12 | fs.createReadStream(null, { 13 | fd 14 | }).pipe(res); 15 | } 16 | }); 17 | 18 | let is_main_page = url => /^\/(?:(?:index|main)(?:\.(?:(?:ht)?ml|js))?)?$/.test(url); 19 | 20 | let is_release = url => /\/releases?/.test(url); 21 | 22 | let match_only_version = url => url.match(/^\/(?:[vV]?(?(?0|[1-9]\d*)(?:\.(?0|[1-9]\d*)(?:\.(?0|[1-9]\d*))?)?)|(?last|latest))$/); 23 | 24 | let match_correct_path = url => url.match(/^\/(?:[vV]?(?(?0|[1-9]\d*)(?:\.(?0|[1-9]\d*)(?:\.(?0|[1-9]\d*))?)?)|(?last|latest))(?\/[^\/]*)?$/); 25 | 26 | let list_version = res => { 27 | console.log("releases"); 28 | serve_file(res)("index.html"); 29 | }; 30 | 31 | let server = http.createServer(function(req, res) { 32 | let u = url.parse(req.url); 33 | var match; 34 | 35 | if (u.search) 36 | console.error(res.connection.remoteAddress, res.connection.remotePort, req.url); 37 | 38 | if (is_main_page(u.pathname)) { 39 | console.log("is_main_page: index"); 40 | serve_file(res)("index.html"); 41 | } /*else if (is_release(u.pathname)) { 42 | console.log("is_release: list versions"); 43 | list_version(res); 44 | // TO BE COMPLETED 45 | } */else if ((match = match_only_version(u.pathname))) { 46 | var {groups: {major = '0', minor = '0', patch = '0', shorcut}} = match; 47 | console.log("match_version: redirect ", match.groups.version, "or", match.groups.shorcut, "to", `${major}.${minor}.${patch}/`); 48 | switch (shorcut) 49 | { 50 | case "latest": 51 | case "last": 52 | res.writeHead(302, { 53 | "Location": v + "/" 54 | }); 55 | break; 56 | default: 57 | res.writeHead(301, { 58 | "Location": `${major}.${minor}.${patch}/` 59 | }); 60 | break; 61 | } 62 | res.end(); 63 | } else if ((match = match_correct_path(u.pathname))) { 64 | var folder = undefined; 65 | var {groups: {major = '0', minor = '0', patch = '0', shorcut, rest}} = match; 66 | switch (shorcut) 67 | { 68 | case "latest": 69 | case "last": 70 | folder = v; 71 | break; 72 | default: 73 | folder = `${major}.${minor}.${patch}`; 74 | // add the .0 if needed 75 | break; 76 | } 77 | console.log("match_correct_path: folder :", folder); 78 | var new_path; 79 | if (is_main_page(rest)) 80 | new_path = folder + "/index.html"; 81 | else 82 | new_path = folder + "/" + rest.split('/').pop(); 83 | console.log("match_correct_path: ", new_path); 84 | serve_file(res)(new_path); 85 | } else { 86 | var new_path = u.pathname.split('/').pop(); 87 | console.log("fallback", new_path);// by default we look at current directory 88 | serve_file(res)(new_path); 89 | } 90 | }).listen(80); 91 | -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/logo.png -------------------------------------------------------------------------------- /assets/pi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/pi.png -------------------------------------------------------------------------------- /create-release.sh: -------------------------------------------------------------------------------- 1 | mkdir -p bin 2 | cp $cur__bin/* bin 3 | echo "<3" 4 | -------------------------------------------------------------------------------- /dune: -------------------------------------------------------------------------------- 1 | (env 2 | (dev 3 | (flags 4 | (:standard -w -42 -warn-error -A))) 5 | (release 6 | (flags 7 | (:standard -O3)))) 8 | 9 | (install 10 | (section bin) 11 | (package OCalc) 12 | (files 13 | package.json)) 14 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 1.7) 2 | (version dev) 3 | (using fmt 1.1) 4 | -------------------------------------------------------------------------------- /equation.ml: -------------------------------------------------------------------------------- 1 | let lire_sys nom_fichier = 2 | let nom_fichier = open_in nom_fichier in 3 | let rec boucle acc = 4 | try 5 | let s = input_line nom_fichier in 6 | let s = String.split_on_char '\t' s in 7 | let s = Array.of_list s in 8 | boucle (s :: acc) 9 | with End_of_file -> 10 | let () = close_in nom_fichier in 11 | match List.rev acc with 12 | [] -> failwith "pas assez de ligne" 13 | | e :: l -> l |> Array.of_list, e 14 | in let mat, inc = boucle [] in 15 | let w = Array.length inc in 16 | let mat = Array.map (function ligne -> Array.map float_of_string ligne) mat in 17 | let h = Array.length mat in 18 | mat, w, h, inc 19 | 20 | let addition_ligne ligne lignej = 21 | Array.mapi (fun i -> (+.) lignej.(i)) ligne 22 | 23 | let multiplication_ligne ligne j = 24 | Array.mapi (fun _ e -> e *. j) ligne 25 | 26 | let comb_lineaire mat (a, i) (b, j) = 27 | Array.mapi (fun k e -> a *. e +. b *. mat.(j).(k)) mat.(i) 28 | 29 | let echanger_ligne mat i j = 30 | let l = mat.(i) in 31 | let () = mat.(i) <- mat.(j) in 32 | mat.(j) <- l 33 | 34 | let ajouter_ligne mat i w h = 35 | let l = Array.make (w + 1) 0. in 36 | let () = l.(i) <- 1. in 37 | let () = l.(w) <- 1. in 38 | let () = mat := Array.append !mat [| l |] in 39 | incr h 40 | 41 | (** check if zero for the float*) 42 | let zero a = 43 | -0.0001 < a && a < 0.0001 44 | 45 | (** print unkwon and coefficient*) 46 | let print_mat inc mat = 47 | let () = Array.iter (Printf.printf "%.8s ") inc in 48 | let () = print_endline "" in 49 | Array.iter (fun l -> 50 | let () = Array.iter (Printf.printf "%.6f ") l in 51 | print_endline "" 52 | ) !mat 53 | 54 | let triangle_superieur (* inc *) mat h w = 55 | let mat = ref mat 56 | and h = ref h in 57 | let () = 58 | for i = 0 to pred w do 59 | (*let () = Printf.printf "on traite la colonne i: %d\n" i in*) 60 | let () = 61 | if i > pred !h then 62 | (*let () = Printf.printf "il nous manque une ligne\n" in 63 | let () = *)ajouter_ligne mat i w h 64 | (*in print_mat inc mat*) 65 | in let () = 66 | if zero !mat.(i).(i) then 67 | (*let () = Printf.printf "notre pivot est nul\n" in*) 68 | let () = 69 | for k = i + 1 to pred !h do 70 | if not (zero !mat.(k).(i)) then 71 | echanger_ligne !mat i i 72 | done 73 | in(* let () = print_mat inc mat in*) 74 | if zero !mat.(i).(i) then 75 | (*let () = Printf.printf "on n'a pas de remplacant\n" in*) 76 | let () = ajouter_ligne mat i w h in 77 | (*let () = *)echanger_ligne !mat (pred !h) i(* in 78 | print_mat inc mat*) 79 | in for j = i + 1 to pred !h do 80 | (*let () = Printf.printf "on traite la ligne j: %d\n" j in 81 | let () = print_mat inc mat in 82 | let () =*) 83 | !mat.(j) <- comb_lineaire !mat (!mat.(j).(i), i) (~-. (!mat.(i).(i)), j) 84 | (*in print_mat inc mat*) 85 | done 86 | done 87 | in !mat, !h 88 | 89 | let nomalise (* inc *) mat w = 90 | let () = 91 | for i = 0 to pred w do 92 | (*let () = 93 | Printf.printf "On reduit la ligne i: %d selon le pivot (%d, %d): %f\n" 94 | i i i mat.(i).(i) 95 | in let () = *)mat.(i) <- multiplication_ligne mat.(i) (1. /. mat.(i).(i))(* in 96 | print_mat inc (ref mat)*) 97 | done 98 | in mat 99 | 100 | let remonte (* inc *) mat w = 101 | let () = 102 | for i = pred w downto 0 do 103 | for k = i - 1 downto 0 do 104 | (*let () = Printf.printf "i: %d, k: %d, val: %f, val: %f\n" i k (mat.(i).(i)) (mat.(k).(i)) in 105 | let () = *)mat.(k) <- comb_lineaire mat (~-.(mat.(k).(i)), i) (mat.(i).(i), k)(* in 106 | print_mat inc (ref mat)*) 107 | done 108 | done 109 | in mat 110 | 111 | let contractition_presente mat w h = 112 | let resultat = ref false in 113 | let () = 114 | for i = w to pred h do 115 | (*let () = Printf.printf "i: %d, w: %d\n" i w in*) 116 | resultat := not (Float.classify_float mat.(i).(w) = Float.FP_zero) || !resultat 117 | done 118 | in !resultat 119 | 120 | let sauvegarder_resultat mat w h inc fichier = 121 | let fichier = open_out fichier in 122 | let () = 123 | if contractition_presente mat w h then 124 | output_string fichier "il y a une contractition presente\n" 125 | else 126 | Array.iteri (fun i e -> Printf.fprintf fichier "%s = %f\n" e mat.(i).(w)) inc in 127 | close_out fichier 128 | 129 | let resoudre_sys mat w h inc = 130 | let mat, h = triangle_superieur (* inc *) mat h w in 131 | let mat = nomalise (* inc *) mat w in 132 | let mat = remonte (* inc *) mat w in 133 | mat, w, h, inc;; 134 | 135 | let resoudre_sys_depuis_fichier nom_fichier sortie_fichier = 136 | let mat, w, h, inc = lire_sys nom_fichier in 137 | (*let () = Printf.printf "On a lu le systeme et on a w: %d, h: %d\n" w h in*) 138 | let mat, w, h, inc = resoudre_sys mat w h inc in 139 | sauvegarder_resultat mat w h inc sortie_fichier 140 | 141 | (** examples files*) 142 | let res = resoudre_sys_depuis_fichier "equation0.equ" "solution0.res";; 143 | let res = resoudre_sys_depuis_fichier "equation1.equ" "solution1.res";; 144 | let res = resoudre_sys_depuis_fichier "equation2.equ" "solution2.res";; 145 | let res = resoudre_sys_depuis_fichier "equation3.equ" "solution3.res";; 146 | let res = resoudre_sys_depuis_fichier "equation4.equ" "solution4.res";; 147 | let res = resoudre_sys_depuis_fichier "equation5.equ" "solution5.res";; 148 | let res = resoudre_sys_depuis_fichier "equation6.equ" "solution6.res";; 149 | -------------------------------------------------------------------------------- /equation0.equ: -------------------------------------------------------------------------------- 1 | x y z 2 | 1 1 0 4 3 | 2 2 5 6 4 | -------------------------------------------------------------------------------- /equation1.equ: -------------------------------------------------------------------------------- 1 | x y z 2 | 1 1 0 4 3 | 2 0 5 6 4 | -------------------------------------------------------------------------------- /equation2.equ: -------------------------------------------------------------------------------- 1 | x y z 2 | 1 1 0 4 3 | 0 2 5 6 4 | -------------------------------------------------------------------------------- /equation3.equ: -------------------------------------------------------------------------------- 1 | x y z 2 | 1 1 0 4 3 | 0 2 5 6 4 | 1 5 2 1 5 | 7 8 9 5 6 | -------------------------------------------------------------------------------- /equation4.equ: -------------------------------------------------------------------------------- 1 | x y z 2 | 0 1 1 4 3 | 5 2 0 6 4 | 2 5 1 1 5 | 9 8 7 5 6 | -------------------------------------------------------------------------------- /equation5.equ: -------------------------------------------------------------------------------- 1 | x y z a 2 | 0 1 1 0 4 3 | 5 2 0 0 6 4 | 2 5 1 0 1 5 | 9 8 7 0 5 6 | -------------------------------------------------------------------------------- /equation6.equ: -------------------------------------------------------------------------------- 1 | x y z 2 | 3 1 2 13 3 | 1 2 3 13 4 | 1 1 1 6 5 | 2 2 2 12 6 | -------------------------------------------------------------------------------- /matrix.ml: -------------------------------------------------------------------------------- 1 | module type Value = sig 2 | type t 3 | 4 | val zero : t 5 | val unit : t 6 | val neg : t -> t 7 | val additioner : t -> t -> t 8 | val soustraire : t -> t -> t 9 | val diviser : t -> t -> t 10 | val multiplier : t -> t -> t 11 | val print : t -> unit 12 | end 13 | 14 | module Generic_matrix (V : Value) = struct 15 | type t = V.t array array 16 | 17 | let print = V.print 18 | let init n p = Array.make_matrix n p V.zero 19 | let __protect m = Array.length m > 0 && Array.length m.(0) > 0 20 | let size m = 21 | let h = Array.length m in 22 | if h = 0 then 23 | h, 0 24 | else 25 | h, Array.length m.(0) 26 | let foreach ?(line = function _ -> ()) m f = 27 | if __protect m then 28 | let h, w = size m in 29 | for i = 0 to pred h do 30 | let () = 31 | for j = 0 to pred w do 32 | f i j m.(i).(j) 33 | done 34 | in line m.(i) 35 | done 36 | let print m = 37 | let () = 38 | foreach ~line:(fun _ -> print_char '\n') m (fun _ _ -> V.print) 39 | in print_char '\n' 40 | let foreach2 f m1 m2 = 41 | let (h, w) = size m1 in 42 | if (h, w) = size m2 then 43 | let mres = init h w in 44 | let () = foreach m1 (fun i j e -> mres.(i).(j) <- f e m2.(i).(j)) in 45 | mres 46 | else 47 | failwith (I18n.matrice_mauvaise_dimension ()) 48 | let __vide_vers_identite m = 49 | let h, w = size m in 50 | let () = 51 | for i = 0 to pred (min h w) do 52 | m.(i).(i) <- V.unit 53 | done 54 | in m 55 | let identite n = 56 | let mres = init n n in 57 | __vide_vers_identite mres 58 | let additioner m1 m2 = foreach2 V.additioner m1 m2 59 | let soustraire m1 m2 = foreach2 V.soustraire m1 m2 60 | let multiplier m1 m2 = 61 | let (n, p) = size m1 62 | and (p', q) = size m2 in 63 | if p = p' then 64 | let mres = init n n in 65 | let prod_ligne_colonne i j = 66 | let res = ref V.zero in 67 | let () = 68 | for k = 0 to pred p do 69 | res := V.additioner !res (V.multiplier m1.(i).(k) m2.(k).(j)) 70 | done 71 | in !res 72 | in let () = foreach mres (fun i j _ -> mres.(i).(j) <- prod_ligne_colonne i j) in 73 | mres 74 | else 75 | failwith (I18n.matrice_mauvaise_dimension ()) 76 | let multiplier_scalaire m scalaire = 77 | let (h, w) = size m in 78 | let mres = init h w in 79 | let () = foreach m (fun i j e -> mres.(i).(j) <- V.multiplier e scalaire) in 80 | mres 81 | module Operation_elementaires = struct 82 | let multiplier_ligne l scalaire = 83 | Array.map (V.multiplier scalaire) l 84 | let additioner_ligne l1 l2 = 85 | Array.mapi (fun k -> V.additioner l2.(k)) l1 86 | let neg_ligne l = 87 | Array.map V.neg l 88 | let echanger_ligne m i j = 89 | let tmp = m.(i) in 90 | let () = m.(i) <- m.(j) in 91 | m.(j) <- tmp 92 | let affecter_ligne m i l = 93 | m.(i) <- l 94 | end 95 | let inverser m' = 96 | let h, w = size m' in 97 | let m = init h w in 98 | let () = foreach m' (fun i j e -> m.(i).(j) <- e) in 99 | let n = min h w in 100 | let mres = init w h in 101 | let mres = __vide_vers_identite mres in 102 | let open Operation_elementaires in 103 | let () = 104 | for i = 0 to pred (pred n) do 105 | for j = i + 1 to pred h do 106 | if m.(j).(i) <> V.zero then 107 | (* let () = *) 108 | if m.(i).(i) = V.zero then 109 | let () = echanger_ligne m j i in 110 | echanger_ligne mres j i 111 | else 112 | let pivot = m.(i).(i) in 113 | let coeff = V.diviser m.(j).(i) pivot in 114 | let modifier_ligne m = 115 | let ligne = multiplier_ligne m.(i) coeff in 116 | let ligne = neg_ligne ligne in 117 | let ligne = additioner_ligne m.(j) ligne in 118 | affecter_ligne m j ligne 119 | in let () = modifier_ligne m in 120 | if j < n then 121 | modifier_ligne mres 122 | (* in fact we should empty it *) 123 | (*in print mres*) 124 | done 125 | done 126 | in let () = print m in 127 | let () = print_char '\n' in 128 | let () = print_char '\n' in 129 | mres 130 | 131 | end 132 | 133 | module Test = struct 134 | type t = int 135 | 136 | let zero = 0 137 | let unit = 1 138 | let neg = ( ~- ) 139 | let additioner = ( + ) 140 | let soustraire = ( - ) 141 | let diviser = ( / ) 142 | let multiplier = ( * ) 143 | let print = Printf.printf "%5d" 144 | end 145 | 146 | module Test_matrix = Generic_matrix(Test) 147 | 148 | module Test_float = struct 149 | type t = float 150 | 151 | let zero = 0. 152 | let unit = 1. 153 | let neg = ( ~-. ) 154 | let additioner = ( +. ) 155 | let soustraire = ( -. ) 156 | let diviser = ( /. ) 157 | let multiplier = ( *. ) 158 | let print = Printf.printf "%10.6f" 159 | end 160 | 161 | module Test_float_matrix = Generic_matrix(Test_float) 162 | 163 | let m1 = 164 | [| 165 | [|1; 2; 3|]; 166 | [|4; 5; 6|]; 167 | [|7; 8; 9|]; 168 | |] 169 | 170 | let m2 = 171 | [| 172 | [|9; 8; 7|]; 173 | [|6; 5; 4|]; 174 | [|3; 2; 1|]; 175 | |] 176 | 177 | let m3 = 178 | [| 179 | [|6.; 6.; 6.|]; 180 | [|4.; 7.; 6.|]; 181 | [|6.; 4.; 6.|]; 182 | (*[|6.; 4.; 6.|];(* for test *) 183 | [|6.; 4.; 5.|];(* for test *) 184 | [|6.; 4.; 6.|];(* for test *) *) 185 | |] 186 | 187 | let inv_m3 = 188 | [| 189 | [|9. ; -6.; -3.|]; 190 | [|6. ; 0.; -6.|]; 191 | [|-13.; 6.; 9.|]; 192 | |] 193 | 194 | (* 195 | let i3 = Test_matrix.identite 3 196 | let res1 = Test_matrix.additioner m1 m2 197 | let res2 = Test_matrix.soustraire res1 m2 198 | let res3 = Test_matrix.multiplier i3 m1*) 199 | let res4 = Test_float_matrix.inverser m3 200 | (* 201 | let () = Test_float_matrix.print 202 | (Test_float_matrix.multiplier_scalaire inv_m3 (1. /. 12.)) 203 | let () = Test_float_matrix.print (Test_float_matrix.multiplier res4 m3) 204 | *) 205 | 206 | (* 207 | let () = Test_matrix.print i3 208 | let () = Test_matrix.print m1 209 | let () = Test_matrix.print res1 210 | let () = Test_matrix.print res2 211 | let () = Test_matrix.print res3 212 | *) 213 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ocalc", 3 | "version": "0.5.1", 4 | "description": "A formal calculator written in OCaml", 5 | "main": "index.js", 6 | "esy": { 7 | "build": [ 8 | "dune build OCalc.install", 9 | "refmterr dune build src/interfaces/topCmd.exe", 10 | "refmterr dune build src/interfaces/topTest.exe", 11 | "refmterr dune build src/interfaces/topGui.exe" 12 | ], 13 | "install": [ 14 | "esy-installer OCalc.install" 15 | ] 16 | }, 17 | "dependencies": { 18 | "ejs": "^2.6.1" 19 | }, 20 | "devDependencies": { 21 | "@esy-ocaml/reason": "3.4.0", 22 | "reason-glfw": "^3.2.1024", 23 | "reason-fontkit": "^2.4.0", 24 | "reason-gl-matrix": "^0.9.9304", 25 | "rebez": "*", 26 | "revery": "*", 27 | "@opam/color": "^0.2.0", 28 | "@opam/js_of_ocaml": "*", 29 | "@opam/js_of_ocaml-compiler": "*", 30 | "@opam/js_of_ocaml-lwt": "*", 31 | "@opam/lwt": "^4.0.0", 32 | "@opam/lwt_ppx": "^1.1.0", 33 | "@brisk/brisk-reconciler": "*", 34 | "flex": "^1.2.2", 35 | "reperf": "^1.4.0", 36 | "@reason-native/console": "^0.0.3", 37 | "ocaml": "^4.7.0", 38 | "@opam/dune": "^1.5.0", 39 | "@opam/odoc": "*", 40 | "@opam/yojson": "^1.7.0", 41 | "@opam/lambda-term": "1.13", 42 | "minesweeper": "*" 43 | }, 44 | "resolutions": { 45 | "@opam/dune": "1.7.3", 46 | "rebez": "github:jchavarri/rebez#46cbc183", 47 | "@opam/cmdliner": "1.0.2", 48 | "@opam/js_of_ocaml": "github:ocsigen/js_of_ocaml:js_of_ocaml.opam#db257ce", 49 | "@opam/js_of_ocaml-compiler": "github:ocsigen/js_of_ocaml:js_of_ocaml-compiler.opam#db257ce", 50 | "@brisk/brisk-reconciler": "github:briskml/brisk-reconciler#dd933fc", 51 | "revery": "github:revery-ui/revery#ea61525eb266b8c7b478558bad5686acdccc10c4", 52 | "minesweeper": "github:Et7f3/minesweeper#6bb8fde5b4556f7b209ad85cb8aba66b480d6dc6" 53 | }, 54 | "scripts": { 55 | "test": "echo \"Error: no test specified\" && exit 1", 56 | "build": "esy b", 57 | "build:release": "esy b dune build --profile=release --root . -j4", 58 | "build:js": "esy b dune build examples/Examples.bc.js", 59 | "build:js:release": "esy b dune build examples/Examples.bc.js", 60 | "revery-test": "esy b dune runtest", 61 | "format": "esy dune build @fmt --auto-promote", 62 | "format:windows": "esy b .ci/format.sh", 63 | "doc": "refmterr esy dune build @doc --root .", 64 | "create-release": "bash ./create-release.sh", 65 | "run": "esy x OCalc #{self.bin}/include.math" 66 | }, 67 | "repository": { 68 | "type": "git", 69 | "url": "ocal.github" 70 | }, 71 | "keywords": [ 72 | "formal", 73 | "calculator", 74 | "ocaml" 75 | ], 76 | "maintainers": [ 77 | "elie.brami", 78 | "alexandre.mourgues", 79 | "gautier.habermann", 80 | "quentin.feugueur" 81 | ], 82 | "license": "ISC" 83 | } 84 | -------------------------------------------------------------------------------- /src/interfaces/commune.ml: -------------------------------------------------------------------------------- 1 | let argv = Sys.argv 2 | let argc = Array.length argv 3 | let api_url = "https://api.github.com/repos/Et7f3/ocalc/releases" 4 | 5 | let liste_historique = ref [] 6 | 7 | let evaluer_fichier fichier contexte = 8 | if Revery.Environment.webGL then 9 | contexte 10 | else 11 | if Filename.check_suffix fichier ".math" then 12 | try 13 | let fichier = open_in fichier in 14 | let rec boucle f = 15 | try 16 | let entree = input_line fichier in 17 | let sortie, f = 18 | try 19 | Noyau.Moteur.evaluate_with_history entree f 20 | with Division_by_zero -> (I18n.division_par_zero ()), f 21 | in let hist = Printf.sprintf "%s = %s" entree sortie in 22 | let () = liste_historique := hist :: !liste_historique in 23 | let () = print_endline hist in 24 | let () = flush stdout in 25 | boucle f 26 | with End_of_file -> 27 | let () = close_in fichier in 28 | f 29 | in boucle contexte 30 | with Sys_error _ -> 31 | let () = prerr_endline (I18n.fichier_inexistant fichier) in 32 | contexte 33 | else 34 | let () = prerr_endline (I18n.fichier_pas_math fichier) in 35 | contexte 36 | 37 | let init_context = 38 | if Revery.Environment.webGL then 39 | Noyau.Moteur.empty_context 40 | else 41 | let evaluate_arg f max = 42 | let rec evaluate_arg f i = 43 | if i = max then 44 | let () = flush stdout in 45 | let () = flush stderr in 46 | f 47 | else 48 | let f = evaluer_fichier Sys.argv.(i) f in 49 | evaluate_arg f (i + 1) 50 | in evaluate_arg f 1 51 | in evaluate_arg Noyau.Moteur.empty_context (Array.length Sys.argv) 52 | 53 | (* 54 | let ip = Unix.((gethostbyname "localhost").h_addr_list.(0)) 55 | let addr = Unix.ADDR_INET (ip, 80) 56 | 57 | let s = 58 | "GET /repos/Et7f3/ocalc/releases HTTP/1.1\r\n\ 59 | Host: api.github.com\r\n\ 60 | User-Agent: OCaml\r\n\ 61 | Connection: close\r\n\ 62 | \r\n" 63 | 64 | let sock = Unix.(socket PF_INET SOCK_STREAM 0) 65 | let _ = Unix.connect sock addr 66 | 67 | let in_ch = Unix.in_channel_of_descr sock 68 | let out_ch = Unix.out_channel_of_descr sock 69 | 70 | 71 | 72 | let _ = 73 | output_string out_ch 74 | s; 75 | flush out_ch 76 | 77 | 78 | 79 | let g = 80 | try 81 | let () = while input_line in_ch <> "\r"; do () done in 82 | Yojson.Basic.from_channel in_ch 83 | with End_of_file -> 84 | let () = Unix.close sock in 85 | Yojson.Basic.from_string "[]";; 86 | 87 | match g with 88 | `List l -> List.iter (function g -> Printf.printf "%s\n\n" (Yojson.Basic.to_string g)) l 89 | | _ -> print_endline "can't load versions" 90 | *) 91 | -------------------------------------------------------------------------------- /src/interfaces/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name Commune) 3 | (modules Commune) 4 | (libraries Yojson Revery Noyau)) 5 | 6 | (executable 7 | (name topCmd) 8 | (modules TopCmd) 9 | (public_name topCmd) 10 | (package OCalc) 11 | (libraries Commune Noyau I18n)) 12 | 13 | (executable 14 | (name topTest) 15 | (modules TopTest) 16 | (public_name topTest) 17 | (package OCalc) 18 | (libraries Commune Noyau)) 19 | 20 | (executable 21 | (name topGui) 22 | (modules TopGui) 23 | (public_name OCalc) 24 | (package OCalc) 25 | (libraries js_of_ocaml Revery Commune Noyau Minesweeper.lib)) 26 | -------------------------------------------------------------------------------- /src/interfaces/topCmd.ml: -------------------------------------------------------------------------------- 1 | let corp_principal contexte = 2 | let ps1 = "# " in 3 | let () = print_endline (I18n.bienvenue ()) in 4 | let () = print_endline (I18n.sortir_msg ()) in 5 | let rec evalue_en_boucle ancienne_ligne contexte = 6 | let () = print_string ps1 in 7 | let ligne = ancienne_ligne ^ read_line () in 8 | if Filename.check_suffix ligne ";;" then 9 | let ligne = 10 | let taille = String.length ligne - 2 in 11 | String.sub ligne 0 taille 12 | in 13 | if ligne <> I18n.sortir_1 () || ligne <> I18n.sortir_2 () then 14 | let sortie, contexte = 15 | if Noyau.Utils.parenthese_correcte ligne then 16 | try 17 | Noyau.Moteur.evaluate_with_history ligne contexte 18 | with Division_by_zero -> (I18n.division_par_zero ()), contexte 19 | else 20 | I18n.mauvais_parenthesage (), contexte 21 | in let () = print_endline sortie in 22 | evalue_en_boucle "" contexte 23 | else 24 | evalue_en_boucle ligne contexte 25 | in evalue_en_boucle "" contexte 26 | in corp_principal Commune.init_context 27 | -------------------------------------------------------------------------------- /src/interfaces/topCmd.mli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topCmd.mli -------------------------------------------------------------------------------- /src/interfaces/topFichiers.ml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topFichiers.ml -------------------------------------------------------------------------------- /src/interfaces/topFichiers.mli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topFichiers.mli -------------------------------------------------------------------------------- /src/interfaces/topGui.ml: -------------------------------------------------------------------------------- 1 | open Revery 2 | open Revery.UI 3 | open Revery.UI.Components 4 | 5 | 6 | let bgColor = 7 | (*if Environment.webGL then 8 | Color.hex("#ffffff") 9 | else*) 10 | Color.hex("#212733") 11 | 12 | let _ (* txtColor *) = 13 | (*if Environment.webGL then 14 | Color.rgb 0. 0. 0. 15 | else*) 16 | Color.rgb 255. 255. 255. 17 | 18 | type vue = 19 | [ 20 | `VueCalcul 21 | | `VueHistorique 22 | | `VueMatrice 23 | | `VueAccueil 24 | | `VueEquation 25 | | `VueBonus 26 | ] 27 | 28 | (* 29 | type vue_par_defaut_state = 30 | { 31 | nothing: unit; 32 | } 33 | *) 34 | type calcul_state = 35 | { 36 | valeur: string; 37 | res: string; 38 | liste_historique: string list; 39 | context: Noyau.Moteur.context; 40 | } 41 | 42 | type historique_state = 43 | { 44 | mutable liste: string list; 45 | } 46 | 47 | type matrice_mode = 48 | [ 49 | `Solveur 50 | | `Addition 51 | | `Soustraction 52 | | `Multiplication 53 | | `Inverse 54 | ] 55 | 56 | type matrice_state = 57 | { 58 | mode: matrice_mode; 59 | mutable matrice1: string array array; 60 | mutable matrice2: string array array; 61 | mutable matrice_res: string array array; 62 | mutable taille1: int * int; 63 | mutable taille2: int * int; 64 | mutable taille_res: int * int; 65 | message: string; 66 | } 67 | 68 | type equation_state = 69 | { 70 | (* 71 | mutable inconnu: string list; 72 | mutable nbr_inc: int; 73 | mutable lines: int; 74 | mutable mat1: string array array; 75 | mutable mat2: string array array; 76 | res: string; 77 | *) 78 | inconnues: string array; 79 | nbr_inc: int; 80 | coef: string array array; 81 | nbr_ligne: int; 82 | resultat: Noyau.Moteur.Expr_matrix.solution_equation option 83 | } 84 | 85 | type accueil_state = 86 | { 87 | lang : I18n.lang; 88 | } 89 | 90 | type application_state = 91 | { 92 | vue_courante: vue; 93 | } 94 | 95 | type application_sauvegarde = 96 | { 97 | calcul: calcul_state; 98 | equation: equation_state; 99 | historique: historique_state; 100 | matrice: matrice_state; 101 | accueil: accueil_state; 102 | } 103 | 104 | (* 105 | module VueParDefaut = struct 106 | let component = React.component "VueParDefaut" 107 | 108 | type action = Nope 109 | 110 | let reducer action etat = 111 | match action with 112 | Nope -> etat 113 | 114 | let createElement ~initialState ~changerVue ~onUpdate = 115 | fun ~children:_ () -> 116 | component 117 | (fun hooks -> 118 | let ({_} (* nouvel etat *) as etat, _ (* dispatch *), hooks) = 119 | React.Hooks.reducer ~initialState reducer hooks 120 | in let () = onUpdate (`VueParDefaut etat) in 121 | (hooks, View.createElement ~children:[] ())) 122 | end 123 | *) 124 | 125 | module Bouton = struct 126 | let style_btn = Style.[fontSize 25; fontFamily "Roboto-Regular.ttf"] 127 | 128 | let menu_retour ~onMouseUp ?(style=[]) () = 129 | Text.createElement ~text:(I18n.retour ()) ~onMouseUp 130 | ~style:(style @ style_btn) 131 | ~children:[] () 132 | 133 | let calculer ~onMouseUp ?(style=[]) () = 134 | Text.createElement ~text:(I18n.calculer ()) ~onMouseUp 135 | ~style:(style @ style_btn) 136 | ~children:[] () 137 | 138 | let effacer ~onMouseUp ?(style=[]) () = 139 | Text.createElement ~text:(I18n.effacer ()) ~onMouseUp 140 | ~style:(style @ style_btn) 141 | ~children:[] () 142 | 143 | let menu_historique ~onMouseUp ?(style=[]) () = 144 | Text.createElement ~text:(I18n.menu_historique ()) ~onMouseUp 145 | ~style:(style @ style_btn) 146 | ~children:[] () 147 | 148 | let menu_matrices ~onMouseUp ?(style=[]) () = 149 | Text.createElement ~text:(I18n.menu_matrices ()) ~onMouseUp 150 | ~style:(style @ style_btn) 151 | ~children:[] () 152 | 153 | let menu_accueil ~onMouseUp ?(style=[]) () = 154 | Text.createElement ~text:(I18n.menu_accueil ()) ~onMouseUp 155 | ~style:(style @ style_btn) 156 | ~children:[] () 157 | 158 | let menu_calcul ~onMouseUp ?(style=[]) () = 159 | Text.createElement ~text:(I18n.menu_calcul ()) ~onMouseUp 160 | ~style:(style @ style_btn) 161 | ~children:[] () 162 | 163 | let menu_equations ~onMouseUp ?(style=[]) () = 164 | Text.createElement ~text:(I18n.menu_equations ()) ~onMouseUp 165 | ~style:(style @ style_btn) 166 | ~children:[] () 167 | 168 | let plus ~onMouseUp ?(style=[]) () = 169 | Text.createElement ~text:"+" ~onMouseUp 170 | ~style:(style @ style_btn) 171 | ~children:[] () 172 | 173 | let moins ~onMouseUp ?(style=[]) () = 174 | Text.createElement ~text:"-" ~onMouseUp 175 | ~style:(style @ style_btn) 176 | ~children:[] () 177 | end 178 | 179 | module VueBonus = struct 180 | let createElement ~changerVue ~onUpdate:_ ~children:_ () = 181 | let retour_maison = 182 | Bouton.menu_retour ~onMouseUp:(fun _ -> changerVue `VueAccueil) 183 | ~style:Style.[position `Absolute; bottom 10; right 10] () 184 | in Minesweeper_lib.MineSweeper.createElement ~children:[retour_maison] () 185 | end 186 | 187 | module Calcul = struct 188 | let component = React.component "Calcul" 189 | 190 | type action = 191 | Vider 192 | | MiseAJour of string 193 | | Calculer 194 | 195 | let reducer action etat = 196 | match action with 197 | Vider -> {etat with valeur = ""} 198 | | MiseAJour valeur -> {etat with valeur} (* ici on met à jour notre état *) 199 | | Calculer -> 200 | let res = etat.valeur in 201 | let res, cxt = 202 | try 203 | Noyau.Moteur.evaluate_with_history res etat.context 204 | with 205 | Failure msg -> msg, etat.context (* old context *) 206 | | Division_by_zero -> 207 | I18n.division_par_zero (), etat.context (* old context *) 208 | in let res = etat.valeur ^ " = " ^ res in 209 | { 210 | liste_historique = res :: etat.liste_historique; 211 | context = cxt; 212 | valeur = ""; 213 | res 214 | } 215 | 216 | let createElement ~initialState ~changerVue ~onUpdate = 217 | let containerStyle = 218 | Style.[ 219 | position `Absolute; 220 | justifyContent `Center; 221 | alignItems `Center; 222 | bottom 0; 223 | top 0; 224 | left 0; 225 | right 0; 226 | ] 227 | in let textStyle = 228 | Style.[ 229 | fontSize 25; 230 | fontFamily "Roboto-Regular.ttf"; 231 | bottom 0; 232 | top 0; 233 | left 0; 234 | right 0; 235 | ] 236 | in fun ~children:_ () -> 237 | component (function hooks -> 238 | let ({valeur; res; _} as etat, dispatch, hooks) = 239 | React.Hooks.reducer ~initialState reducer hooks 240 | in let () = onUpdate (`Calcul etat) in 241 | let bouton_calc = 242 | Bouton.calculer ~style:[] ~onMouseUp:(fun _ -> dispatch Calculer) () 243 | in let bouton_supp = 244 | Bouton.effacer ~style:Style.[marginHorizontal 20] 245 | ~onMouseUp:(fun _ -> dispatch Vider) () 246 | in let sous_bout = 247 | View.createElement ~style:Style.[flexDirection `Row] 248 | ~children:[bouton_calc; bouton_supp] () 249 | in let bouton_his = 250 | Bouton.menu_historique 251 | ~style:Style.[position `Absolute; left 10; bottom 10] 252 | ~onMouseUp:(fun _ -> changerVue `VueHistorique) () 253 | in let bouton_acc = 254 | Bouton.menu_accueil 255 | ~style:Style.[position `Absolute; bottom 10; right 10] 256 | ~onMouseUp:(fun _ -> changerVue `VueAccueil) () 257 | in let boutton_mat = 258 | Bouton.menu_matrices 259 | ~onMouseUp:(fun _ -> changerVue `VueMatrice) 260 | ~style:Style.[justifyContent `Center; 261 | position `Absolute; bottom 50; right 10] 262 | () 263 | in let boutton_equ = 264 | Bouton.menu_equations 265 | ~onMouseUp:(fun _ -> changerVue `VueEquation) 266 | ~style:Style.[justifyContent `Center; position `Absolute; 267 | bottom 90; right 10] () 268 | in let dimensions = Monitor.getPrimaryMonitor () |> Monitor.getSize in 269 | hooks, 270 | View.createElement ~style:containerStyle ~children:[ 271 | Input.createElement 272 | ~style:Style.[color (Color.rgb 25. 5. 5.); bottom 0; top 0; 273 | left 0; right 0; width ( 274 | let taille = max 200 (String.length valeur * 10 + 20) in 275 | if taille < dimensions.width / 2 - 20 then 276 | taille 277 | else 278 | dimensions.width / 2 - 20 279 | )] 280 | ~value:valeur ~placeholder:"Entrer votre calcul" 281 | ~onChange:(fun {value; _} -> dispatch(MiseAJour value)) 282 | ~children:[] (); 283 | Text.createElement ~text:res(* retour du moteur *) ~style:textStyle 284 | ~children:[] (); sous_bout; bouton_acc; bouton_his; 285 | boutton_equ; boutton_mat] ()) 286 | end 287 | 288 | module Historique = struct 289 | let component = React.component "Historique" 290 | 291 | let createElement historique ~changerVue ~onUpdate:_ = 292 | let containerStyle = 293 | Style.[ 294 | position `Absolute; 295 | justifyContent `Center; 296 | alignItems `Center; 297 | bottom 0; 298 | top 0; 299 | left 0; 300 | right 0 301 | ] 302 | in let textStyle = 303 | Style.[ 304 | fontSize 25; 305 | left 0; 306 | right 0; 307 | bottom 0; 308 | top 0; 309 | fontFamily "Roboto-Regular.ttf" 310 | ] 311 | in let histol hist = 312 | let txt_gen = Text.createElement ~style:textStyle ~children:[] in 313 | List.map (fun text -> txt_gen ~text ()) hist 314 | in fun ~children:_ () -> 315 | component (fun hooks -> 316 | let bouton_retour = 317 | Bouton.menu_retour ~onMouseUp:(fun _ -> changerVue `VueCalcul) 318 | ~style:Style.[position `Absolute; bottom 10; right 10] () 319 | in hooks, 320 | View.createElement ~style:containerStyle 321 | ~children:(bouton_retour :: (histol historique)) ()) 322 | end 323 | 324 | module Matrice = struct 325 | let component = React.component "Matrice" 326 | 327 | type 'a action = 328 | MiseAJour of int * int * int * string(* * ('a -> unit) *) 329 | | MiseAJourEntete of int * string(* * ('a -> unit) *) 330 | | ChangerMode of matrice_mode 331 | | Calculer of matrice_mode 332 | 333 | let reducer action etat = 334 | match action with 335 | MiseAJour (id, i, j, v(*, f*)) -> 336 | let mat = 337 | if id = 1 then 338 | etat.matrice1 339 | else 340 | etat.matrice2 341 | in let () = 342 | try 343 | let _ = float_of_string v in 344 | mat.(i).(j) <- v 345 | with Failure _ -> () 346 | in (*let () = f (`Matrice etat) in*) 347 | if id = 1 then 348 | {etat with matrice1 = mat} 349 | else 350 | {etat with matrice2 = mat} 351 | | MiseAJourEntete (j, v(*, f*)) -> 352 | let () = etat.matrice1.(0).(j) <- v in 353 | {etat with matrice1 = etat.matrice1} 354 | | ChangerMode m -> 355 | if m <> `Solveur then 356 | { 357 | etat with mode = m; 358 | taille2 = (let (h, _) = etat.taille1 in (h, 2)); 359 | taille_res = (let (h, _) = etat.taille_res in (h, 2)); 360 | } 361 | else 362 | { 363 | etat with mode = m; 364 | taille2 = (let (h, _) = etat.taille1 in (h, 1)); 365 | taille_res = (let (h, _) = etat.taille_res in (h, 1)); 366 | } 367 | | Calculer `Solveur -> 368 | etat 369 | | Calculer _ -> 370 | let array_map2 f = Array.map (fun e -> Array.map f e) in 371 | let m1 = array_map2 float_of_string etat.matrice1 in 372 | let m2 = array_map2 float_of_string etat.matrice2 in 373 | let f = 374 | ( 375 | match etat.mode with 376 | `Addition -> Modules.Matrix.Test_float_matrix.additioner 377 | | `Soustraction -> Modules.Matrix.Test_float_matrix.soustraire 378 | | `Multiplication -> Modules.Matrix.Test_float_matrix.multiplier 379 | | _ -> Modules.Matrix.Test_float_matrix.additioner 380 | ) 381 | in let matrice_res = f m1 m2 in 382 | let matrice_res = array_map2 string_of_float matrice_res in 383 | { 384 | etat with matrice_res; 385 | taille_res = (Array.length matrice_res, Array.length matrice_res.(0)); 386 | } 387 | 388 | 389 | let createElement ~initialState ~changerVue ~onUpdate = 390 | fun ~children:_ () -> 391 | component (fun hooks -> 392 | let (etat (* nouvel etat *), dispatch, hooks) = 393 | React.Hooks.reducer ~initialState reducer hooks 394 | in let () = onUpdate (`Matrice etat) in 395 | let dessiner_matrice (h, w) f = 396 | let input = ref [] in 397 | let row_gen = View.createElement ~style:Style.[flexDirection(`Row)] in 398 | let () = 399 | for i = pred h downto 0 do 400 | let row = ref [] in 401 | let () = 402 | for j = pred w downto 0 do 403 | row := (f i j) :: !row 404 | done 405 | in input := (row_gen ~children:!row ()) :: !input 406 | done 407 | in (View.createElement ~children:!input) () 408 | in let input_gen = 409 | Input.createElement 410 | ~style:Style.[color (Color.rgb 255. 255. 255.); width 100; 411 | margin2 ~horizontal:40 ~vertical:10] 412 | in let m1 = 413 | dessiner_matrice etat.taille1 (fun i j -> input_gen 414 | ~value:etat.matrice1.(i).(j) 415 | ~placeholder:etat.matrice1.(0).(j) 416 | ~onChange:(fun {value; _} -> 417 | if i = 0 && etat.mode = `Solveur then 418 | dispatch(MiseAJourEntete (j, value(*, onUpdate *))) 419 | else 420 | dispatch(MiseAJour (1, i, j, value(*, onUpdate *))) 421 | ) 422 | ~children:[] ()) 423 | in let op: Dropdown.items = 424 | [ 425 | {value = "+"; label = "+ "; 426 | (* all this space are for a bug *)}; 427 | {value = "-"; label = "- ";}; 428 | {value = "*"; label = "* ";}; 429 | (*{value = "resoudre"; label = "resoudre ";};*) 430 | ] 431 | in let dropdown = 432 | Dropdown.createElement ~items:op 433 | ~onItemSelected:(fun {value = a; _} -> dispatch ((function 434 | "+" -> ChangerMode `Addition 435 | | "-" -> ChangerMode `Soustraction 436 | | "*" -> ChangerMode `Multiplication 437 | | "resoudre" -> ChangerMode `Solveur 438 | | _ -> failwith "impossible") a)) 439 | ~children:[] () 440 | in let m2 = 441 | dessiner_matrice etat.taille2 (fun i j -> input_gen 442 | ~value:etat.matrice2.(i).(j) 443 | ~placeholder:etat.matrice2.(0).(j) 444 | ~onChange:(fun {value; _} -> 445 | if i = 0 && etat.mode = `Solveur then 446 | dispatch(MiseAJourEntete (j, value(*, onUpdate *))) 447 | else 448 | dispatch(MiseAJour (2, i, j, value(*, onUpdate *))) 449 | ) 450 | ~children:[] ()) 451 | in let m_res = 452 | dessiner_matrice etat.taille_res (fun i j -> input_gen 453 | ~value:etat.matrice_res.(i).(j) 454 | ~children:[] ()) 455 | in let bouton_calc = 456 | Bouton.calculer 457 | ~onMouseUp:(fun _ -> dispatch (Calculer etat.mode)) 458 | ~style:Style.[position `Absolute; bottom 10; right 10] () 459 | in let bouton_retour = 460 | Bouton.menu_accueil 461 | ~onMouseUp:(fun _ -> changerVue `VueAccueil) 462 | ~style:Style.[position `Absolute; bottom 10; left 10] () 463 | in let boutton_equ = 464 | Bouton.menu_equations ~onMouseUp:(fun _ -> changerVue `VueEquation) 465 | ~style:Style.[justifyContent `Center; position `Absolute; 466 | bottom 90; left 10] () 467 | in let boutton_cal = 468 | Bouton.menu_calcul ~onMouseUp:(fun _ -> changerVue `VueCalcul) 469 | ~style:Style.[justifyContent `Center; position `Absolute; 470 | bottom 50; left 10] () 471 | in let children1 = 472 | [bouton_retour; bouton_calc; boutton_cal; boutton_equ] 473 | in let chmttaille id c d (a, b) = 474 | match id with 475 | 1 when d -> 476 | if c then 477 | etat.taille1 <- (a + 1, b) 478 | else if a > 1 then 479 | etat.taille1 <- (a - 1, b) 480 | | 1 -> 481 | if c then 482 | etat.taille1 <- (a, b + 1) 483 | else if b > 1 then 484 | etat.taille1 <- (a, b - 1) 485 | | 2 when d -> 486 | if c then 487 | etat.taille2 <- (a + 1, b) 488 | else if a > 1 then 489 | etat.taille2 <- (a - 1, b) 490 | | 2 -> 491 | if c then 492 | etat.taille2 <- (a, b + 1) 493 | else if b > 1 then 494 | etat.taille2 <- (a, b - 1) 495 | | 3 when d -> 496 | if c then 497 | etat.taille_res <- (a + 1, b) 498 | else if a > 1 then 499 | etat.taille_res <- (a - 1, b) 500 | | _ -> 501 | if c then 502 | etat.taille_res <- (a, b + 1) 503 | else if b > 1 then 504 | etat.taille_res <- (a, b - 1) 505 | in let chmtmat id (a, b) = 506 | match id with 507 | 1 -> etat.matrice1 <- Array.make_matrix a b "0" 508 | | 2 -> etat.matrice2 <- Array.make_matrix a b "0" 509 | | _ -> etat.matrice_res <- Array.make_matrix a b "0" 510 | (*in let squareu id signe = 511 | match id with 512 | 1 -> chmttaille 1 signe true etat.taille1; 513 | chmttaille 1 signe false etat.taille1; chmtmat 1 etat.taille1 514 | | 2 -> chmttaille 2 signe true etat.taille2; 515 | chmttaille 2 signe false etat.taille2; chmtmat 2 etat.taille2 516 | | _ -> chmttaille 3 signe true etat.taille_res; 517 | chmttaille 3 signe false etat.taille_res; 518 | chmtmat 3 etat.taille_res*) 519 | in let mat1cou = 520 | Bouton.plus 521 | ~onMouseUp:(fun _ -> (*if etat.mode = `Multiplication then 522 | begin*) 523 | chmttaille 1 true true etat.taille1; chmtmat 1 etat.taille1; 524 | (*chmttaille 3 true true etat.taille_res; 525 | chmtmat 3 etat.taille_res;*) 526 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0))) (* 527 | end 528 | else 529 | begin 530 | squareu 1 true; squareu 2 true; squareu 3 true; 531 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0))); 532 | end*) ) ~style:[] () 533 | in let mat1cod = 534 | Bouton.moins ~style:Style.[marginHorizontal 20] 535 | ~onMouseUp:(fun _ -> (*if etat.mode = `Multiplication then 536 | begin*) 537 | chmttaille 1 false true etat.taille1; chmtmat 1 etat.taille1; 538 | (*chmttaille 3 false true etat.taille_res; 539 | chmtmat 3 etat.taille_res;*) 540 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0))) (* 541 | end 542 | else 543 | begin 544 | squareu 1 false; squareu 2 false; squareu 3 false; 545 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0))) 546 | end*)) () 547 | in let boutton_mat1c = 548 | View.createElement 549 | ~style:Style.[flexDirection `Row; flexGrow 2; 550 | marginHorizontal 50] 551 | ~children:[mat1cou; mat1cod] () 552 | in let mat2cou = 553 | Bouton.plus ~style:Style.[marginHorizontal 20] 554 | ~onMouseUp:(fun _ -> 555 | chmttaille 2 true true etat.taille2; chmtmat 2 etat.taille2; 556 | dispatch(MiseAJour (2, 0, 0, etat.matrice2.(0).(0)))) () 557 | in let mat2cod = 558 | Bouton.moins 559 | ~onMouseUp:(fun _ -> 560 | chmttaille 2 false true etat.taille2; chmtmat 2 etat.taille2; 561 | dispatch(MiseAJour (2, 0, 0, etat.matrice2.(0).(0)))) () 562 | in let boutton_mat2c = 563 | View.createElement 564 | ~style:Style.[flexDirection `RowReverse; marginHorizontal 50] 565 | ~children:( 566 | (*if etat.mode = `Multiplication then*) 567 | [mat2cou; mat2cod] 568 | (*else 569 | [mat1cou; mat1cod]*)) () 570 | in let boutton_matc = 571 | View.createElement ~style:Style.[flexDirection`Row] 572 | ~children:[boutton_mat1c; boutton_mat2c] () 573 | in let mat1liu = 574 | Bouton.plus 575 | ~onMouseUp:(fun _ -> (*if etat.mode = `Multiplication then 576 | begin*) 577 | chmttaille 1 true false etat.taille1; chmtmat 1 etat.taille1; 578 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0))) 579 | (*end 580 | else 581 | begin 582 | squareu 1 true; squareu 2 true; squareu 3 true; 583 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0))) 584 | end*)) () 585 | in let mat1lid = Bouton.moins 586 | ~onMouseUp:(fun _ ->(*if etat.mode = `Multiplication then 587 | begin*) 588 | chmttaille 1 false false etat.taille1; chmtmat 1 etat.taille1; 589 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0))) 590 | (*end 591 | else 592 | begin 593 | squareu 1 false; squareu 2 false; squareu 3 false; 594 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0))) 595 | end*)) () 596 | in let boutton_mat1l = 597 | View.createElement ~children:[mat1liu; mat1lid] () 598 | in let mat2liu = 599 | Bouton.plus 600 | ~onMouseUp:(fun _ -> 601 | chmttaille 2 true false etat.taille2; chmtmat 2 etat.taille2; 602 | (*chmttaille 3 true false etat.taille_res; 603 | chmtmat 3 etat.taille_res;*) 604 | dispatch(MiseAJour (2, 0, 0, etat.matrice2.(0).(0)))) () 605 | in let mat2lid = 606 | Bouton.moins 607 | ~onMouseUp:(fun _ -> 608 | chmttaille 2 false false etat.taille2; chmtmat 2 etat.taille2; 609 | (*chmttaille 3 false false etat.taille_res; 610 | chmtmat 3 etat.taille_res;*) 611 | dispatch(MiseAJour (2, 0, 0, etat.matrice2.(0).(0)))) () 612 | in let boutton_mat2l = 613 | View.createElement 614 | ~children:( 615 | (*if etat.mode = `Multiplication then*) 616 | [mat2liu; mat2lid] 617 | (*else 618 | [mat1liu; mat1lid]*)) () 619 | in let children = 620 | View.createElement ~style:Style.[flexDirection `Row] 621 | ~children:[boutton_mat1l; m1; dropdown; m2; boutton_mat2l] () 622 | in hooks, 623 | View.createElement 624 | ~style:Style.[position `Absolute; alignItems `Center; bottom 0; 625 | top 0; left 0; right 0] 626 | ~children:(boutton_matc :: children :: m_res :: children1) ()) 627 | end 628 | 629 | (* 630 | module Equation_old = struct 631 | 632 | let component = React.component "Equation" 633 | 634 | type 'a action = 635 | MiseAJour of int * int * string 636 | | MiseAJourVariable of int * int * string 637 | | Calculer of int 638 | 639 | let reducer action etat = 640 | match action with 641 | MiseAJour (i, j, v) -> 642 | let mat = etat.mat1 643 | in let _ = mat.(i).(j) <- v in 644 | {etat with mat1 = mat} 645 | | MiseAJourVariable (i, j, v) -> 646 | let mat = etat.mat2 647 | in let _ = mat.(i).(j) <- v in 648 | {etat with mat2 = mat} 649 | | Calculer _ -> 650 | let array_map2 f = Array.map (fun e -> Array.map f e) in 651 | let m1 = array_map2 float_of_string etat.mat1 in 652 | let m2 = array_map2 float_of_string etat.mat2 in 653 | let f = (fun _ -> "0" ) in 654 | let res = "" (* f m1 m2 *) in 655 | {etat with res} 656 | 657 | 658 | let createElement ~initialState ~changerVue ~onUpdate = 659 | fun ~children:_ () -> 660 | component (fun hooks -> 661 | let (etat (* nouvel etat *), dispatch, hooks) = 662 | React.Hooks.reducer ~initialState reducer hooks 663 | in let () = onUpdate (`Equation etat) in 664 | let bouton_acc = 665 | Bouton.menu_accueil 666 | ~onMouseUp:(fun _ -> changerVue `VueAccueil) 667 | ~style:Style.[justifyContent `Center; position `Absolute; 668 | bottom 10; left 10] () 669 | in let bouton_calc = 670 | Bouton.calculer ~onMouseUp:(fun _ -> dispatch (Calculer 1)) 671 | ~style:Style.[position `Absolute; bottom 10; right 10] () 672 | in let egal = 673 | Text.createElement ~text:"=" ~style:Style.[fontSize 25; 674 | fontFamily "Roboto-Regular.ttf"; marginVertical 15] ~children:[] () 675 | in let boutton_mat = 676 | Bouton.menu_matrices 677 | ~onMouseUp:(fun _ -> changerVue `VueMatrice) 678 | ~style:Style.[justifyContent `Center; position `Absolute; 679 | bottom 90; left 10] () 680 | in let boutton_cal = 681 | Bouton.menu_calcul ~onMouseUp:(fun _ -> changerVue `VueCalcul) 682 | ~style:Style.[justifyContent `Center; position `Absolute; 683 | bottom 50; left 10] () 684 | in let rec inc_to_list = function 685 | [] -> [] 686 | | e :: l -> (Text.createElement ~text:e ~style:Style.[ 687 | fontSize 25; fontFamily "Roboto-Regular.ttf"; 688 | marginHorizontal 95] 689 | ~children:[] ()) :: inc_to_list l 690 | in let dessiner_matrice (h, w) f = 691 | let input = ref [] in 692 | let row_gen = View.createElement ~style:Style.[flexDirection `Row] in 693 | let () = 694 | for i = pred h downto 0 do 695 | let row = ref [] in 696 | let () = 697 | for j = pred w downto 0 do 698 | row := (f i j) :: !row 699 | done 700 | in input := (row_gen ~children:!row ()) :: !input 701 | done 702 | in (View.createElement ~children:!input) () 703 | in let m1 = 704 | dessiner_matrice (etat.lines, etat.nbr_inc) (fun i j -> 705 | Input.createElement 706 | ~style:Style.[color (Color.rgb 255. 255. 255.); width 100; 707 | margin2 ~horizontal:40 ~vertical:10] 708 | ~value:etat.mat1.(i).(j) 709 | ~placeholder:etat.mat1.(i).(j) 710 | ~onChange:(fun {value; _} -> dispatch(MiseAJour (i, j, value))) 711 | ~children:[] ()) 712 | in let m2 = 713 | dessiner_matrice (etat.lines, 1) (fun i j -> Input.createElement 714 | ~style:Style.[color (Color.rgb 255. 255. 255.); width 100; 715 | margin2 ~horizontal:40 ~vertical:10] 716 | ~value:etat.mat2.(i).(j) 717 | ~placeholder:etat.mat2.(i).(j) 718 | ~onChange:(fun {value; _} -> 719 | dispatch(MiseAJourVariable (i, j, value))) 720 | ~children:[] ()) 721 | in let add_inc () = 722 | let suf = List.nth etat.inconnu (etat.nbr_inc - 1) 723 | in let inc = 1 + int_of_char suf.[0] in 724 | let inc = 725 | let inc = if inc > 122 then inc - 26 else inc in 726 | String.make 1 (char_of_int inc) 727 | in let inc = ( 728 | if (List.exists (fun a -> String.equal a inc) etat.inconnu) then 729 | String.make ((String.length (suf)) + 1) inc.[0] 730 | else 731 | inc) 732 | in let _ = etat.inconnu <- etat.inconnu @ [inc] in 733 | etat.nbr_inc <- etat.nbr_inc + 1 734 | in let minus_inc () = 735 | if etat.nbr_inc > 1 then 736 | let (_ :: l) = List.rev etat.inconnu in 737 | let () = etat.inconnu <- List.rev l in 738 | let () = etat.nbr_inc <- etat.nbr_inc - 1 in 739 | etat.mat1 <- Array.make_matrix 1 etat.nbr_inc "0" 740 | in let boutton_addinc = 741 | Bouton.plus ~style:Style.[marginHorizontal 10] ~onMouseUp:(fun _ -> 742 | add_inc (); 743 | etat.mat1 <- Array.make_matrix etat.lines etat.nbr_inc "0"; 744 | dispatch(MiseAJour (0, 0, etat.mat1.(0).(0)))) () 745 | in let boutton_mininc = 746 | Bouton.moins ~style:Style.[marginHorizontal 10] 747 | ~onMouseUp:(fun _ -> minus_inc (); 748 | dispatch(MiseAJour (0, 0, etat.mat1.(0).(0)))) () 749 | (*in let boutton_addline = 750 | Text.createElement ~text:"+" ~onMouseUp:(fun _ -> 751 | etat.lines <- etat.lines + 1; 752 | etat.mat1 <- Array.make_matrix etat.lines etat.nbr_inc "0"; 753 | etat.mat2 <- Array.make_matrix etat.lines 1 "0"; 754 | dispatch(MiseAJour (1, 0, 0, "0"))) 755 | ~style:Style.[fontSize 25; fontFamily "Roboto-Regular.ttf"; 756 | marginHorizontal 10] 757 | ~children:[] () 758 | in let boutton_minline = 759 | Bouton.moins ~onMouseUp:(fun _ -> 760 | if etat.lines > 1 then 761 | begin 762 | etat.lines <- etat.lines - 1; 763 | etat.mat1 <- Array.make_matrix etat.lines etat.nbr_inc "0"; 764 | etat.mat2 <- Array.make_matrix etat.lines 1 "0"; 765 | dispatch(MiseAJour (1, 0, 0, "0")) 766 | end ) 767 | ~style:Style.[fontSize 25; fontFamily "Roboto-Regular.ttf"; 768 | marginHorizontal 10] 769 | ~children:[] ()*) 770 | in let children = 771 | View.createElement ~children:[boutton_addinc; boutton_mininc] () 772 | in let list_inc = 773 | View.createElement 774 | ~style:Style.[flexDirection `Row; alignSelf `FlexStart] 775 | ~children:(children :: (inc_to_list etat.inconnu)) () 776 | in let children = 777 | View.createElement 778 | ~style:Style.[flexDirection `Row; alignSelf `FlexStart] 779 | ~children:[m1; egal; m2] () 780 | (*in let line = View.createElement 781 | ~style:Style.[flexDirection `Row; alignSelf `FlexStart] 782 | ~children:[boutton_addline; boutton_minline] ()*) 783 | in let resultat = 784 | Text.createElement ~text:etat.res 785 | ~style:Style.[fontSize 25; fontFamily "Roboto-Regular.ttf"] 786 | ~children:[] () 787 | in hooks, 788 | View.createElement 789 | ~style:Style.[position `Absolute; alignItems `Center; bottom 0; 790 | top 0; left 0; right 0] 791 | ~children:[list_inc; children; resultat; 792 | (*line;*) bouton_acc; boutton_cal; boutton_mat; bouton_calc] ()) 793 | end 794 | *) 795 | module Equation = struct 796 | type action = 797 | Editer_inconnu of int * string 798 | | Editer_coefficient of int * int * string 799 | | Ajouter_inconnu 800 | | Enlever_inconnu 801 | | Ajouter_ligne 802 | | Enlever_ligne 803 | | Calculer 804 | 805 | let reducer action etat = 806 | match action with 807 | Editer_inconnu (i, v) -> 808 | let inconnues = etat.inconnues in 809 | let () = inconnues.(i) <- v in 810 | {etat with inconnues} 811 | | Editer_coefficient (j, i, v) -> 812 | let coef = etat.coef in 813 | let () = coef.(j).(i) <- v in 814 | {etat with coef} 815 | | Ajouter_inconnu -> 816 | { 817 | etat with 818 | inconnues = Array.append etat.inconnues [| "" |]; 819 | coef = 820 | Array.map (fun inc -> 821 | let l = Array.append inc [| "" |] in 822 | let () = l.(etat.nbr_inc + 1) <- l.(etat.nbr_inc) in 823 | let () = l.(etat.nbr_inc) <- "" in 824 | l) etat.coef; 825 | nbr_inc = etat.nbr_inc + 1; 826 | } 827 | | Enlever_inconnu -> 828 | if etat.nbr_inc > 1 then 829 | { 830 | etat with 831 | inconnues = Array.sub etat.inconnues 0 (etat.nbr_inc - 1); 832 | coef = 833 | Array.map (fun inc -> 834 | let l = Array.sub inc 0 etat.nbr_inc in 835 | let () = l.(etat.nbr_inc - 1) <- inc.(etat.nbr_inc) in 836 | l) etat.coef; 837 | nbr_inc = etat.nbr_inc - 1; 838 | } 839 | else 840 | etat 841 | | Ajouter_ligne -> 842 | { 843 | etat with 844 | coef = Array.append etat.coef [| Array.make (etat.nbr_inc + 1) "" |]; 845 | nbr_ligne = etat.nbr_ligne + 1; 846 | } 847 | | Enlever_ligne -> 848 | if etat.nbr_ligne > 1 then 849 | { 850 | etat with 851 | coef = Array.sub etat.coef 0 (etat.nbr_ligne - 1); 852 | nbr_ligne = etat.nbr_ligne - 1; 853 | } 854 | else 855 | etat 856 | | Calculer -> 857 | let open Noyau.Moteur.Expr_matrix in 858 | let e = 859 | if Array.for_all ((<>) "") etat.inconnues then 860 | let coef = 861 | Array.map (Array.map (fun e -> if e = "" then "0" else e)) etat.coef 862 | in try 863 | solveur coef etat.nbr_inc etat.nbr_ligne etat.inconnues 864 | with Failure s -> Erreur s 865 | else 866 | Erreur (I18n.champ_variable_vide ()) 867 | in { 868 | etat with 869 | resultat = Some e; 870 | } 871 | 872 | let component = React.component "Equation" 873 | 874 | let createElement ~initialState ~changerVue ~onUpdate = 875 | fun ~children:_ () -> 876 | component (fun hooks -> 877 | let (etat (* nouvel etat *), dispatch, hooks) = 878 | React.Hooks.reducer ~initialState reducer hooks 879 | in let () = onUpdate (`Equation etat) in 880 | let children = 881 | Array.mapi (fun i value -> 882 | Input.createElement ~value 883 | ~style:Style.[color (Color.hex "#fff"); width 100; 884 | marginHorizontal 20] 885 | ~onChange:(fun {value; _} -> dispatch(Editer_inconnu(i, value))) 886 | ~children:[] ()) etat.inconnues 887 | in let children = Array.to_list children in 888 | let ajouter_inconnu = 889 | Bouton.plus 890 | ~style:Style.[marginHorizontal 20] 891 | ~onMouseUp:(fun _ -> dispatch Ajouter_inconnu) () 892 | in let enlever_inconnu = 893 | Bouton.moins 894 | ~style:Style.[marginHorizontal 20] 895 | ~onMouseUp:(fun _ -> dispatch Enlever_inconnu) () 896 | in let egal = 897 | Text.createElement ~text:"=" 898 | ~style:Style.[fontSize 25; fontFamily "Roboto-Regular.ttf"; 899 | marginHorizontal 10] 900 | ~children:[] () 901 | in let dessiner_ligne_coef len j arr = 902 | let res = 903 | Input.createElement ~value:arr.(len) ~placeholder:"Résultat" 904 | ~style:Style.[color (Color.hex "#fff"); width 100; 905 | marginHorizontal 20] 906 | ~onChange:(fun {value; _} -> 907 | dispatch(Editer_coefficient(j, len, value))) 908 | ~children:[] () 909 | in let ret = ref [egal; res] in 910 | let () = 911 | for i = pred len downto 0 do 912 | let e = 913 | Input.createElement ~value:arr.(i) 914 | ~placeholder:etat.inconnues.(i) 915 | ~style:Style.[color (Color.hex "#fff"); width 100; 916 | marginHorizontal 20] 917 | ~onChange:(fun {value; _} -> 918 | dispatch(Editer_coefficient(j, i, value))) 919 | ~children:[] () 920 | in ret := e :: !ret 921 | done 922 | in 923 | View.createElement ~style:Style.[flexDirection `Row] ~children:!ret () 924 | in let coef = Array.mapi (dessiner_ligne_coef etat.nbr_inc) etat.coef in 925 | let coef = 926 | View.createElement ~style:Style.[flexDirection `Column] 927 | ~children:(Array.to_list coef) () 928 | in let inc = 929 | View.createElement ~style:Style.[flexDirection `Row] 930 | ~children:(children @ [ajouter_inconnu; enlever_inconnu]) () 931 | in let ajouter_ligne = 932 | Bouton.plus 933 | ~style:Style.[marginHorizontal 20] 934 | ~onMouseUp:(fun _ -> dispatch Ajouter_ligne) () 935 | in let enlever_ligne = 936 | Bouton.moins 937 | ~style:Style.[marginHorizontal 20] 938 | ~onMouseUp:(fun _ -> dispatch Enlever_ligne) () 939 | in let modifier_ligne = 940 | View.createElement ~style:Style.[flexDirection `Row] 941 | ~children:[ajouter_ligne; enlever_ligne] () 942 | in let bouton_acc = 943 | Bouton.menu_accueil 944 | ~onMouseUp:(fun _ -> changerVue `VueAccueil) 945 | ~style:Style.[justifyContent `Center; position `Absolute; 946 | bottom 10; left 10] () 947 | in let bouton_calc = 948 | Bouton.calculer ~onMouseUp:(fun _ -> dispatch Calculer) 949 | ~style:Style.[position `Absolute; bottom 10; right 10] () 950 | in let boutton_mat = 951 | Bouton.menu_matrices 952 | ~onMouseUp:(fun _ -> changerVue `VueMatrice) 953 | ~style:Style.[justifyContent `Center; position `Absolute; 954 | bottom 90; left 10] () 955 | in let boutton_cal = 956 | Bouton.menu_calcul ~onMouseUp:(fun _ -> changerVue `VueCalcul) 957 | ~style:Style.[justifyContent `Center; position `Absolute; 958 | bottom 50; left 10] () 959 | in let resultat = 960 | let open Noyau.Moteur.Expr_matrix in 961 | match etat.resultat with 962 | None -> None 963 | | Some (Erreur text) -> 964 | let style = 965 | Style.[color (Color.hex "#f00"); fontSize 25; 966 | fontFamily "Roboto-Regular.ttf"] 967 | in Some (Text.createElement ~text ~style ~children:[] ()) 968 | | Some (Solution_systeme l) -> 969 | let style = Style.[fontSize 25; fontFamily "Roboto-Regular.ttf"] in 970 | let text_gen (variable, valeur) = 971 | let valeur = Noyau.Moteur.texte_depuis_expr valeur in 972 | let text = variable ^ " = " ^ valeur in 973 | Text.createElement ~text ~style ~children:[] () 974 | in let children = List.map text_gen l in 975 | Some (View.createElement ~children ()) 976 | in let children = [boutton_cal; boutton_mat; bouton_calc] in 977 | let children = 978 | match resultat with 979 | None -> children 980 | | Some e -> e :: children 981 | in let children = 982 | inc :: coef :: modifier_ligne :: bouton_acc :: children 983 | in hooks, 984 | View.createElement 985 | ~style:Style.[position `Absolute; bottom 0; 986 | top 0; left 0; right 0; flexDirection `Column] 987 | ~children () 988 | ) 989 | end 990 | 991 | module Accueil = struct 992 | let component = React.component "Accueil" 993 | 994 | type action = 995 | ChangerLangue of I18n.lang 996 | 997 | let reducer action _ (* etat *) = 998 | match action with 999 | ChangerLangue lang -> 1000 | let () = I18n.definir_lang lang in 1001 | {lang} 1002 | 1003 | let createElement ~initialState ~changerVue ~onUpdate = 1004 | fun ~children:_ () -> 1005 | component (fun hooks -> 1006 | let (etat (* nouvel etat *), dispatch, hooks) = 1007 | React.Hooks.reducer ~initialState reducer hooks 1008 | in let () = onUpdate (`Accueil etat) in 1009 | let containerStyle = 1010 | Style.[ 1011 | position `Absolute; 1012 | justifyContent `Center; 1013 | alignItems `Center; 1014 | bottom 0; 1015 | top 0; 1016 | left 0; 1017 | right 0 1018 | ] 1019 | in let translate1, hooks = 1020 | Hooks.animation (Animated.floatValue (-250.)) 1021 | { 1022 | toValue = 20.; 1023 | duration = Seconds 2.5; 1024 | delay = Seconds 0.; 1025 | repeat = false; 1026 | easing = Easing.linear; 1027 | direction = `Normal; 1028 | } hooks 1029 | in let translate2, hooks = 1030 | Hooks.animation (Animated.floatValue 150.) 1031 | { 1032 | toValue = -90.; 1033 | duration = Seconds 5.; 1034 | delay = Seconds 2.5; 1035 | repeat = false; 1036 | easing = Easing.linear; 1037 | direction = `Normal 1038 | } hooks 1039 | in let scale, hooks = 1040 | Hooks.animation (Animated.floatValue 0.) 1041 | { 1042 | toValue = 1.; 1043 | duration = Seconds 5.; 1044 | delay = Seconds 2.5; 1045 | repeat = false; 1046 | easing = Easing.linear; 1047 | direction = `Normal 1048 | } hooks 1049 | in let imageStyle1 = 1050 | Style.[ 1051 | bottom 0; 1052 | top 0; 1053 | left 0; 1054 | right 0; 1055 | width 200; 1056 | height 200; 1057 | transform [Transform.TranslateX translate1] 1058 | ] 1059 | in let imageStyle2 = 1060 | Style.[ 1061 | top 0; 1062 | bottom 0; 1063 | right 0; 1064 | left 0; 1065 | width 75; 1066 | height 75; 1067 | transform [ 1068 | Transform.TranslateY translate2; 1069 | Transform.ScaleX scale; 1070 | Transform.ScaleY scale; 1071 | ]; 1072 | ] 1073 | in let bouton_cal = 1074 | Bouton.menu_calcul ~onMouseUp:(fun _ -> changerVue `VueCalcul) 1075 | ~style:Style.[justifyContent `Center; color (Color.rgb 255. 120. 10.); 1076 | position `Absolute; bottom 10; left 10] () 1077 | in let bouton_mat = 1078 | Bouton.menu_matrices ~onMouseUp:(fun _ -> changerVue `VueMatrice) 1079 | ~style:Style.[justifyContent `Center; color (Color.rgb 255. 120. 10.); 1080 | position `Absolute; right 10; bottom 10] () 1081 | in let bouton_equa = 1082 | Bouton.menu_equations ~onMouseUp:(fun _ -> changerVue `VueEquation) 1083 | ~style:Style.[ 1084 | justifyContent `Center; color (Color.rgb 255. 120. 10.); 1085 | position `Absolute; bottom 50; right 10] () 1086 | in let bouton_langue = 1087 | let src = "drapeau_" ^ (I18n.obtenir_lang ()) ^ ".png" 1088 | and style = 1089 | Style.[position `Absolute; top 10; right 10; height 25; width 38] 1090 | and onMouseUp _ = 1091 | let nouvelle_langue = 1092 | match I18n.obtenir_lang () with 1093 | "fr" -> I18n.Anglais 1094 | | "eng" -> I18n.Francais 1095 | | _ -> failwith "langue non reconnu" 1096 | in dispatch (ChangerLangue nouvelle_langue) 1097 | in Image.createElement ~src ~style ~onMouseUp ~children:[] () 1098 | in hooks, 1099 | View.createElement ~style:containerStyle 1100 | ~children:[bouton_langue; 1101 | Image.createElement 1102 | ~onMouseUp:(fun _ -> changerVue `VueBonus) ~src:"pi.png" 1103 | ~style:imageStyle2 ~children:[] (); 1104 | Image.createElement ~src:"camel.png" ~style:imageStyle1 1105 | ~children:[] (); 1106 | bouton_cal; bouton_equa; bouton_mat; 1107 | ] ()) 1108 | end 1109 | 1110 | module Application = struct 1111 | let component = React.component "Application" 1112 | 1113 | type action = 1114 | ChangerVue of vue 1115 | 1116 | let sauvegarde = 1117 | ref { 1118 | equation = 1119 | { 1120 | (* 1121 | inconnu = ["x"]; 1122 | nbr_inc = 1; 1123 | lines = 1; 1124 | mat1 = Array.make_matrix 1 1 "0"; 1125 | mat2 = Array.make_matrix 1 1 "0"; 1126 | res = ""; 1127 | *) 1128 | inconnues = Array.make 1 ""; 1129 | nbr_inc = 1; 1130 | coef = Array.make_matrix 1 2 ""; 1131 | nbr_ligne = 1; 1132 | resultat = None; 1133 | }; 1134 | calcul = { 1135 | valeur = ""; 1136 | res = " "(* trick to be displayed *); 1137 | liste_historique = !Commune.liste_historique; 1138 | (* TODO: avoid this double list *) 1139 | context = Commune.init_context 1140 | }; 1141 | historique = { 1142 | liste = []; 1143 | }; 1144 | matrice = { 1145 | mode = `Addition; 1146 | matrice1 = Array.make_matrix 2 2 "0"; 1147 | matrice2 = Array.make_matrix 2 2 "0"; 1148 | matrice_res = Array.make_matrix 2 2 "0"; 1149 | taille1 = (2, 2); 1150 | taille2 = (2, 2); 1151 | taille_res = (2, 2); 1152 | message = ""; 1153 | }; 1154 | accueil = { 1155 | lang = I18n.Francais; 1156 | }; 1157 | } 1158 | 1159 | let reducer action _ (* etat *) = 1160 | match action with 1161 | ChangerVue v -> {(* etat with *) vue_courante = v} 1162 | 1163 | let miseAJour = function 1164 | `Calcul e -> 1165 | let () = sauvegarde := {!sauvegarde with calcul = e} in 1166 | !sauvegarde.historique.liste <- e.liste_historique 1167 | | `Matrice e -> sauvegarde := {!sauvegarde with matrice = e} 1168 | | `Accueil e -> sauvegarde := {!sauvegarde with accueil = e} 1169 | | `Equation e -> sauvegarde := {!sauvegarde with equation = e} 1170 | 1171 | let createElement = 1172 | fun ~children:_ () -> 1173 | component(fun hooks -> 1174 | let {vue_courante}, dispatch, hooks = 1175 | React.Hooks.reducer ~initialState:{vue_courante = `VueAccueil} 1176 | reducer hooks 1177 | in let choisir_vue = function 1178 | `VueCalcul -> Calcul.createElement 1179 | ~initialState:(!sauvegarde.calcul) 1180 | | `VueHistorique -> Historique.createElement 1181 | !sauvegarde.calcul.liste_historique 1182 | | `VueMatrice -> Matrice.createElement 1183 | ~initialState:(!sauvegarde.matrice) 1184 | | `VueAccueil -> Accueil.createElement 1185 | ~initialState:(!sauvegarde.accueil) 1186 | | `VueEquation -> Equation.createElement 1187 | ~initialState:(!sauvegarde.equation) 1188 | | `VueBonus -> VueBonus.createElement 1189 | in hooks, 1190 | (choisir_vue vue_courante) 1191 | ~changerVue:(fun v -> dispatch (ChangerVue v)) 1192 | ~onUpdate:miseAJour 1193 | ~children:[] ()) 1194 | end 1195 | 1196 | (* 1197 | let init app = 1198 | let win = App.createWindow app "OCalc" in 1199 | Input.createElement ~style:Style.[top (100); left (300); position `Absolute] 1200 | ~children:[] () |> 1201 | UI.start win |> ignore 1202 | 1203 | let init app = 1204 | let win = App.createWindow app "OCalc" in 1205 | Input.createElement ~style:Style.[] ~children:[] () |> 1206 | UI.start win |> ignore 1207 | 1208 | let init app = 1209 | let win = App.createWindow app "OCalc" in 1210 | let op: Dropdown.items = [ 1211 | {value = "+"; label = "+";}; 1212 | {value = "-"; label = "-";}; 1213 | {value = "*"; label = "*";}; 1214 | ] in Dropdown.createElement ~items:op ~onItemSelected:(fun _ -> ()) 1215 | ~children:[] () |> 1216 | UI.start win |> ignore 1217 | *) 1218 | 1219 | let init app = 1220 | let maximized = Environment.webGL in 1221 | let dimensions = Monitor.getPrimaryMonitor () |> Monitor.getSize in 1222 | let windowWidth = dimensions.width / 2 in 1223 | let windowHeight = dimensions.height / 2 in 1224 | let options_fen = 1225 | WindowCreateOptions.create ~width:windowWidth ~height:windowHeight 1226 | ~maximized ~icon:(Some "logo.png") ~backgroundColor:bgColor () 1227 | in let fen = App.createWindow ~createOptions:options_fen app "OCalc" in 1228 | let () = 1229 | if not Environment.webGL then 1230 | let xPosition = (dimensions.width - windowWidth) / 2 in 1231 | let yPosition = (dimensions.height - windowHeight) / 2 in 1232 | Window.setPos fen xPosition yPosition 1233 | in let afficher () = Application.createElement ~children:[] () in 1234 | UI.start fen (afficher ()) (afficher ()) 1235 | 1236 | let _ = App.start init 1237 | -------------------------------------------------------------------------------- /src/interfaces/topGui.mli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topGui.mli -------------------------------------------------------------------------------- /src/interfaces/topServeur.ml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topServeur.ml -------------------------------------------------------------------------------- /src/interfaces/topServeur.mli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topServeur.mli -------------------------------------------------------------------------------- /src/interfaces/topTest.ml: -------------------------------------------------------------------------------- 1 | open Noyau 2 | open Modules 3 | open Type 4 | open Utils 5 | open Lexer 6 | open Parser 7 | open GrandEntier_on 8 | 9 | let mechant = false 10 | 11 | (*numéro de *) 12 | let (test_total, test_valide_total, suite, test, test_valide) = ref 0, ref 0, ref 0, ref 0, ref 0 13 | 14 | let test_unitaire_assert a b = 15 | let () = 16 | if a <> b then 17 | Printf.printf "Le test #%d n'as pas produit la valeure attendue\n" !test 18 | else 19 | let () = test_valide := !test_valide + 1 in 20 | test_valide_total := !test_valide_total + 1 21 | in let () = test_total := !test_total + 1 in 22 | test := !test + 1 23 | 24 | let init_suite name = 25 | let () = Printf.printf "\n\n\x1b[4mSuite #%d\x1b[0m: %s\n" !suite name in 26 | suite := !suite + 1 27 | 28 | let fin_suite () = 29 | let () = 30 | Printf.printf "%3.2f %% de tests passés pour cette suite\n" (100. *. float_of_int !test_valide /. float_of_int !test) in 31 | let () = test_valide := 0 in 32 | test := 0 33 | 34 | let reinit_test_suite () = 35 | let () = test_total := 0 in 36 | let () = test_valide_total := 0 in 37 | let () = suite := 0 in 38 | let () = test := 0 in 39 | test_valide := 0 40 | 41 | 42 | let () = init_suite "est_entier" 43 | 44 | let () = test_unitaire_assert (est_entier "123" 10) true 45 | let () = test_unitaire_assert (est_entier "-123" 10) true 46 | let () = test_unitaire_assert (est_entier "+123" 10) true 47 | let () = test_unitaire_assert (est_entier "007" 10) true 48 | let () = test_unitaire_assert (est_entier "0" 10) true 49 | let () = test_unitaire_assert (est_entier "" 10) false 50 | let () = test_unitaire_assert (est_entier "123a" 10) false 51 | let () = test_unitaire_assert (est_entier "_123" 10) false 52 | let () = test_unitaire_assert (est_entier "1u23" 10) false 53 | 54 | let () = fin_suite () 55 | 56 | let () = init_suite "est_entier_base" 57 | 58 | let () = test_unitaire_assert (est_entier_base "12310") false 59 | let () = test_unitaire_assert (est_entier_base "123_10") true 60 | let () = test_unitaire_assert (est_entier_base "(123)_10") true 61 | let () = test_unitaire_assert (est_entier_base "123)_10") false 62 | let () = test_unitaire_assert (est_entier_base "(123_10") false 63 | let () = test_unitaire_assert (est_entier_base "_123_10") false 64 | let () = test_unitaire_assert (est_entier_base "g123_10") false 65 | let () = test_unitaire_assert (est_entier_base "123u_10") false 66 | let () = test_unitaire_assert (est_entier_base "12b3_10") false 67 | let () = test_unitaire_assert (est_entier_base "à12b3_10") false 68 | 69 | let () = fin_suite () 70 | 71 | let () = init_suite "est_variable" 72 | 73 | let () = test_unitaire_assert (est_variable "a") true 74 | let () = test_unitaire_assert (est_variable "x") true 75 | let () = test_unitaire_assert (est_variable "x'") true 76 | let () = test_unitaire_assert (est_variable "pi") true 77 | let () = test_unitaire_assert (est_variable "pi2") true 78 | let () = test_unitaire_assert (est_variable "pi-2") false 79 | let () = test_unitaire_assert (est_variable "pi_t") true 80 | let () = test_unitaire_assert (est_variable "pi_2") true (*Va être confondu avec est_entier_base ?*) 81 | let () = test_unitaire_assert (est_variable "a_") false (*Termine par un _ *) 82 | let () = test_unitaire_assert (est_variable "Ax") false (*Constante qui commence par une maj ? Matrice ?*) 83 | let () = test_unitaire_assert (est_variable "x'''''") true (*apostrophe ok*) 84 | let () = test_unitaire_assert (est_variable "x'''''123") true 85 | let () = test_unitaire_assert (est_variable "xZE") true (*Majuscule pas à la première ok*) 86 | 87 | let () = fin_suite () 88 | 89 | let () = init_suite "contient_texte" 90 | 91 | let () = test_unitaire_assert (contient_texte "123" ['+']) false 92 | let () = test_unitaire_assert (contient_texte "123+456" ['+']) true 93 | let () = test_unitaire_assert (contient_texte "123+456" ['-']) false 94 | let () = test_unitaire_assert (contient_texte "123-456+789" ['-'; '+']) true 95 | 96 | let () = fin_suite () 97 | 98 | let () = init_suite "couper_texte" 99 | 100 | let () = test_unitaire_assert (couper_texte "123" ['+']) ["123"] 101 | let () = test_unitaire_assert (couper_texte "123+456" ['+']) ["123"; "+"; "456"] 102 | let () = test_unitaire_assert (couper_texte "123+456" ['-']) ["123+456"] 103 | let () = test_unitaire_assert (couper_texte "123-456+789" ['-'; '+']) ["123"; "-"; "456"; "+"; "789"] 104 | 105 | let () = fin_suite () 106 | 107 | let () = init_suite "texte_de_expr" 108 | 109 | let () = test_unitaire_assert (texte_de_expr (Variable "x")) "x" 110 | let () = test_unitaire_assert (texte_de_expr (Operation ("+", [Variable "x"]))) "x" 111 | let () = test_unitaire_assert (texte_de_expr (Operation ("+", [Variable "x"; Variable "y"]))) "(x+y)" 112 | let () = test_unitaire_assert (texte_de_expr (Operation ("*", [Operation ("+", [Variable "x"; Variable "y"])]))) "(x+y)" 113 | let () = test_unitaire_assert (texte_de_expr (Operation ("*", [Variable "z"; Operation ("+", [Variable "x"; Variable "y"])]))) "(z*(x+y))" 114 | 115 | let () = fin_suite () 116 | 117 | let () = init_suite "expr_de_texte_etend" 118 | 119 | let parse = [] 120 | (* this is an old time 121 | let () = test_unitaire_assert (expr_de_texte_etend parse "3445") (Textenonvalide "3445") in 122 | let () = test_unitaire_assert (expr_de_texte_etend parse "x") (Textenonvalide "x") in 123 | *) 124 | let parse = 125 | let parse = (est_multiplication_division, variable_de_multiplication_division) :: parse in 126 | let parse = (est_addition_soustraction, variable_de_addition_soustraction) :: parse in 127 | let parse = (est_variable, variable_de_texte) :: parse in 128 | let parse = (est_entier10, variable_de_entier) :: parse in 129 | parse 130 | let () = test_unitaire_assert (expr_de_texte_etend parse "3445") (Entier (ge "3445")) 131 | let () = test_unitaire_assert (expr_de_texte_etend parse "+3445") (Entier (ge "3445")) 132 | let () = test_unitaire_assert (expr_de_texte_etend parse "-3445") (Entier (ge "-3445")) 133 | let () = test_unitaire_assert (expr_de_texte_etend parse "x+3445") (Operation ("+", [Variable "x"; Entier (ge "3445")])) 134 | let () = test_unitaire_assert (expr_de_texte_etend parse "x+3445-y") (Operation ("+", [Variable "x"; Entier (ge "3445"); Neg (Variable "y")])) 135 | let () = test_unitaire_assert (expr_de_texte_etend parse "-123+x-y") (Operation ("+", [Entier (ge "-123"); Variable "x"; Neg (Variable "y")])) 136 | let () = test_unitaire_assert (expr_de_texte_etend parse "-z") (Neg (Variable "z")) 137 | let () = test_unitaire_assert (expr_de_texte_etend parse "+alexandre") (Variable "alexandre") 138 | let () = test_unitaire_assert (expr_de_texte_etend parse "x") (Variable ("x")) 139 | let () = test_unitaire_assert (expr_de_texte_etend parse "1+2*3") (Operation ("+", [Entier (ge "1"); Operation ("*", [Entier (ge "2"); Entier (ge "3")])])) 140 | 141 | let () = fin_suite () 142 | 143 | (** test sur les Grand Entiers *) 144 | let grandentier_depuis_texte a = Obj.magic grandentier_depuis_texte a 145 | let texte_depuis_grandentier a = Obj.magic texte_depuis_grandentier a 146 | let a = grandentier_depuis_texte "-5" 147 | let b = grandentier_depuis_texte "-50" 148 | let c = grandentier_depuis_texte "5" 149 | let d = grandentier_depuis_texte "0" 150 | let e = grandentier_depuis_texte "-0" 151 | let _ = grandentier_depuis_texte "-45" 152 | 153 | let () = init_suite "est_negatif" 154 | 155 | let () = test_unitaire_assert (est_negatif a) true 156 | let () = test_unitaire_assert (est_negatif b) true 157 | let () = test_unitaire_assert (est_negatif c) false 158 | let () = test_unitaire_assert (est_negatif d) false 159 | let () = test_unitaire_assert (est_negatif e) false 160 | 161 | let () = fin_suite () 162 | 163 | let () = init_suite "comparer" 164 | 165 | let () = test_unitaire_assert (comparer a b) ~-1 166 | let () = test_unitaire_assert (comparer b a) 1 167 | let () = test_unitaire_assert (comparer c a) ~-1 168 | let () = test_unitaire_assert (comparer a c) 1 169 | let () = test_unitaire_assert (comparer a d) 1 170 | let () = test_unitaire_assert (comparer d e) 0 171 | 172 | let () = fin_suite () 173 | 174 | let () = init_suite "additioner" 175 | 176 | let () = test_unitaire_assert (additioner a b) (grandentier_depuis_texte "-55") 177 | let () = test_unitaire_assert (additioner b a) (grandentier_depuis_texte "-55") 178 | let () = test_unitaire_assert (additioner c a) d 179 | let () = test_unitaire_assert (additioner a c) d 180 | let () = if mechant then 181 | test_unitaire_assert (additioner a d) a 182 | let () = test_unitaire_assert (additioner d e) d 183 | 184 | let () = fin_suite () 185 | 186 | let () = init_suite "soustraire" 187 | 188 | let () = if mechant then 189 | test_unitaire_assert (soustraire a b) (grandentier_depuis_texte "45") 190 | let () = if mechant then 191 | test_unitaire_assert (soustraire b a) (grandentier_depuis_texte "-45") 192 | let () = test_unitaire_assert (soustraire c a) (grandentier_depuis_texte "10") 193 | let () = test_unitaire_assert (soustraire a c) (grandentier_depuis_texte "-10") 194 | let () = test_unitaire_assert (soustraire a d) a 195 | let () = test_unitaire_assert (soustraire d e) d 196 | let () = test_unitaire_assert (soustraire a a) d 197 | 198 | let () = fin_suite () 199 | 200 | let () = init_suite "multiplier" 201 | 202 | let () = test_unitaire_assert (multiplier a b) (grandentier_depuis_texte "250") 203 | let () = test_unitaire_assert (multiplier b a) (grandentier_depuis_texte "250") 204 | let () = test_unitaire_assert (multiplier c a) (grandentier_depuis_texte "-25") 205 | let () = test_unitaire_assert (multiplier a c) (grandentier_depuis_texte "-25") 206 | let () = test_unitaire_assert (multiplier a d) d 207 | let () = test_unitaire_assert (multiplier d e) d 208 | let () = test_unitaire_assert (multiplier a a) (grandentier_depuis_texte "25") 209 | 210 | let () = fin_suite () 211 | 212 | let () = init_suite "grandentier_depuis_texte" 213 | 214 | let () = test_unitaire_assert (grandentier_depuis_texte "3445") (false, [5; 4; 4; 3]) 215 | let () = test_unitaire_assert (grandentier_depuis_texte "-3445") (true, [5; 4; 4; 3]) 216 | let () = test_unitaire_assert (grandentier_depuis_texte "0") (false, []) 217 | let () = test_unitaire_assert (grandentier_depuis_texte "-0") (false, []) 218 | 219 | let () = fin_suite () 220 | 221 | let () = init_suite "texte_depuis_grandentier" 222 | 223 | let () = test_unitaire_assert (texte_depuis_grandentier (false, [5; 4; 4; 3])) "3445" 224 | let () = test_unitaire_assert (texte_depuis_grandentier (true, [5; 4; 4; 3])) "-3445" 225 | let () = test_unitaire_assert (texte_depuis_grandentier (false, [])) "0" 226 | let () = test_unitaire_assert (texte_depuis_grandentier (true, [])) "0" 227 | 228 | let () = fin_suite () 229 | 230 | let () = Printf.printf "\n\n%3.2f %% des tests global passés\n" (100. *. float_of_int !test_valide_total /. float_of_int !test_total) 231 | let () = reinit_test_suite () 232 | -------------------------------------------------------------------------------- /src/interfaces/topTest.mli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topTest.mli -------------------------------------------------------------------------------- /src/modules/I18n.ml: -------------------------------------------------------------------------------- 1 | type lang = 2 | Francais 3 | | Anglais 4 | 5 | let lang = ref Francais 6 | 7 | let definir_lang l = 8 | lang := l 9 | 10 | let obtenir_lang () = 11 | match !lang with 12 | Francais -> "fr" 13 | | Anglais -> "eng" 14 | 15 | let division_par_zero () = 16 | match !lang with 17 | Francais -> "Division par zéro à eu lieu" 18 | | Anglais -> "Division by zero occur" 19 | 20 | let separateur_unite () = 21 | match !lang with 22 | Francais -> "," 23 | | Anglais -> "." 24 | 25 | let impossible_convertir_pas_affectable () = 26 | match !lang with 27 | Francais -> "Impossible de convertir Pas_affectable" 28 | | Anglais -> "We can't convert Pas_affectable" 29 | 30 | let impossible_convertir_vide () = 31 | match !lang with 32 | Francais -> "Impossible de convertir Vide" 33 | | Anglais -> "We can't convert Vide" 34 | 35 | let matrice_mauvaise_dimension () = 36 | match !lang with 37 | Francais -> "matrice de mauvaise dimension" 38 | | Anglais -> "Matrix don't have right size" 39 | 40 | let fichier_inexistant fichier = 41 | match !lang with 42 | Francais -> fichier ^ " n'existe pas" 43 | | Anglais -> fichier ^ " doesn't exist" 44 | 45 | let fichier_pas_math fichier = 46 | match !lang with 47 | Francais -> fichier ^ " n'as pas l'extension .math" 48 | | Anglais -> fichier ^ " isn't a .math file" 49 | 50 | let bienvenue () = 51 | match !lang with 52 | Francais -> "Bienvenue chez OCalc" 53 | | Anglais -> "Walcome at OCalc" 54 | 55 | let sortir_msg () = 56 | match !lang with 57 | Francais -> "tapez sortir ou quitter pour quitter" 58 | | Anglais -> "type exit or quit to quit" 59 | 60 | let sortir_1 () = 61 | match !lang with 62 | Francais -> "sortir" 63 | | Anglais -> "exit" 64 | 65 | let sortir_2 () = 66 | match !lang with 67 | Francais -> "quitter" 68 | | Anglais -> "quit" 69 | 70 | let mauvais_parenthesage () = 71 | match !lang with 72 | Francais -> "Vérifiez vos parenthèses !!!" 73 | | Anglais -> "Some parenthesis mismatch !!!" 74 | 75 | let erreur_de_syntaxe () = 76 | match !lang with 77 | Francais -> "Erreur de syntaxe" 78 | | Anglais -> "Syntax error" 79 | 80 | let definition_valide () = 81 | match !lang with 82 | Francais -> "Définition valide" 83 | | Anglais -> "Definition valid" 84 | 85 | let retour () = 86 | match !lang with 87 | Francais -> "Retour" 88 | | Anglais -> "Back" 89 | 90 | let calculer () = 91 | match !lang with 92 | Francais -> "Calculer" 93 | | Anglais -> "Compute" 94 | 95 | let effacer () = 96 | match !lang with 97 | Francais -> "Effacer" 98 | | Anglais -> "Erase" 99 | 100 | let menu_historique () = 101 | match !lang with 102 | Francais -> "Historique" 103 | | Anglais -> "History" 104 | 105 | let menu_accueil () = 106 | match !lang with 107 | Francais -> "Accueil" 108 | | Anglais -> "Home" 109 | 110 | let menu_calcul () = 111 | match !lang with 112 | Francais -> "Calcul" 113 | | Anglais -> "Calculus" 114 | 115 | let menu_matrices () = 116 | match !lang with 117 | Francais -> "Matrices" 118 | | Anglais -> "Matrix" 119 | 120 | let menu_equations () = 121 | match !lang with 122 | Francais -> "Équations" 123 | | Anglais -> "Solver" 124 | 125 | let contractition_presente () = 126 | match !lang with 127 | Francais -> "Il y a une contradiction présente" 128 | | Anglais -> "Solution doesn't exist" 129 | 130 | let definition_non_autorise () = 131 | match !lang with 132 | Francais -> "Vous ne pouvez pas définir de variable ici" 133 | | Anglais -> "You can't define value here" 134 | 135 | let champ_variable_vide () = 136 | match !lang with 137 | Francais -> "Vous devez donner un nom a toutes les inconnues" 138 | | Anglais -> "You must give a name for all unknown" 139 | -------------------------------------------------------------------------------- /src/modules/I18n.mli: -------------------------------------------------------------------------------- 1 | type lang = 2 | Francais 3 | | Anglais 4 | 5 | val definir_lang : lang -> unit 6 | 7 | val obtenir_lang : unit -> string 8 | 9 | val division_par_zero : unit -> string 10 | 11 | val separateur_unite : unit -> string 12 | 13 | val impossible_convertir_pas_affectable : unit -> string 14 | 15 | val impossible_convertir_vide : unit -> string 16 | 17 | val matrice_mauvaise_dimension : unit -> string 18 | 19 | val fichier_inexistant : string -> string 20 | 21 | val fichier_pas_math : string -> string 22 | 23 | val bienvenue : unit -> string 24 | 25 | val sortir_msg : unit -> string 26 | 27 | val sortir_1 : unit -> string 28 | 29 | val sortir_2 : unit -> string 30 | 31 | val mauvais_parenthesage : unit -> string 32 | 33 | val erreur_de_syntaxe : unit -> string 34 | 35 | val definition_valide : unit -> string 36 | 37 | val retour : unit -> string 38 | 39 | val calculer : unit -> string 40 | 41 | val effacer : unit -> string 42 | 43 | val menu_historique : unit -> string 44 | 45 | val menu_accueil : unit -> string 46 | 47 | val menu_calcul : unit -> string 48 | 49 | val menu_matrices : unit -> string 50 | 51 | val menu_equations : unit -> string 52 | 53 | val contractition_presente : unit -> string 54 | 55 | val definition_non_autorise : unit -> string 56 | 57 | val champ_variable_vide : unit -> string 58 | -------------------------------------------------------------------------------- /src/modules/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name Modules) 3 | (wrapped true) 4 | (modules GrandNum_on GrandEntier_on GrandReel_on GrandRationnel_on Matrix) 5 | (libraries I18n)) 6 | 7 | (library 8 | (name I18n) 9 | (wrapped true) 10 | (modules I18n)) 11 | -------------------------------------------------------------------------------- /src/modules/grandEntier_off.ml: -------------------------------------------------------------------------------- 1 | type grandentier = int 2 | (** grandentier est un tuple [(signe négatif, \[unité, dizaine, centaine, ...\])] 3 | [-123] correspond à [(true, \[3; 2; 1\])] *) 4 | 5 | let zero = 0 6 | 7 | let unit = 1 8 | 9 | let est_negatif x = x < 0 10 | (** renvoie [grandentier < 0] *) 11 | 12 | let neg = (~-) 13 | (** renvoie l'oposé *) 14 | 15 | let comparer ga gb = 16 | if ga < gb then 17 | 1 18 | else if ga = gb then 19 | 0 20 | else 21 | -1 22 | (** 1 si ga < gb sinon 0 si ga = gb sinon -1 *) 23 | 24 | let additioner ga gb = ga + gb 25 | (** renvoie ga + gb *) 26 | 27 | let soustraire ga gb = ga - gb 28 | (** renvoie ga - gb *) 29 | 30 | let multiplier ga gb = ga * gb 31 | (** renvoie ga * gb *) 32 | 33 | let rec pgcd ga gb = 34 | if ga = 0 then 35 | gb 36 | else 37 | pgcd (gb mod ga) ga 38 | (** renvoie pgcd(ga, gb) *) 39 | 40 | let diviser_multiple ga gb = ga / gb 41 | (** renvoie ga / gb où ga est multiple de gb *) 42 | 43 | let diviser ga gb = 44 | let pgcd = pgcd ga gb in 45 | ga / pgcd, gb / pgcd 46 | (** renvoie (nominateur, dénominateur) de la fraction ga / gb *) 47 | 48 | let grandentier_depuis_texte sa = int_of_string sa 49 | (** renvoie le grandentier à partir de sa représentation textuelle *) 50 | 51 | let texte_depuis_grandentier ga = string_of_int ga 52 | (** renvoie la représentation textuelle d'un grandentier *) 53 | -------------------------------------------------------------------------------- /src/modules/grandEntier_off.mli: -------------------------------------------------------------------------------- 1 | type grandentier 2 | val zero : grandentier 3 | val unit : grandentier 4 | val est_negatif : grandentier -> bool 5 | val neg : grandentier -> grandentier 6 | val comparer : grandentier -> grandentier -> int 7 | val additioner : grandentier -> grandentier -> grandentier 8 | val soustraire : grandentier -> grandentier -> grandentier 9 | val multiplier : grandentier -> grandentier -> grandentier 10 | val pgcd : grandentier -> grandentier -> grandentier 11 | val diviser_multiple : grandentier -> grandentier -> grandentier 12 | val diviser : grandentier -> grandentier -> grandentier * grandentier 13 | val grandentier_depuis_texte : string -> grandentier 14 | val texte_depuis_grandentier : grandentier -> string 15 | -------------------------------------------------------------------------------- /src/modules/grandEntier_on.ml: -------------------------------------------------------------------------------- 1 | type grandentier = bool * int list 2 | (** grandentier est un tuple [(signe négatif, \[unité, dizaine, centaine, ...\])] 3 | [ - 123] correspond à [(true, \[3; 2; 1\])] *) 4 | 5 | (** https://www.youtube.com/watch?v=ih9zBLDr_ro Ca détend **) 6 | 7 | let zero = false, [] 8 | 9 | let unit = false, [1] 10 | 11 | (** renvoie [grandentier < 0] *) 12 | let est_negatif (signe, _) = signe 13 | 14 | (** ah **) 15 | 16 | (** renvoie l'oposé *) 17 | let neg (a, b) = 18 | match b with 19 | [] -> false, [] 20 | | _ -> not a, b 21 | 22 | let nettoyer_zero a = 23 | let rec n0 = function 24 | [] -> [] 25 | | 0 :: c -> n0 c 26 | | c -> List.rev c 27 | in n0 (List.rev a) 28 | 29 | (** 1 si ga < gb sinon 0 si ga = gb sinon -1 *) 30 | (* 1 : gb > ga 31 | 0 : ga = gb 32 | -1 : ga > gb*) 33 | 34 | let comparer_nbr_abs ga gb = 35 | let la = List.length ga 36 | and lb = List.length gb in 37 | if la > lb then 38 | -1 39 | else if la < lb then 40 | 1 41 | else 42 | let rec cna = function 43 | e1 :: ga, e2 :: gb -> 44 | if e1 > e2 then 45 | -1 46 | else if e2 > e1 then 47 | 1 48 | else 49 | cna (ga, gb) 50 | (* this will not happen *) 51 | | [], [] -> 0 52 | | _, [] -> -1 53 | | [], _ -> 1 54 | in cna (List.rev ga, List.rev gb) 55 | 56 | let comparer ga gb = 57 | match ga, gb with 58 | (true, _), (false, _) -> 1 59 | | (false, _), (true, _) -> -1 60 | | (false, b), (false, d) | (true, d), (true, b) -> comparer_nbr_abs b d 61 | (** 1 si ga < gb sinon 0 si ga = gb sinon -1 *) 62 | (* 1 : gb > ga 63 | 0 : ga = gb 64 | -1 : ga > gb*) 65 | 66 | (** Merci la prog :D**) 67 | let bigint_sum big1 big2 = 68 | let rec add = function 69 | [], r | r, [] -> r 70 | | d1 :: r1, d2 :: r2 -> 71 | let s = d1 + d2 in 72 | if s < 10 then 73 | s :: add(r1, r2) 74 | else 75 | (s - 10) :: add (add([1], r1), r2) 76 | in add (big1, big2) 77 | 78 | (* Constructeur propre a la sousatraction qui va 79 | permettre de ne pas effectuer la retenue *) 80 | let bigint_sum_for_sous big1 big2 = 81 | let rec add = function 82 | [], r | r, [] -> r 83 | | d1 :: r1, d2 :: r2 -> 84 | let s = d1 + d2 in 85 | s :: add (r1, r2) 86 | in add (big1, big2) 87 | 88 | (* On preferera a > b en abs et on aura toujours*) 89 | let rec sous = function 90 | [], [] -> [] 91 | | [], r | r, [] -> r 92 | | d1 :: r1, d2 :: r2 -> 93 | if d1 >= d2 then 94 | (d1 - d2) :: sous(r1, r2) 95 | else 96 | (d1 + 10 - d2) :: sous (r1, (bigint_sum_for_sous [1] r2)) 97 | 98 | let sous a = sous a |> nettoyer_zero 99 | 100 | (** renvoie ga + gb *) 101 | let additioner ga gb = 102 | match ga, gb with 103 | (true, b), (false, d) | (false, d), (true, b) -> 104 | if comparer_nbr_abs b d = -1 then 105 | true, sous (b, d) 106 | else 107 | false, sous (d, b) 108 | | (a, b), (_ (* = a *), d) -> a, bigint_sum b d 109 | 110 | (** renvoie ga - gb *) 111 | let soustraire ga gb = 112 | match ga, gb with 113 | (true, b), (true, d) | (false, d), (false, b) -> 114 | if comparer_nbr_abs b d = -1 then 115 | true, sous (b, d) 116 | else 117 | false, sous (d, b) 118 | | (a, b), (_ (* not a *), d) -> a, bigint_sum b d 119 | 120 | 121 | let bigint_mult big n = 122 | if n < 0 then 123 | invalid_arg "bigint_mult: negative multiplier" 124 | else 125 | let rec mult n = function 126 | [], 0 -> [] 127 | | [], carry -> (* bigint_of_int *) [carry] 128 | | d :: r, carry -> 129 | let res = n * d + carry in 130 | (res mod 10) :: mult n (r, res / 10) 131 | in 132 | match n with 133 | 0 -> [] 134 | | 1 -> big 135 | | n -> mult n (big, 0) 136 | 137 | 138 | let bigint_times big1 big2 = 139 | let rec mult = function 140 | [], _ | _, [] -> [] 141 | | 0 :: r, big | big, 0 :: r -> 0 :: mult (r, big) 142 | | 1 :: [], big | big, 1 :: [] -> big 143 | | 1 :: r, big | big, 1 :: r -> bigint_sum big (0 :: mult (r, big)) 144 | | d :: r, big -> bigint_sum (bigint_mult big d) (0 :: mult (r, big)) 145 | in mult (big1, big2) 146 | 147 | (** renvoie ga * gb *) 148 | let multiplier ga gb = 149 | match ga, gb with 150 | (a, b), (c, d) when a = c -> false, bigint_times b d 151 | | (_, b), (_, d) -> true, bigint_times b d 152 | 153 | let abaisser a e ret = 154 | let rec abaisser a n = 155 | let cmp = comparer_nbr_abs a e in 156 | if cmp = 1 then 157 | a, n 158 | else 159 | abaisser (sous (a, e)) (n + 1) 160 | in let a, n = abaisser a 0 in 161 | a, n :: ret 162 | 163 | let rec div_mul a e = 164 | let cmp = comparer_nbr_abs a e in 165 | if cmp = 1 then 166 | a, [] 167 | else 168 | let a, n = div_mul a (0 :: e) in 169 | abaisser a e n 170 | 171 | let div_eucl = function 172 | _, (_, []) -> raise Division_by_zero 173 | | (a, b), (c, d) -> 174 | let m, div = div_mul b d in 175 | (a, m), (a <> c, div) 176 | 177 | 178 | let div_eucl_fix = function 179 | _, (_, []) -> raise Division_by_zero 180 | | (false as a, b), (c, d) -> 181 | let m, div = div_mul b d in 182 | (a, m), (a <> c, div) 183 | | (true as a, b), (c, d) -> 184 | let m, div = div_mul b d in 185 | additioner (a, m) (false, d), additioner (a <> c, div) (not c, [1]) 186 | 187 | (** renvoie ga / gb où ga est multiple de gb *) 188 | let diviser_multiple ((a, _) as ga) ((c, _) as gb) = 189 | let _, (s, div) = div_eucl (ga, gb) in 190 | if a then 191 | additioner (a <> c, div) (not c, [1]) 192 | else 193 | s, div 194 | 195 | (** renvoie le reste de la division euclidienne de ga par gb *) 196 | let modulo ((a, _) as ga) ((_, d) as gb) = 197 | let (s, m), _ = div_eucl (ga, gb) in 198 | if a then 199 | additioner (a, m) (false, d) 200 | else 201 | s, m 202 | 203 | (** renvoie pgcd(ga, gb) *) 204 | let rec pgcd ga gb = 205 | let ga, gb = 206 | if comparer ga gb = 1 (*ga < gb*) then 207 | gb, ga 208 | else 209 | ga, gb 210 | in if gb = zero then 211 | ga 212 | else 213 | pgcd gb (modulo ga gb) 214 | 215 | (** renvoie (nominateur, dénominateur) de la fraction ga / gb *) 216 | let diviser ga gb = 217 | let gc = pgcd ga gb in 218 | diviser_multiple ga gc, diviser_multiple gb gc 219 | 220 | (** renvoie le grandentier à partir de sa représentation textuelle *) 221 | let cse_rec a n = 222 | let n = n - 1 in 223 | let rec abc acc i = 224 | if i = n then 225 | List.rev acc 226 | else 227 | abc ((int_of_char a.[i]) - 48 :: acc) (i - 1) 228 | in abc [] (String.length a - 1) |> nettoyer_zero 229 | 230 | let grandentier_depuis_texte sa = 231 | if sa.[0] = '-' then 232 | true, cse_rec sa 1 233 | else if sa.[0] = '+' then 234 | false, cse_rec sa 1 235 | else 236 | false, cse_rec sa 0 237 | 238 | (* A QUE COUCOU BOP*) 239 | (*Convertit basiquement le nombre*) 240 | let textedechiffre ga = 241 | let rec tdc acc = function 242 | [] -> acc 243 | | e :: ga -> (tdc [@tailcall]) ((string_of_int e) ^ acc) ga 244 | in tdc "" ga 245 | 246 | (** renvoie la représentation textuelle d'un grandentier *) 247 | let texte_depuis_grandentier (a, b) = 248 | if b = [] then 249 | "0" 250 | else if a then 251 | "-" ^ textedechiffre b 252 | else 253 | textedechiffre b 254 | -------------------------------------------------------------------------------- /src/modules/grandEntier_on.mli: -------------------------------------------------------------------------------- 1 | type grandentier = bool * int list 2 | val zero : grandentier 3 | val unit : grandentier 4 | val est_negatif : grandentier -> bool 5 | val neg : grandentier -> grandentier 6 | val comparer : grandentier -> grandentier -> int 7 | val additioner : grandentier -> grandentier -> grandentier 8 | val soustraire : grandentier -> grandentier -> grandentier 9 | val multiplier : grandentier -> grandentier -> grandentier 10 | val pgcd : grandentier -> grandentier -> grandentier 11 | val diviser_multiple : grandentier -> grandentier -> grandentier 12 | val diviser : grandentier -> grandentier -> grandentier * grandentier 13 | val grandentier_depuis_texte : string -> grandentier 14 | val texte_depuis_grandentier : grandentier -> string 15 | -------------------------------------------------------------------------------- /src/modules/grandNum_on.ml: -------------------------------------------------------------------------------- 1 | type num = 2 | E of GrandEntier_on.grandentier 3 | | R of GrandReel_on.grandreel 4 | | Q of GrandRationnel_on.grandrationnel 5 | 6 | let power c = 7 | let rec p i = function 8 | 0 -> i 9 | | c -> p (0 :: i) (c - 1) 10 | in p [1] c 11 | 12 | let rec up (a, b, c) = 13 | if c <= 0 then 14 | a, b, [1] 15 | else 16 | up (a, 0 :: b, c - 1) 17 | 18 | let q_depuis_r (a, b, c) = 19 | if c = 0 then 20 | a, b, [1] 21 | else if c > 0 then 22 | up (a, b, c) 23 | else 24 | a, b, power ~-c 25 | 26 | let zero = E (GrandEntier_on.grandentier_depuis_texte "0") 27 | 28 | let unit = E (GrandEntier_on.grandentier_depuis_texte "1") 29 | 30 | let vers_grandentier = function 31 | E _ as e -> e 32 | | R (_, [], _) -> zero 33 | | R (s, mantisse, exp) as r -> 34 | if exp > 0 then 35 | let s, mantisse, exp = up (s, mantisse, exp) in 36 | if exp = [1] then (* Should always be true *) 37 | E (s, mantisse) 38 | else 39 | r 40 | else 41 | r 42 | | Q (_, [], _) -> zero 43 | | Q (_, _, []) -> raise Division_by_zero 44 | | Q (signe, nom, [1]) -> E (signe, nom) 45 | | Q _ as q -> q 46 | 47 | let multiplier = function 48 | E e1, E e2 -> E (GrandEntier_on.multiplier e1 e2) 49 | | R r1, R r2 -> R (GrandReel_on.multiplier r1 r2) 50 | | Q q1, Q q2 -> Q (GrandRationnel_on.multiplier q1 q2) 51 | | R r2, E (signe, e1) -> R (GrandReel_on.multiplier (signe, e1, 0) r2) 52 | | E (signe, e1), R r2 -> R (GrandReel_on.multiplier (signe, e1, 0) r2) 53 | | E (signe, e1), Q q1 -> Q (GrandRationnel_on.multiplier q1 (signe, e1, [1])) 54 | | Q q1, E (signe, e1) -> Q (GrandRationnel_on.multiplier q1 (signe, e1, [1])) 55 | | R r1, Q q1 -> Q (GrandRationnel_on.multiplier q1 (q_depuis_r r1)) 56 | | Q q1, R r1 -> Q (GrandRationnel_on.multiplier q1 (q_depuis_r r1)) 57 | 58 | let multiplier e = multiplier e |> vers_grandentier 59 | 60 | let soustraire = function 61 | E e1, E e2 -> E (GrandEntier_on.soustraire e1 e2) 62 | | R r1, R r2 -> R (GrandReel_on.soustraire r1 r2) 63 | | Q q1, Q q2 -> Q (GrandRationnel_on.soustraire q1 q2) 64 | | R r2, E (signe, e1) -> R (GrandReel_on.soustraire (signe, e1, 0) r2) 65 | | E (signe, e1), R r2 -> R (GrandReel_on.soustraire (signe, e1, 0) r2) 66 | | E (signe, e1), Q q1 -> Q (GrandRationnel_on.soustraire q1 (signe, e1, [1])) 67 | | Q q1, E (signe, e1) -> Q (GrandRationnel_on.soustraire q1 (signe, e1, [1])) 68 | | R r1, Q q1 -> Q (GrandRationnel_on.soustraire q1 (q_depuis_r r1)) 69 | | Q q1, R r1 -> Q (GrandRationnel_on.soustraire q1 (q_depuis_r r1)) 70 | 71 | let soustraire e = soustraire e |> vers_grandentier 72 | 73 | let additioner = function 74 | E e1, E e2 -> E (GrandEntier_on.additioner e1 e2) 75 | | R r1, R r2 -> R (GrandReel_on.additioner r1 r2) 76 | | Q q1, Q q2 -> Q (GrandRationnel_on.additioner q1 q2) 77 | | R r2, E (signe, e1) -> R (GrandReel_on.additioner (signe, e1, 0) r2) 78 | | E (signe, e1), R r2 -> R (GrandReel_on.additioner (signe, e1, 0) r2) 79 | | E (signe, e1), Q q1 -> Q (GrandRationnel_on.additioner q1 (signe, e1, [1])) 80 | | Q q1, E (signe, e1) -> Q (GrandRationnel_on.additioner q1 (signe, e1, [1])) 81 | | R r1, Q q1 -> Q (GrandRationnel_on.additioner q1 (q_depuis_r r1)) 82 | | Q q1, R r1 -> Q (GrandRationnel_on.additioner q1 (q_depuis_r r1)) 83 | 84 | let additioner e = additioner e |> vers_grandentier 85 | 86 | let diviser = function 87 | E (signe1, e1), E (signe2, e2) -> Q (signe1 <> signe2, e1, e2) 88 | | R r1, R r2 -> Q (GrandRationnel_on.diviser (q_depuis_r r1) (q_depuis_r r2)) 89 | | Q q1, Q q2 -> Q (GrandRationnel_on.diviser q1 q2) 90 | | R r2, E (signe, e1) -> Q (GrandRationnel_on.diviser (signe, e1, [1]) (q_depuis_r r2)) 91 | | E (signe, e1), R r2 -> Q (GrandRationnel_on.diviser (signe, e1, [1]) (q_depuis_r r2)) 92 | | E (signe, e1), Q q1 -> Q (GrandRationnel_on.diviser q1 (signe, e1, [1])) 93 | | Q q1, E (signe, e1) -> Q (GrandRationnel_on.diviser q1 (signe, e1, [1])) 94 | | R r1, Q q1 -> Q (GrandRationnel_on.diviser q1 (q_depuis_r r1)) 95 | | Q q1, R r1 -> Q (GrandRationnel_on.diviser q1 (q_depuis_r r1)) 96 | 97 | let diviser e = diviser e |> vers_grandentier 98 | 99 | let opposer = function 100 | E (signe, e1) -> E (not signe, e1) 101 | | Q (signe, q1, q2) -> Q (not signe, q1, q2) 102 | | R (signe, r, exp) -> R (not signe, r, exp) 103 | 104 | let opposer e = opposer e |> vers_grandentier 105 | 106 | let inverser = function 107 | E (signe, e1) -> Q (signe, [1], e1) 108 | | Q (signe, q1, q2) -> Q (signe, q2, q1) 109 | | R r1 -> 110 | let a, b, c = q_depuis_r r1 in 111 | Q (a, c, b) 112 | 113 | let inverser e = inverser e |> vers_grandentier 114 | 115 | let texte_depuis_num = function 116 | E e1 -> GrandEntier_on.texte_depuis_grandentier e1 117 | | R r1 -> GrandReel_on.texte_depuis_grandreel r1 118 | | Q (signe, q1, q2) -> 119 | let q1 = GrandEntier_on.texte_depuis_grandentier (false, q1) 120 | and q2 = GrandEntier_on.texte_depuis_grandentier (false, q2) in 121 | let q = q1 ^ "/" ^ q2 in 122 | if signe then 123 | "-" ^ q 124 | else 125 | q 126 | 127 | let est_negatif = function 128 | E (signe, _) -> signe 129 | | Q (signe, _, _) -> signe 130 | | R (signe, _, _) -> signe 131 | -------------------------------------------------------------------------------- /src/modules/grandNum_on.mli: -------------------------------------------------------------------------------- 1 | type num = 2 | E of GrandEntier_on.grandentier 3 | | R of GrandReel_on.grandreel 4 | | Q of GrandRationnel_on.grandrationnel 5 | val zero : num 6 | val unit : num 7 | val power : int -> int list 8 | val up : 'a * int list * int -> 'a * int list * int list 9 | val q_depuis_r : GrandReel_on.grandreel -> GrandRationnel_on.grandrationnel 10 | val multiplier : num * num -> num 11 | val soustraire : num * num -> num 12 | val additioner : num * num -> num 13 | val diviser : num * num -> num 14 | val opposer : num -> num 15 | val inverser : num -> num 16 | val texte_depuis_num : num -> string 17 | val est_negatif : num -> bool 18 | -------------------------------------------------------------------------------- /src/modules/grandRationnel_on.ml: -------------------------------------------------------------------------------- 1 | open GrandEntier_on 2 | 3 | type grandrationnel = bool * int list * int list 4 | 5 | let additioner (a, b, c) (d, e, f) = 6 | let z = multiplier (a, b) (false, f) 7 | and elie = multiplier (false, c) (d, e) 8 | and travail = multiplier (false, c) (false, f) in 9 | let alex, gautier = additioner z elie in 10 | let (_, quentin), (_, tropdeu) = diviser (alex, gautier) travail in 11 | alex, quentin, tropdeu 12 | 13 | let soustraire (a, b, c) (d, e, f) = 14 | additioner (a, b, c) (not d, e, f) 15 | 16 | let multiplier (a, b, c) (d, e, f) = 17 | let thomas = multiplier (false, b) (false, e) 18 | and mouton = multiplier (false, c) (false, f) in 19 | let (_, x), (_, i) = diviser thomas mouton in 20 | a <> d, x, i 21 | 22 | let diviser (a, b, c) (d, e, f) = 23 | multiplier (a, b, c) (d, f, e) 24 | -------------------------------------------------------------------------------- /src/modules/grandReel_on.ml: -------------------------------------------------------------------------------- 1 | open GrandEntier_on 2 | 3 | (** grandreel est un tuple [(signe négatif, \[unité, dizaine, centaine, ...\], exposant base 10)] 4 | [-1,23] correspond à [(true, \[3; 2; 1\], -2)] *) 5 | type grandreel = bool * int list * int 6 | 7 | (** zero de grandreel *) 8 | let zero = false, [], 0 9 | 10 | (** unité de grandreel *) 11 | let unit = false, [1], 0 12 | 13 | (** renvoie [grandreel < 0] *) 14 | let est_negatif (s, _, _) = s 15 | 16 | (* let is_nul (a, b, c) = b = [] *) 17 | 18 | (** renvoie l'oposé *) 19 | let neg = function 20 | _, [], _ -> false, [], 0 21 | | s, m, e -> not s, m, e 22 | 23 | 24 | let remove a = 25 | let rec r0 = function 26 | [] -> [] 27 | | 0 :: c -> r0 c 28 | | c -> List.rev c 29 | in r0 (List.rev a) 30 | 31 | 32 | let rec powerup = function 33 | _, [], _ -> false, [], 0 34 | | s, 0 :: b, c -> powerup (s, b, c + 1) 35 | | s, e :: b, c -> s, e :: b, c 36 | 37 | 38 | (* 39 | Fonction Auxiliaire qui va mettre les deux valeurs sur la meme puissance 40 | On choisira toujours la plus grande 41 | *) 42 | let reunir_puissance ga gb = 43 | let rec r_p ga gb = 44 | let sa, va, a = ga 45 | and sb, vb, b = gb in 46 | if a = b then 47 | ga, gb 48 | else if a < b then 49 | r_p (sa, va, a) (sb, 0 :: vb, b - 1) 50 | else 51 | r_p (sa, 0 :: va, a - 1) (sb, vb, b) 52 | in r_p ga gb 53 | 54 | (** 1 si ga < gb sinon 0 si ga = gb sinon -1 *) 55 | (* 1 : gb > ga 56 | 0 : ga = gb 57 | -1 : ga > gb*) 58 | 59 | let comparer ga gb = 60 | let (a, b, _), (d, e, _) = reunir_puissance ga gb in 61 | comparer (a, b) (d, e) 62 | 63 | (** renvoie ga + gb *) 64 | let additioner ga gb = 65 | let (a, b, c), (d, e, _) = reunir_puissance ga gb in 66 | let a, b = additioner (a, b) (d, e) in 67 | powerup (a, remove b, c) 68 | 69 | (** renvoie ga - gb *) 70 | let soustraire ga gb = 71 | let (a, b, c), (d, e, _) = reunir_puissance ga gb in 72 | let a, b = soustraire (a, b) (d, e) in 73 | powerup (a, remove b, c) 74 | 75 | (** renvoie ga * gb *) 76 | let multiplier (a, b, c) (d, e, f) = 77 | let a, b = multiplier (a, b) (d, e) in 78 | powerup (a, remove b, c + f) 79 | 80 | (** renvoie ga / gb *) 81 | let diviser (a, b, c) (d, e, f) = 82 | let () = 83 | if e = [] then (* / 0 *) 84 | failwith "Pas de mechant mot :(" 85 | in let signe = b <> [] (* 0 / a -> + *) && a <> d in 86 | let b = [] in 87 | powerup (signe, remove b, c - f), powerup (signe, remove b, c - f) 88 | 89 | let grandReel_depuis_texte_transfo start ga = 90 | let max = String.length ga in 91 | let rec grdt (a, b, c) cpt = 92 | if cpt = max then 93 | b, c 94 | else 95 | let next = 96 | match a, ga.[cpt] with 97 | _, (',' | '.') -> true, b, c 98 | | true, cha -> true, (int_of_char cha - 48) :: b, c - 1 99 | | false, cha -> false, (int_of_char cha - 48) :: b, c 100 | in grdt next (cpt + 1) 101 | in grdt (false, [], 0) start 102 | 103 | 104 | let grandreel_depuis_texte sa = 105 | let signe, transfo = 106 | match sa.[0] with (* sa is not "" *) 107 | '-' -> true, grandReel_depuis_texte_transfo 1 108 | | '+' -> false, grandReel_depuis_texte_transfo 1 109 | | _ -> false, grandReel_depuis_texte_transfo 0 110 | in let mantisse, exposant = transfo sa in 111 | (signe, remove mantisse, exposant) |> powerup 112 | 113 | (*Convertit basiquement le nombre*) 114 | let textedechiffre ga = 115 | let rec tdc = function 116 | [] -> "" 117 | | e :: ga -> tdc ga ^ (string_of_int e) 118 | in tdc ga 119 | 120 | (** renvoie la représentation textuelle d'un grandentier *) 121 | let texte_depuis_grandentier ga = 122 | let a, b = ga in 123 | if a then 124 | "-" ^ textedechiffre b 125 | else 126 | textedechiffre b 127 | 128 | let rec ajouterdes0 texte nbr = 129 | if nbr = 0 then 130 | texte 131 | else 132 | ajouterdes0 (texte ^ "0") (nbr - 1) 133 | 134 | let rec tdgcs = function 135 | [], _ -> "" 136 | | a, 0 -> tdgcs (a, 1) ^ "," 137 | | e :: a, b -> tdgcs (a, b + 1) ^ string_of_int e 138 | 139 | let texte_depuis_grandreel_cas_neg (a, b, c) = 140 | let texte = tdgcs (b, c) in 141 | if a then 142 | "-" ^ texte 143 | else 144 | texte 145 | 146 | let texte_depuis_grandreel = function 147 | _, [], _ -> "0" 148 | | a, b, 0 -> texte_depuis_grandentier (a, b) 149 | | a, b, c when c > 0 -> ajouterdes0 (texte_depuis_grandentier (a, b)) c 150 | | ga -> texte_depuis_grandreel_cas_neg ga 151 | 152 | (* 153 | let t_depart = "42,24" 154 | let ga = grandreel_depuis_texte t_depart 155 | let resultat_correct = texte_depuis_grandreel ga = t_depart 156 | *) 157 | -------------------------------------------------------------------------------- /src/modules/grandReel_on.mli: -------------------------------------------------------------------------------- 1 | type grandreel = bool * int list * int 2 | val zero : grandreel 3 | val unit : grandreel 4 | val est_negatif : grandreel -> bool 5 | val neg : grandreel -> grandreel 6 | val comparer : grandreel -> grandreel -> int 7 | val additioner : grandreel -> grandreel -> grandreel 8 | val soustraire : grandreel -> grandreel -> grandreel 9 | val multiplier : grandreel -> grandreel -> grandreel 10 | val diviser : grandreel -> grandreel -> grandreel * grandreel 11 | val grandreel_depuis_texte : string -> grandreel 12 | val texte_depuis_grandreel : grandreel -> string 13 | -------------------------------------------------------------------------------- /src/modules/matrix.ml: -------------------------------------------------------------------------------- 1 | module type Value = sig 2 | type t 3 | 4 | val zero : t 5 | val unit : t 6 | val symb : string -> t 7 | val neg : t -> t 8 | val est_zero : t -> bool 9 | val depuis_texte : string -> t 10 | val vers_texte : t -> string 11 | val additioner : t -> t -> t 12 | val soustraire : t -> t -> t 13 | val diviser : t -> t -> t 14 | val multiplier : t -> t -> t 15 | val print : t -> unit 16 | end 17 | 18 | module Generic_matrix (V : Value) = struct 19 | type t = V.t array array 20 | type solution_equation = 21 | Erreur of string 22 | | Solution_systeme of (string * V.t) list 23 | 24 | let print = V.print 25 | let init n p = Array.make_matrix n p V.zero 26 | let __protect m = Array.length m > 0 && Array.length m.(0) > 0 27 | let size m = 28 | let h = Array.length m in 29 | if h = 0 then 30 | h, 0 31 | else 32 | h, Array.length m.(0) 33 | let foreach ?(line = function _ -> ()) m f = 34 | if __protect m then 35 | let h, w = size m in 36 | for i = 0 to pred h do 37 | let () = 38 | for j = 0 to pred w do 39 | f i j m.(i).(j) 40 | done 41 | in line m.(i) 42 | done 43 | let print m = 44 | let () = 45 | foreach ~line:(fun _ -> print_char '\n') m (fun _ _ -> V.print) 46 | in print_char '\n' 47 | let foreach2 f m1 m2 = 48 | let (h, w) = size m1 in 49 | if (h, w) = size m2 then 50 | let mres = init h w in 51 | let () = foreach m1 (fun i j e -> mres.(i).(j) <- f e m2.(i).(j)) in 52 | mres 53 | else 54 | failwith (I18n.matrice_mauvaise_dimension ()) 55 | let __vide_vers_identite m = 56 | let h, w = size m in 57 | let () = 58 | for i = 0 to pred (min h w) do 59 | m.(i).(i) <- V.unit 60 | done 61 | in m 62 | let identite n = 63 | let mres = init n n in 64 | __vide_vers_identite mres 65 | let additioner m1 m2 = foreach2 V.additioner m1 m2 66 | let soustraire m1 m2 = foreach2 V.soustraire m1 m2 67 | let multiplier m1 m2 = 68 | let (n, p) = size m1 69 | and (p', q) = size m2 in 70 | if p = p' then 71 | let mres = init n q in 72 | let prod_ligne_colonne i j = 73 | let res = ref V.zero in 74 | let () = 75 | for k = 0 to pred p do 76 | res := V.additioner !res (V.multiplier m1.(i).(k) m2.(k).(j)) 77 | done 78 | in !res 79 | in let () = foreach mres (fun i j _ -> mres.(i).(j) <- prod_ligne_colonne i j) in 80 | mres 81 | else 82 | failwith "taille mauvaise dimension" 83 | let multiplier_scalaire m scalaire = 84 | let (h, w) = size m in 85 | let mres = init h w in 86 | let () = foreach m (fun i j e -> mres.(i).(j) <- V.multiplier e scalaire) in 87 | mres 88 | module Operation_elementaires = struct 89 | let multiplier_ligne l scalaire = 90 | Array.map (V.multiplier scalaire) l 91 | let additioner_ligne l1 l2 = 92 | Array.mapi (fun k -> V.additioner l2.(k)) l1 93 | let neg_ligne l = 94 | Array.map V.neg l 95 | let echanger_ligne m i j = 96 | let tmp = m.(i) in 97 | let () = m.(i) <- m.(j) in 98 | m.(j) <- tmp 99 | let affecter_ligne m i l = 100 | m.(i) <- l 101 | let comb_lineaire mat (a, i) (b, j) = 102 | Array.mapi (fun k e -> 103 | V.additioner (V.multiplier a e) (V.multiplier b mat.(j).(k))) 104 | mat.(i) 105 | let ajouter_ligne inc mat i w h = 106 | let l = Array.make (w + 1) V.zero in 107 | let () = l.(i) <- V.unit in 108 | let () = l.(w) <- V.symb inc.(i) in 109 | let () = mat := Array.append !mat [| l |] in 110 | incr h 111 | end 112 | let inverser m' = 113 | let h, w = size m' in 114 | let m = init h w in 115 | let () = foreach m' (fun i j e -> m.(i).(j) <- e) in 116 | let n = min h w in 117 | let mres = init w h in 118 | let mres = __vide_vers_identite mres in 119 | let open Operation_elementaires in 120 | let () = 121 | for i = 0 to pred (pred n) do 122 | for j = i + 1 to pred h do 123 | if m.(j).(i) <> V.zero then 124 | let () = 125 | if m.(i).(i) = V.zero then 126 | let () = echanger_ligne m j i in 127 | echanger_ligne mres j i 128 | else 129 | let pivot = m.(i).(i) in 130 | let coeff = V.diviser m.(j).(i) pivot in 131 | let modifier_ligne m = 132 | let ligne = multiplier_ligne m.(i) coeff in 133 | let ligne = neg_ligne ligne in 134 | let () = Printf.printf "%d, %d\n" (Array.length m.(j)) (Array.length ligne) in 135 | let ligne = additioner_ligne m.(j) ligne in 136 | affecter_ligne m j ligne 137 | in let () = modifier_ligne m in 138 | if j < n then 139 | modifier_ligne mres 140 | (* in fact we should empty it *) 141 | in print mres 142 | done 143 | done 144 | in let () = print m in 145 | mres 146 | 147 | let triangle_superieur inc mat h w = 148 | let mat = ref mat 149 | and h = ref h in 150 | let () = 151 | for i = 0 to pred w do 152 | let () = 153 | if i > pred !h then 154 | Operation_elementaires.ajouter_ligne inc mat i w h 155 | in let () = 156 | if V.est_zero !mat.(i).(i) then 157 | let () = 158 | for k = i + 1 to pred !h do 159 | if not (V.est_zero !mat.(k).(i)) then 160 | Operation_elementaires.echanger_ligne !mat i i 161 | done 162 | in if V.est_zero !mat.(i).(i) then 163 | let () = Operation_elementaires.ajouter_ligne inc mat i w h in 164 | Operation_elementaires.echanger_ligne !mat (pred !h) i 165 | in for j = i + 1 to pred !h do 166 | !mat.(j) <- Operation_elementaires.comb_lineaire !mat (!mat.(j).(i), i) (V.neg (!mat.(i).(i)), j) 167 | done 168 | done 169 | in !mat, !h 170 | 171 | let nomalise mat w = 172 | let () = 173 | for i = 0 to pred w do 174 | mat.(i) <- Operation_elementaires.multiplier_ligne mat.(i) (V.diviser V.unit mat.(i).(i)) 175 | done 176 | in mat 177 | 178 | let remonte mat w = 179 | let () = 180 | for i = pred w downto 0 do 181 | for k = i - 1 downto 0 do 182 | mat.(k) <- Operation_elementaires.comb_lineaire mat (V.neg mat.(k).(i), i) (mat.(i).(i), k) 183 | done 184 | done 185 | in mat 186 | 187 | let contractition_presente mat w h = 188 | let resultat = ref false in 189 | let () = 190 | for i = w to pred h do 191 | resultat := not (V.est_zero mat.(i).(w)) || !resultat 192 | done 193 | in !resultat 194 | 195 | let resoudre_sys mat w h inc = 196 | let mat, h = triangle_superieur inc mat h w in 197 | let mat = nomalise mat w in 198 | let mat = remonte mat w in 199 | mat, w, h, inc 200 | 201 | let solveur mat w h inc = 202 | let mat = Array.map (Array.map V.depuis_texte) mat in 203 | let mat, w, h, inc = resoudre_sys mat w h inc in 204 | if contractition_presente mat w h then 205 | Erreur (I18n.contractition_presente ()) 206 | else 207 | Solution_systeme ((Array.mapi (fun i e -> (e, mat.(i).(w))) inc) |> Array.to_list) 208 | end 209 | 210 | module Test_int = struct 211 | type t = int 212 | 213 | let zero = 0 214 | let unit = 1 215 | let symb _ = unit 216 | let neg = ( ~- ) 217 | let est_zero = (=) 0 218 | let depuis_texte = int_of_string 219 | let vers_texte = string_of_int 220 | let additioner = ( + ) 221 | let soustraire = ( - ) 222 | let diviser = ( / ) 223 | let multiplier = ( * ) 224 | let print = Printf.printf "%5d" 225 | end 226 | 227 | module Test_int_matrix = Generic_matrix(Test_int) 228 | 229 | module Test_float = struct 230 | type t = float 231 | 232 | let zero = 0. 233 | let unit = 1. 234 | let symb _ = unit 235 | let neg = ( ~-. ) 236 | let est_zero a = -0.0001 < a && a < 0.0001 237 | let depuis_texte = float_of_string 238 | let vers_texte = string_of_float 239 | let additioner = ( +. ) 240 | let soustraire = ( -. ) 241 | let diviser = ( /. ) 242 | let multiplier = ( *. ) 243 | let print = Printf.printf "%10.6f" 244 | end 245 | 246 | module Test_float_matrix = Generic_matrix(Test_float) 247 | -------------------------------------------------------------------------------- /src/modules/matrix.mli: -------------------------------------------------------------------------------- 1 | module type Value = 2 | sig 3 | type t 4 | val zero : t 5 | val unit : t 6 | val symb : string -> t 7 | val neg : t -> t 8 | val est_zero : t -> bool 9 | val depuis_texte : string -> t 10 | val vers_texte : t -> string 11 | val additioner : t -> t -> t 12 | val soustraire : t -> t -> t 13 | val diviser : t -> t -> t 14 | val multiplier : t -> t -> t 15 | val print : t -> unit 16 | end 17 | module Generic_matrix : 18 | functor (V : Value) -> 19 | sig 20 | type t = V.t array array 21 | type solution_equation = 22 | Erreur of string 23 | | Solution_systeme of (string * V.t) list 24 | val init : int -> int -> V.t array array 25 | val __protect : 'a array array -> bool 26 | val size : 'a array array -> int * int 27 | val foreach : 28 | ?line:('a array -> unit) -> 29 | 'a array array -> (int -> int -> 'a -> unit) -> unit 30 | val print : V.t array array -> unit 31 | val foreach2 : 32 | ('a -> 'b -> V.t) -> 33 | 'a array array -> 'b array array -> V.t array array 34 | val __vide_vers_identite : V.t array array -> V.t array array 35 | val identite : int -> V.t array array 36 | val additioner : V.t array array -> V.t array array -> V.t array array 37 | val soustraire : V.t array array -> V.t array array -> V.t array array 38 | val multiplier : V.t array array -> V.t array array -> V.t array array 39 | val multiplier_scalaire : V.t array array -> V.t -> V.t array array 40 | module Operation_elementaires : 41 | sig 42 | val multiplier_ligne : V.t array -> V.t -> V.t array 43 | val additioner_ligne : V.t array -> V.t array -> V.t array 44 | val neg_ligne : V.t array -> V.t array 45 | val echanger_ligne : 'a array -> int -> int -> unit 46 | val affecter_ligne : 'a array -> int -> 'a -> unit 47 | end 48 | val inverser : V.t array array -> V.t array array 49 | val solveur : string array array -> int -> int -> string array -> solution_equation 50 | end 51 | module Test_int : 52 | sig 53 | type t = int 54 | val zero : int 55 | val unit : int 56 | val symb : string -> t 57 | val neg : int -> int 58 | val est_zero : int -> bool 59 | val depuis_texte : string -> int 60 | val vers_texte : int -> string 61 | val additioner : int -> int -> int 62 | val soustraire : int -> int -> int 63 | val diviser : int -> int -> int 64 | val multiplier : int -> int -> int 65 | val print : int -> unit 66 | end 67 | module Test_int_matrix : 68 | sig 69 | type t = Test_int.t array array 70 | type solution_equation = 71 | Erreur of string 72 | | Solution_systeme of (string * Test_int.t) list 73 | val init : int -> int -> Test_int.t array array 74 | val __protect : 'a array array -> bool 75 | val size : 'a array array -> int * int 76 | val foreach : 77 | ?line:('a array -> unit) -> 78 | 'a array array -> (int -> int -> 'a -> unit) -> unit 79 | val print : Test_int.t array array -> unit 80 | val foreach2 : 81 | ('a -> 'b -> Test_int.t) -> 82 | 'a array array -> 'b array array -> Test_int.t array array 83 | val __vide_vers_identite : 84 | Test_int.t array array -> Test_int.t array array 85 | val identite : int -> Test_int.t array array 86 | val additioner : 87 | Test_int.t array array -> 88 | Test_int.t array array -> Test_int.t array array 89 | val soustraire : 90 | Test_int.t array array -> 91 | Test_int.t array array -> Test_int.t array array 92 | val multiplier : 93 | Test_int.t array array -> 94 | Test_int.t array array -> Test_int.t array array 95 | val multiplier_scalaire : 96 | Test_int.t array array -> Test_int.t -> Test_int.t array array 97 | module Operation_elementaires : 98 | sig 99 | val multiplier_ligne : 100 | Test_int.t array -> Test_int.t -> Test_int.t array 101 | val additioner_ligne : 102 | Test_int.t array -> Test_int.t array -> Test_int.t array 103 | val neg_ligne : Test_int.t array -> Test_int.t array 104 | val echanger_ligne : 'a array -> int -> int -> unit 105 | val affecter_ligne : 'a array -> int -> 'a -> unit 106 | end 107 | val inverser : Test_int.t array array -> Test_int.t array array 108 | val solveur : string array array -> int -> int -> string array -> solution_equation 109 | end 110 | module Test_float : 111 | sig 112 | type t = float 113 | val zero : t 114 | val unit : t 115 | val symb : string -> t 116 | val neg : float -> float 117 | val est_zero : float -> bool 118 | val depuis_texte : string -> float 119 | val vers_texte : float -> string 120 | val additioner : float -> float -> float 121 | val soustraire : float -> float -> float 122 | val diviser : float -> float -> float 123 | val multiplier : float -> float -> float 124 | val print : float -> unit 125 | end 126 | module Test_float_matrix : 127 | sig 128 | type t = Test_float.t array array 129 | type solution_equation = 130 | Erreur of string 131 | | Solution_systeme of (string * Test_float.t) list 132 | val init : int -> int -> Test_float.t array array 133 | val __protect : 'a array array -> bool 134 | val size : 'a array array -> int * int 135 | val foreach : 136 | ?line:('a array -> unit) -> 137 | 'a array array -> (int -> int -> 'a -> unit) -> unit 138 | val print : Test_float.t array array -> unit 139 | val foreach2 : 140 | ('a -> 'b -> Test_float.t) -> 141 | 'a array array -> 'b array array -> Test_float.t array array 142 | val __vide_vers_identite : 143 | Test_float.t array array -> Test_float.t array array 144 | val identite : int -> Test_float.t array array 145 | val additioner : 146 | Test_float.t array array -> 147 | Test_float.t array array -> Test_float.t array array 148 | val soustraire : 149 | Test_float.t array array -> 150 | Test_float.t array array -> Test_float.t array array 151 | val multiplier : 152 | Test_float.t array array -> 153 | Test_float.t array array -> Test_float.t array array 154 | val multiplier_scalaire : 155 | Test_float.t array array -> Test_float.t -> Test_float.t array array 156 | module Operation_elementaires : 157 | sig 158 | val multiplier_ligne : 159 | Test_float.t array -> Test_float.t -> Test_float.t array 160 | val additioner_ligne : 161 | Test_float.t array -> Test_float.t array -> Test_float.t array 162 | val neg_ligne : Test_float.t array -> Test_float.t array 163 | val echanger_ligne : 'a array -> int -> int -> unit 164 | val affecter_ligne : 'a array -> int -> 'a -> unit 165 | end 166 | val inverser : Test_float.t array array -> Test_float.t array array 167 | val solveur : string array array -> int -> int -> string array -> solution_equation 168 | end 169 | -------------------------------------------------------------------------------- /src/noyau/ancien_moteur.ml: -------------------------------------------------------------------------------- 1 | open Lien 2 | open Type 3 | 4 | let rec additioner = function 5 | [], [] -> failwith "Chut OCaml: additioner rien du tout ?" 6 | | [], e :: l -> additioner ([eval e], l) 7 | | acc, [] -> List.rev acc 8 | | e :: acc, (a :: l) -> 9 | match eval e, eval a with 10 | | Entier a, Variable e -> additioner (Variable e :: acc, Entier a :: l) 11 | | Entier e, Entier a -> 12 | let res = Entier (GrandEntier.additioner e a) in 13 | additioner (res :: acc, l) 14 | | e, a -> additioner (a :: e :: acc, l) 15 | 16 | and multiplier = function 17 | [], [] -> failwith "Chut OCaml: multiplier rien du tout ?" 18 | | [], e :: l -> multiplier ([eval e], l) 19 | | acc, [] -> List.rev acc 20 | | e :: acc, Inv a :: l when (match e with Inv _ -> false | _ -> true) -> 21 | multiplier (acc, Inv a :: e :: l) 22 | | e :: acc, (a :: l) -> 23 | match eval e, eval a with 24 | | Entier a, Variable e -> multiplier (Variable e :: acc, Entier a :: l) 25 | | Entier e, Entier a -> 26 | let res = Entier (GrandEntier.multiplier e a) 27 | in multiplier (res :: acc, l) 28 | | Entier e, Inv (Entier a) | Inv (Entier a), Entier e -> 29 | (match GrandEntier.diviser e a with 30 | e, x when x = GrandEntier.unit -> multiplier ((Entier e) :: acc, l) 31 | | x, a when x = GrandEntier.unit -> multiplier (acc, Inv (Entier a) :: l) 32 | | e, a -> multiplier ((Entier e) :: Inv (Entier a) :: acc, l)) 33 | | Inv (Entier e), Inv (Entier a) -> 34 | let res = GrandEntier.multiplier e a in 35 | multiplier (acc, Inv (Entier res) :: l) 36 | | e, a -> multiplier (a :: e :: acc, l) 37 | 38 | and eval = function 39 | Operation ("+", []) -> failwith "euh il y a un problème" 40 | | Operation ("+", [e]) -> eval e 41 | | Operation ("+", e :: l) -> 42 | let acc = [eval e] in 43 | (match additioner (acc, l) with 44 | [e] -> e 45 | | l -> Operation ("+", l)) 46 | | Operation ("*", []) -> failwith "euh il y a un problème" 47 | | Operation ("*", [e]) -> eval e 48 | | Operation ("*", e :: l) -> 49 | let acc = [eval e] in 50 | (match multiplier (acc, l) with 51 | [e] -> e 52 | | l -> Operation ("*", l)) 53 | | Neg (Neg e) -> eval e 54 | | a -> a 55 | 56 | type context = expr list 57 | 58 | let empty_context = [] 59 | 60 | let evaluate_with_history str context = 61 | let e = eval (Parser.expr_de_texte str) in 62 | Parser.texte_de_expr e, e :: context 63 | -------------------------------------------------------------------------------- /src/noyau/ancien_moteur.mli: -------------------------------------------------------------------------------- 1 | val eval : Type.expr -> Type.expr 2 | 3 | type context = Type.expr list 4 | 5 | val empty_context: context 6 | val evaluate_with_history: string -> context -> string * context 7 | -------------------------------------------------------------------------------- /src/noyau/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name Noyau) 3 | (modules Lien Type Utils Lexer Parser Moteur Nouveau_type Nouveau_lexer Nouveau_parser Ancien_moteur) 4 | (libraries Modules I18n)) 5 | -------------------------------------------------------------------------------- /src/noyau/lexer.ml: -------------------------------------------------------------------------------- 1 | open Utils 2 | 3 | let est_entier t(*exte*) b(*ase*) = 4 | let l(*ongueur*) = String.length t in 5 | let m(*aximum caractere *) = char_of_int (b + 48) in 6 | let rec est_entier i = 7 | i = l 8 | || '0' <= t.[i] 9 | && t.[i] < m 10 | && est_entier (i + 1) 11 | in 2 <= l 12 | && ('-' = t.[0] 13 | || '+' = t.[0]) 14 | && est_entier 1 15 | || 1 <= l 16 | && 17 | est_entier 0 18 | 19 | let est_entier10 t = est_entier t 10 20 | 21 | let est_entier_base t(*exte*) = 22 | let l(*ongueur*) = String.length t in 23 | let i = 24 | try 25 | String.index t '_' 26 | with Not_found -> -1 27 | in i > 0 28 | && let b = int_of_string (String.sub t (i + 1) (l - i - 1)) in 29 | 0 <= b 30 | && b < 11 31 | && (t.[0] = '(' 32 | && t.[i - 1] = ')' 33 | && est_entier (String.sub t 1 (i - 2)) b) 34 | || (t.[0] != '(' 35 | && t.[i - 1] != ')' 36 | && est_entier (String.sub t 0 i) b) 37 | 38 | let est_variable t(*exte*) = 39 | let l(*ongueur*) = String.length t in 40 | let rec est_variable i = 41 | i = l 42 | || 'a' <= t.[i] && t.[i] <= 'z' 43 | && est_variable2 (i + 1) 44 | and est_variable2 i = 45 | i = l 46 | || match t.[i] with 47 | '_' -> i + 1 <> l && est_variable2 (i + 1) 48 | | c when 'a' <= c && c <= 'z' -> est_variable2 (i + 1) 49 | | c when 'A' <= c && c <= 'Z' -> est_variable2 (i + 1) 50 | | c when '0' <= c && c <= '9' -> est_variable2 (i + 1) 51 | | '\'' -> est_variable2 (i + 1) 52 | | _ -> false 53 | in l > 0 && est_variable 0 54 | 55 | let est_addition_soustraction t(*exte*) = 56 | contient_texte t ['+'; '-'] 57 | 58 | let est_multiplication_division t(*exte*) = 59 | contient_texte t ['*'; '/'] 60 | -------------------------------------------------------------------------------- /src/noyau/lexer.mli: -------------------------------------------------------------------------------- 1 | val est_entier : string -> int -> bool 2 | val est_entier10 : string -> bool 3 | val est_entier_base : string -> bool 4 | val est_variable : string -> bool 5 | val est_addition_soustraction : string -> bool 6 | val est_multiplication_division : string -> bool 7 | -------------------------------------------------------------------------------- /src/noyau/lien.ml: -------------------------------------------------------------------------------- 1 | module GrandEntier = Modules.GrandEntier_on 2 | module GrandReel = Modules.GrandReel_on 3 | module GrandRationnel = Modules.GrandRationnel_on 4 | module GrandNum = Modules.GrandNum_on 5 | -------------------------------------------------------------------------------- /src/noyau/moteur.ml: -------------------------------------------------------------------------------- 1 | open Lien 2 | 3 | type context = 4 | Nouveau_type.expr list (* history *) 5 | * (Nouveau_type.affe, Nouveau_type.expr) Hashtbl.t (* definitions *) 6 | 7 | let empty_context = [], Hashtbl.create 20 8 | 9 | let remplace_inconnu contexte = 10 | let open Nouveau_type in 11 | let rec ri = function 12 | Var s when Hashtbl.find_opt contexte (Def_Var s) <> None -> 13 | Hashtbl.find contexte (Def_Var s) 14 | (*| Fx (nom, n, _) when Hashtbl.find_opt s (Nouveau_type.Def_Fx (nom, n)) <> None -> 15 | Hashtbl.find s (Nouveau_type.Def_Fx (nom, n)) *) 16 | | T (n, l) -> T (n, List.map ri l) 17 | | Fx (nom, n, l) -> Fx (nom, n, List.map ri l) 18 | | Op (`Multiplication, l) -> Op (`Multiplication, List.map ri l) 19 | | Op (`Addition, l) -> Op (`Addition, List.map ri l) 20 | | Inv e -> Inv (ri e) 21 | | Neg e -> Neg (ri e) 22 | | e -> e 23 | in ri 24 | 25 | let rec eval = 26 | let open Nouveau_type in 27 | function 28 | Inv e -> 29 | ( 30 | match eval e with 31 | Inv e -> e 32 | | N (n) -> N (GrandNum.inverser n) 33 | | Neg e -> Neg (Inv e) 34 | | e -> Inv e 35 | ) 36 | | Neg e -> 37 | ( 38 | match eval e with 39 | Neg e -> e 40 | | N (n) -> N (GrandNum.opposer n) 41 | | e -> Neg e 42 | ) 43 | | (C _ | N _ | Var _ ) as e -> e 44 | | T (n, l) -> T (n, List.map eval l) 45 | | Fx ("sin", 1, [C Pi]) -> N (GrandNum.zero) 46 | | Fx (nom, n, l) -> Fx (nom, n, List.map eval l) 47 | | Op (`Addition, l) -> 48 | ( 49 | match List.map eval l |> additioner [] with 50 | [] -> 51 | let () = prerr_endline "On additionne rien du tout." in 52 | N (GrandNum.E (GrandEntier.grandentier_depuis_texte "0")) 53 | | [e] -> e 54 | | l -> Op (`Addition, l) 55 | ) 56 | | Op (`Multiplication, l) -> 57 | ( 58 | match List.map eval l |> multiplier [] with 59 | [] -> 60 | let () = prerr_endline "On multiplie rien du tout." in 61 | N (GrandNum.E (GrandEntier.grandentier_depuis_texte "0")) 62 | | [e] -> e 63 | | l -> Op (`Multiplication, l) 64 | ) 65 | 66 | and additioner acc liste_expr = 67 | let open Nouveau_type in 68 | match acc, liste_expr with 69 | acc, Op (`Addition, l) :: l' -> additioner acc (l @ l') 70 | | N n1 :: acc, N n2 :: l -> 71 | let n = GrandNum.additioner (n1, n2) in 72 | additioner acc ((N n) :: l) 73 | | N n :: acc, e :: l -> additioner acc (e :: N n :: l) 74 | | acc, e :: l -> additioner (e :: acc) l 75 | | acc, [] -> List.rev acc 76 | 77 | and multiplier acc liste_expr = 78 | let open Nouveau_type in 79 | match acc, liste_expr with 80 | acc, Op (`Multiplication, l) :: l' -> multiplier acc (l @ l') 81 | | N e :: _, _ when e = GrandNum.zero -> [N (GrandNum.zero)] 82 | | _, N e :: _ when e = GrandNum.zero -> [N (GrandNum.zero)] 83 | | N n1 :: acc, N n2 :: l -> 84 | let n = GrandNum.multiplier (n1, n2) in 85 | multiplier acc ((N n) :: l) 86 | | N n :: acc, e :: l -> multiplier acc (e :: N n :: l) 87 | | C I :: acc, C J :: l -> 88 | multiplier acc ((C K) :: l) 89 | | C J :: acc, C I :: l -> 90 | multiplier acc ((Neg (C K)) :: l) 91 | | acc, e :: l -> multiplier (e :: acc) l 92 | | acc, [] -> List.rev acc 93 | 94 | let rec text_de_multiplication l = 95 | let open Nouveau_type in 96 | let rec boucle acc = function 97 | [] -> acc 98 | | Op (`Addition, l) :: k -> boucle (acc ^ "(" ^ texte_de_addition l ^ ")") k 99 | | Inv (Op (_, _) as e) :: l -> 100 | let e = texte_depuis_expr e in 101 | boucle (acc ^ " / " ^ e) l 102 | | Inv e :: l -> boucle (acc ^ " / " ^ (texte_depuis_expr e)) l 103 | | e :: l -> boucle (acc ^ " * " ^ (texte_depuis_expr e)) l 104 | in match l with 105 | [] -> boucle "" l 106 | | Op (`Addition, l) :: k -> boucle ("(" ^ texte_de_addition l ^ ")") k 107 | | Inv (Op (_, _) as e) :: l -> 108 | let e = texte_depuis_expr e in 109 | boucle ("1 / " ^ e) l 110 | | Inv e :: l -> boucle ("1 / " ^ (texte_depuis_expr e)) l 111 | | e :: l -> boucle (texte_depuis_expr e) l 112 | 113 | and texte_de_addition l = 114 | let rec boucle acc = function 115 | [] -> acc 116 | | e :: l -> 117 | let e = texte_depuis_expr e in 118 | if e.[0] = '-' then 119 | boucle (acc ^ e) l 120 | else 121 | boucle (acc ^ " + " ^ e) l 122 | in match l with 123 | [] -> boucle "" l 124 | | e :: l -> boucle (texte_depuis_expr e) l 125 | 126 | and text_depuis_expr_liste sep l = 127 | "(" ^ String.concat sep (List.map texte_depuis_expr l) ^ ")" 128 | 129 | and texte_depuis_expr = 130 | let open Nouveau_type in 131 | let open Lien in 132 | function 133 | N n -> 134 | let e = GrandNum.texte_depuis_num n in 135 | if GrandNum.est_negatif n then 136 | "(" ^ e ^ ")" 137 | else 138 | e 139 | | C Pi -> "pi" 140 | | C I -> "i" 141 | | C J -> "j" 142 | | C K -> "k" 143 | | Var s -> s 144 | | T (_, l) -> (text_depuis_expr_liste ";" l) 145 | | Fx (nom, _, l) -> nom ^ (text_depuis_expr_liste ";" l) 146 | | Op (`Multiplication, l) -> text_de_multiplication l 147 | | Op (`Addition, l) -> texte_de_addition l 148 | | Inv e -> " / " ^ texte_depuis_expr e 149 | | Neg e -> "-" ^ texte_depuis_expr e 150 | 151 | let evaluate_with_history s context = 152 | let history, def = context in 153 | let open Nouveau_parser in 154 | match parse s with 155 | Erreur (s, _ (* TODO: convert l *)) -> s, context 156 | | Expression e -> 157 | let e = Nouveau_type.expr_depuis_expression e in 158 | let e = remplace_inconnu def e in 159 | let e = eval e in 160 | texte_depuis_expr e, (e :: history, def) 161 | | Definition l -> 162 | let l = List.map (function 163 | a, e -> 164 | let a = Nouveau_type.affe_depuis_affectable a 165 | and e = Nouveau_type.expr_depuis_expression e in 166 | let e = remplace_inconnu def e in 167 | let e = eval e in 168 | a, e) l 169 | in let () = List.iter (fun (a, e) -> Hashtbl.add def a e) l in 170 | I18n.definition_valide (), (history, def) 171 | 172 | 173 | module Expr = struct 174 | open Nouveau_type 175 | type t = expr 176 | 177 | let zero = N (GrandNum.zero) 178 | let unit = N (GrandNum.unit) 179 | let symb s = Var s 180 | let neg e = eval (Neg e) 181 | let est_zero a = a = N (GrandNum.zero) 182 | let depuis_texte s = 183 | match Nouveau_parser.parse s with 184 | Expression e -> 185 | let e = Nouveau_type.expr_depuis_expression e in 186 | eval e 187 | | Erreur (s, _ (* TODO: convert l *)) -> 188 | failwith (s) 189 | | _ -> failwith (I18n.definition_non_autorise ()) 190 | let vers_texte = texte_depuis_expr 191 | let additioner a b = eval (Op (`Addition, [a; b])) 192 | let soustraire a b = eval (Op (`Addition, [a; Neg b])) 193 | let diviser a b = eval (Op (`Multiplication, [a; Inv b])) 194 | let multiplier a b = eval (Op (`Multiplication, [a; b])) 195 | let print e = print_endline (texte_depuis_expr e) 196 | end 197 | 198 | module Expr_matrix = Modules.Matrix.Generic_matrix(Expr) 199 | -------------------------------------------------------------------------------- /src/noyau/moteur.mli: -------------------------------------------------------------------------------- 1 | type context 2 | 3 | val empty_context: context 4 | val texte_depuis_expr : Nouveau_type.expr -> string 5 | val evaluate_with_history: string -> context -> string * context 6 | 7 | 8 | 9 | module Expr : 10 | sig 11 | type t = Nouveau_type.expr 12 | val zero : t 13 | val unit : t 14 | val symb : string -> t 15 | val neg : t -> t 16 | val est_zero : t -> bool 17 | val depuis_texte : string -> t 18 | val vers_texte : t -> string 19 | val additioner : t -> t -> t 20 | val soustraire : t -> t -> t 21 | val diviser : t -> t -> t 22 | val multiplier : t -> t -> t 23 | val print : t -> unit 24 | end 25 | 26 | module Expr_matrix : 27 | sig 28 | type t = Expr.t array array 29 | type solution_equation = 30 | Erreur of string 31 | | Solution_systeme of (string * Expr.t) list 32 | val solveur : string array array -> int -> int -> string array -> solution_equation 33 | end 34 | -------------------------------------------------------------------------------- /src/noyau/nouveau_lexer.ml: -------------------------------------------------------------------------------- 1 | type operateur = 2 | Plus 3 | | Moins 4 | | Fois 5 | | Division 6 | | Exposant 7 | | Definition 8 | 9 | type token = 10 | Erreur 11 | | EOI 12 | | Blanc 13 | | Digit of string 14 | | Identifiant of string 15 | | Affectation 16 | | Parenthese_ouvrante 17 | | Parenthese_fermante 18 | | Separateur_unite 19 | | Separateur_liste 20 | | Souligne 21 | | Operateur of operateur 22 | 23 | let extraire_blanc s l start = 24 | let aux i = 25 | if i = start then 26 | i, Erreur 27 | else 28 | i, Blanc 29 | in let rec loop i = 30 | if i = l then 31 | aux i 32 | else 33 | match s.[i] with 34 | ('\t' | '\n' | ' ') -> loop (i + 1) 35 | | _ -> aux i 36 | in loop start 37 | 38 | let extraire_digit s l start = 39 | let aux i = 40 | if i = start then 41 | i, Erreur 42 | else 43 | i, Digit (String.sub s start (i - start)) 44 | in let rec loop i = 45 | if i = l then 46 | aux i 47 | else 48 | match s.[i] with 49 | '0' .. '9' -> loop (i + 1) 50 | | _ -> aux i 51 | in loop start 52 | 53 | let extraire_identifiant s l start = 54 | let aux i = 55 | if i = start then 56 | i, Erreur 57 | else 58 | i, Identifiant (String.sub s start (i - start)) 59 | in let rec loop i = 60 | if i = l then 61 | aux i 62 | else 63 | match s.[i] with 64 | ('a' .. 'z' | 'A' .. 'Z' | '\'' | '_') -> loop (i + 1) 65 | | _ -> aux i 66 | in (* loop start *) 67 | if start = l then 68 | aux start 69 | else 70 | match s.[start] with 71 | ('a' .. 'z' | 'A' .. 'Z') -> loop (start + 1) 72 | | _ -> aux start 73 | 74 | let extraire_jeton_general m lon s l start = 75 | if start + lon <= l then 76 | let rec loop i = 77 | if i - start = lon then 78 | i, true 79 | else if s.[i] = m.[i - start] then 80 | loop (i + 1) 81 | else 82 | i, false 83 | in loop start 84 | else 85 | start, false 86 | 87 | let extraire_parenthese_ouvrante s l start = 88 | match extraire_jeton_general "(" 1 s l start with 89 | | i, true -> i, Parenthese_ouvrante 90 | | _ -> start, Erreur 91 | 92 | let extraire_parenthese_fermante s l start = 93 | match extraire_jeton_general ")" 1 s l start with 94 | | i, true -> i, Parenthese_fermante 95 | | _ -> start, Erreur 96 | 97 | let extraire_separateur_unite s l start = 98 | match extraire_jeton_general "," 1 s l start with 99 | | i, true -> i, Separateur_unite 100 | | _ -> start, Erreur 101 | 102 | let extraire_separateur_liste s l start = 103 | match extraire_jeton_general ";" 1 s l start with 104 | | i, true -> i, Separateur_liste 105 | | _ -> start, Erreur 106 | 107 | let extraire_souligne s l start = 108 | match extraire_jeton_general "_" 1 s l start with 109 | | i, true -> i, Souligne 110 | | _ -> start, Erreur 111 | 112 | let extraire_signe_plus s l start = 113 | match extraire_jeton_general "+" 1 s l start with 114 | | i, true -> i, Operateur Plus 115 | | _ -> start, Erreur 116 | 117 | let extraire_signe_moins s l start = 118 | match extraire_jeton_general "-" 1 s l start with 119 | | i, true -> i, Operateur Moins 120 | | _ -> start, Erreur 121 | 122 | let extraire_signe_fois s l start = 123 | match extraire_jeton_general "*" 1 s l start with 124 | | i, true -> i, Operateur Fois 125 | | _ -> start, Erreur 126 | 127 | let extraire_signe_diviser s l start = 128 | match extraire_jeton_general "/" 1 s l start with 129 | | i, true -> i, Operateur Division 130 | | _ -> start, Erreur 131 | 132 | let extraire_signe_exposant s l start = 133 | match extraire_jeton_general "^" 1 s l start with 134 | | i, true -> i, Operateur Exposant 135 | | _ -> start, Erreur 136 | 137 | let extraire_signe_def s l start = 138 | match extraire_jeton_general ":=" 2 s l start with 139 | | i, true -> i, Operateur Definition 140 | | _ -> start, Erreur 141 | 142 | let iter = [ 143 | extraire_blanc; 144 | extraire_digit; 145 | extraire_identifiant; 146 | extraire_parenthese_ouvrante; 147 | extraire_parenthese_fermante; 148 | extraire_separateur_unite; 149 | extraire_separateur_liste; 150 | extraire_souligne; 151 | extraire_signe_plus; 152 | extraire_signe_moins; 153 | extraire_signe_fois; 154 | extraire_signe_diviser; 155 | extraire_signe_exposant; 156 | extraire_signe_def; 157 | ] 158 | 159 | let symbole_suivant s l start = 160 | if l = start then 161 | l, EOI 162 | else 163 | let rec loop = function 164 | f :: reste -> 165 | let i, qqch = f s l start in 166 | if qqch = Erreur then 167 | loop reste 168 | else 169 | i, qqch 170 | | [] -> start, Erreur 171 | in loop iter 172 | 173 | let to_lexbuf s = 174 | let start = 0 in 175 | let l = String.length s in 176 | let rec boucle acc start = 177 | match symbole_suivant s l start with 178 | _, EOI -> List.rev acc 179 | | _, Erreur -> [] (* comment je gère ? *) 180 | | start, qqch -> boucle (qqch :: acc) start 181 | in boucle [] start 182 | -------------------------------------------------------------------------------- /src/noyau/nouveau_lexer.mli: -------------------------------------------------------------------------------- 1 | type operateur = Plus | Moins | Fois | Division | Exposant | Definition 2 | type token = 3 | Erreur 4 | | EOI 5 | | Blanc 6 | | Digit of string 7 | | Identifiant of string 8 | | Affectation 9 | | Parenthese_ouvrante 10 | | Parenthese_fermante 11 | | Separateur_unite 12 | | Separateur_liste 13 | | Souligne 14 | | Operateur of operateur 15 | val extraire_blanc : string -> int -> int -> int * token 16 | val extraire_digit : string -> int -> int -> int * token 17 | val extraire_identifiant : string -> int -> int -> int * token 18 | val extraire_jeton_general : string -> int -> string -> int -> int -> int * bool 19 | val extraire_parenthese_ouvrante : string -> int -> int -> int * token 20 | val extraire_parenthese_fermante : string -> int -> int -> int * token 21 | val extraire_separateur_unite : string -> int -> int -> int * token 22 | val extraire_separateur_liste : string -> int -> int -> int * token 23 | val extraire_souligne : string -> int -> int -> int * token 24 | val extraire_signe_plus : string -> int -> int -> int * token 25 | val extraire_signe_moins : string -> int -> int -> int * token 26 | val extraire_signe_fois : string -> int -> int -> int * token 27 | val extraire_signe_diviser : string -> int -> int -> int * token 28 | val extraire_signe_exposant : string -> int -> int -> int * token 29 | val extraire_signe_def : string -> int -> int -> int * token 30 | val iter : (string -> int -> int -> int * token) list 31 | val symbole_suivant : string -> int -> int -> int * token 32 | val to_lexbuf : string -> token list 33 | -------------------------------------------------------------------------------- /src/noyau/nouveau_parser.ml: -------------------------------------------------------------------------------- 1 | type expression = 2 | Vide 3 | | Entier of string 4 | | Reel of string 5 | | Variable of string 6 | | Tuple of int * expression list 7 | | Fonction of string * int * expression list 8 | | Operation of [ `Multiplication | `Addition ] * expression list 9 | | Inverse of expression 10 | | Negation of expression 11 | 12 | type affectable = 13 | Pas_affectable 14 | | Definition_Variable of string 15 | | Definition_fonction of string * int * string list 16 | 17 | type entre_valide = 18 | Erreur of string * Nouveau_lexer.token list 19 | | Expression of expression 20 | | Definition of (affectable * expression) list 21 | 22 | let entier = 23 | let open Nouveau_lexer in 24 | let rec boucle = function 25 | e1, Digit e2 :: l | e1, Blanc :: Digit e2 :: l -> boucle (e1 ^ e2, l) 26 | | e, Souligne :: l -> boucle (e, l) 27 | | e, l -> Entier e, l 28 | in function 29 | (* (Operateur Plus) :: Digit e :: l | *) (* + entier sera traité plus tard *) 30 | Digit e :: l -> boucle (e, l) 31 | | l -> Vide, l 32 | 33 | let reel l = 34 | let open Nouveau_lexer in 35 | let e1, l = 36 | match entier l with 37 | Entier e, l -> Entier e, l 38 | | _ -> Vide, l 39 | in 40 | let virgule, e2, l = 41 | match l with 42 | Separateur_unite :: l -> ( 43 | match entier l with 44 | Entier e, l -> true, Entier e, l 45 | | _ -> true, Vide, l 46 | ) 47 | | l -> false, Vide, l 48 | in 49 | match e1, e2 with 50 | Entier e1, Entier e2 -> Reel (e1 ^ "," ^ e2), l 51 | | Entier e, Vide -> Entier e, l 52 | | Vide, Entier e -> Reel ("," ^ e), l 53 | | Vide, Vide when virgule -> Reel ",", l 54 | | _, _ -> Vide, l 55 | 56 | let variable = 57 | let open Nouveau_lexer in 58 | function 59 | Identifiant i :: l -> Variable i, l 60 | | l -> Vide, l 61 | 62 | let tuple_de f l = 63 | let open Nouveau_lexer in 64 | let rec boucle n acc = (function 65 | | Parenthese_fermante :: l -> n, List.rev acc, l 66 | | Separateur_liste :: l -> ( 67 | match f l with 68 | | Vide, _ -> 1, [Vide], l 69 | | e, l -> boucle (n + 1) (e :: acc) l 70 | ) 71 | | l -> 72 | let () = prerr_endline "Parenthese_fermante manquante" in 73 | 1, [Vide], l 74 | ) 75 | in match l with 76 | (Parenthese_ouvrante :: l) as original_liste -> ( 77 | match f l with 78 | | Vide, _ -> Vide, original_liste 79 | | e, l -> ( 80 | match boucle 1 [e] l with 81 | 1, [e], l -> e, l 82 | | n, e, l -> Tuple (n, e), l 83 | ) 84 | ) 85 | | l -> Vide, l 86 | 87 | let rec fonction l = 88 | let open Nouveau_lexer in 89 | match l with 90 | (Identifiant f :: l) as original_liste -> ( 91 | match tuple_de expression l with 92 | | Tuple (n, liste_de_parametres), l -> Fonction (f, n, liste_de_parametres), l 93 | | x, l when x <> Vide -> Fonction (f, 1, [x]), l 94 | | _, _ -> Vide, original_liste (* c'est forcement Vide *) 95 | ) 96 | | l -> Vide, l 97 | 98 | and facteur l = 99 | match reel l with 100 | Vide, _ -> ( 101 | match entier l with 102 | Vide, _ -> ( 103 | match fonction l with 104 | Vide, _ -> ( 105 | match variable l with 106 | Vide, _ -> tuple_de expression l 107 | | e, l -> e, l 108 | ) 109 | | e, l -> e, l 110 | ) 111 | | e, l -> e, l 112 | ) 113 | | e, l -> e, l 114 | 115 | and terme l = 116 | let open Nouveau_lexer in 117 | let rec boucle acc = function 118 | (Operateur Fois | Blanc) :: l -> ( 119 | match facteur l with 120 | Vide, _ -> [Vide], l 121 | (*| (Entier _ | Reel _) as e, Identifiant i :: l -> boucle (Variable i :: e :: acc) l*) 122 | | e, l -> boucle (e :: acc) l 123 | ) 124 | | Operateur Division :: l -> ( 125 | match facteur l with 126 | Vide, _ -> [Vide], l 127 | | e, l -> boucle (Inverse e :: acc) l 128 | ) 129 | | l -> List.rev acc, l 130 | in let inverse, l = 131 | match l with 132 | Operateur Division :: l -> true, l 133 | | Operateur Fois :: l | l -> false, l 134 | in match facteur l with 135 | Vide, _ -> Vide, l (* todo error handling*) 136 | | e, l -> 137 | match boucle [if inverse then Inverse e else e] l with 138 | [e], l -> e, l 139 | | e, l -> Operation (`Multiplication, e), l 140 | 141 | and expression l = 142 | let open Nouveau_lexer in 143 | let rec boucle acc l = 144 | match l with 145 | Operateur Plus :: l -> ( 146 | match terme l with 147 | Vide, _ -> [Vide], l 148 | | e, l -> boucle (e :: acc) l 149 | ) 150 | | Operateur Moins :: l -> ( 151 | match terme l with 152 | Vide, _ -> [Vide], l 153 | | e, l -> boucle (Negation e :: acc) l 154 | ) 155 | | l -> List.rev acc, l 156 | in let negatif, l = 157 | match l with 158 | Operateur Moins :: l -> true, l 159 | | Operateur Plus :: l | l -> false, l 160 | in match terme l with 161 | Vide, _ -> Vide, l (* todo error handling*) 162 | | e, l -> 163 | match boucle [if negatif then Negation e else e] l with 164 | [e], l -> e, l 165 | | e, l -> Operation (`Addition, e), l 166 | 167 | let est_affectable e = 168 | match e with 169 | Variable _ -> true 170 | | Fonction (_, _, l) -> List.for_all (fun e -> match e with Variable _ -> true | _ -> false) l 171 | | _ -> false 172 | 173 | let tous_affectable e = 174 | match e with 175 | Tuple (_, l) -> List.for_all est_affectable l 176 | | e -> est_affectable e 177 | 178 | let exrp_l_to_string_l l = List.map (fun e -> match e with Variable x -> x | _ -> "error") l 179 | 180 | let expr_to_def = function 181 | Variable x, e -> Definition_Variable x, e 182 | | Fonction (name, n, l), e -> Definition_fonction (name, n, exrp_l_to_string_l l), e 183 | | _, _ -> Pas_affectable, Vide 184 | 185 | let exprs_to_def = function 186 | Variable x, e -> Definition [Definition_Variable x, e] 187 | | Fonction (name, n, l), e -> Definition [Definition_fonction (name, n, exrp_l_to_string_l l), e] 188 | | Tuple(a, la), Tuple(b, lb) -> 189 | if a = b then 190 | Definition (List.map2 (fun a b -> expr_to_def (a, b)) la lb) 191 | else 192 | Erreur ("nombre de membre incorrect", []) 193 | | _, _ -> Erreur ("WTF", []) 194 | 195 | let expression_principale l = 196 | match expression l with 197 | e, Nouveau_lexer.Operateur Nouveau_lexer.Definition :: l -> ( 198 | if tous_affectable e then 199 | match expression l with 200 | Vide, _ -> Erreur ("membre droit incorrect", []) 201 | | e2, [] -> exprs_to_def (e, e2) 202 | | _, l -> Erreur ("caracteres restant", l) 203 | else 204 | Erreur ("membre de gauche non assignable", []) 205 | ) 206 | | Vide, l -> Erreur (I18n.erreur_de_syntaxe (), l) 207 | | e, [] -> Expression e 208 | | _, l -> Erreur ("caracteres restant", l) 209 | 210 | 211 | let filtre = 212 | let open Nouveau_lexer in 213 | let rec filtre acc = 214 | function 215 | Blanc :: [] | [] -> List.rev acc 216 | | Blanc :: (Operateur v) :: l | (Operateur v) :: Blanc :: l -> filtre acc ((Operateur v) :: l) 217 | | Blanc :: Separateur_liste :: l | Separateur_liste :: Blanc :: l -> filtre acc (Separateur_liste :: l) 218 | | Parenthese_ouvrante :: Blanc :: l -> filtre acc (Parenthese_ouvrante :: l) 219 | | Blanc :: Parenthese_fermante :: l -> filtre acc (Parenthese_fermante :: l) 220 | | Blanc :: Separateur_unite :: l -> filtre acc (Separateur_unite :: l) 221 | | Separateur_unite :: Blanc :: Digit e :: l -> filtre acc (Separateur_unite :: Digit e :: l) 222 | | e :: l -> filtre (e :: acc) l 223 | in function 224 | Blanc :: l -> filtre [] l 225 | | l -> filtre [] l 226 | 227 | let parse s = 228 | let lexbuf = Nouveau_lexer.to_lexbuf s in 229 | let lexbuf = filtre lexbuf in 230 | expression_principale lexbuf 231 | -------------------------------------------------------------------------------- /src/noyau/nouveau_parser.mli: -------------------------------------------------------------------------------- 1 | type expression = 2 | Vide 3 | | Entier of string 4 | | Reel of string 5 | | Variable of string 6 | | Tuple of int * expression list 7 | | Fonction of string * int * expression list 8 | | Operation of [ `Addition | `Multiplication ] * expression list 9 | | Inverse of expression 10 | | Negation of expression 11 | type affectable = 12 | Pas_affectable 13 | | Definition_Variable of string 14 | | Definition_fonction of string * int * string list 15 | type entre_valide = 16 | Erreur of string * Nouveau_lexer.token list 17 | | Expression of expression 18 | | Definition of (affectable * expression) list 19 | val entier : 20 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list 21 | val reel : 22 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list 23 | val variable : 24 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list 25 | val tuple_de : 26 | (Nouveau_lexer.token list -> expression * Nouveau_lexer.token list) -> 27 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list 28 | val fonction : 29 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list 30 | val facteur : 31 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list 32 | val terme : 33 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list 34 | val expression : 35 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list 36 | val est_affectable : expression -> bool 37 | val tous_affectable : expression -> bool 38 | val exrp_l_to_string_l : expression list -> string list 39 | val expr_to_def : expression * expression -> affectable * expression 40 | val exprs_to_def : expression * expression -> entre_valide 41 | val expression_principale : Nouveau_lexer.token list -> entre_valide 42 | val filtre : Nouveau_lexer.token list -> Nouveau_lexer.token list 43 | val parse : string -> entre_valide 44 | -------------------------------------------------------------------------------- /src/noyau/nouveau_type.ml: -------------------------------------------------------------------------------- 1 | open Lien 2 | 3 | type constantes = 4 | Pi 5 | (* Quaternion constantes*) 6 | | I 7 | | J 8 | | K 9 | 10 | type expr = 11 | N of GrandNum.num 12 | | C of constantes 13 | | Var of string 14 | | T of int * expr list 15 | | Fx of string * int * expr list 16 | | Op of [ `Multiplication | `Addition ] * expr list 17 | | Inv of expr 18 | | Neg of expr 19 | 20 | type affe = 21 | Def_Var of string 22 | | Def_Fx of string * int * string list 23 | 24 | let rec expr_depuis_expression = 25 | let open Nouveau_parser in 26 | function 27 | Vide -> failwith (I18n.impossible_convertir_vide ()) 28 | | Entier s -> N (GrandNum.E (GrandEntier.grandentier_depuis_texte s)) 29 | | Reel s -> N (GrandNum.R (GrandReel.grandreel_depuis_texte s)) 30 | | Variable ("pi" | "pI" | "Pi" | "PI") -> C Pi 31 | | Variable ("i" | "I") -> C I 32 | | Variable ("j" | "J") -> C J 33 | | Variable ("k" | "K") -> C K 34 | | Variable s -> Var s 35 | | Tuple (n, l) -> T (n, List.map expr_depuis_expression l) 36 | | Fonction (s, n, l) -> Fx (s, n, List.map expr_depuis_expression l) 37 | | Operation (a, l) -> Op (a, List.map expr_depuis_expression l) 38 | | Inverse e -> Inv (expr_depuis_expression e) 39 | | Negation e -> Neg (expr_depuis_expression e) 40 | 41 | let affe_depuis_affectable = 42 | let open Nouveau_parser in 43 | function 44 | Pas_affectable -> failwith (I18n.impossible_convertir_pas_affectable ()) 45 | | Definition_Variable s -> Def_Var s 46 | | Definition_fonction (f, n, l) -> Def_Fx (f, n, l) 47 | -------------------------------------------------------------------------------- /src/noyau/parser.ml: -------------------------------------------------------------------------------- 1 | open Lien 2 | open Type 3 | open Utils 4 | open Lexer 5 | 6 | (** only for test purpose *) 7 | let ge t = (Obj.magic (GrandEntier.grandentier_depuis_texte t) : Lien.GrandEntier.grandentier) 8 | (** only for test purpose *) 9 | 10 | let variable_de_entier _ t(*exte*) = Entier (GrandEntier.grandentier_depuis_texte t) 11 | 12 | let variable_de_texte _ t(*texte*) = Variable t 13 | 14 | let neg = function 15 | Entier e -> Entier (GrandEntier.neg e) 16 | | a -> Neg a 17 | 18 | let variable_de_addition_soustraction compile t(*texte*) = 19 | let l = couper_texte t ['+'; '-'] in 20 | let premier_el = function 21 | [] | [_] | [_; _] -> failwith "chut OCaml" 22 | | "" :: "-" :: e :: liste -> [neg (compile e)], liste 23 | | "" :: "+" :: e :: liste -> [compile e], liste 24 | | e :: liste -> [compile e], liste 25 | in 26 | let (premier, l) = premier_el l in 27 | let rec boucle acc = function 28 | [_] -> failwith "chut OCaml" 29 | | [] -> List.rev acc 30 | | "+" :: e :: liste -> boucle (compile e :: acc) liste 31 | | "-" :: e :: liste -> boucle (neg (compile e) :: acc) liste 32 | |_-> failwith "error" 33 | 34 | in match boucle premier l with 35 | [] -> failwith "chut OCaml" 36 | | [e] -> e (* l'addition d'un terme est le terme lui même *) 37 | | l -> Operation ("+", l) 38 | 39 | let variable_de_multiplication_division compile t(*texte*) = 40 | let l = couper_texte t ['*'; '/'] in 41 | let premier_el = function 42 | [] | [_] | [_; _] -> failwith "chut OCaml" 43 | | "" :: "/" :: e :: liste -> [Entier (GrandEntier.unit)], "/" :: e :: liste 44 | | "" :: "*" :: e :: liste -> [Entier (GrandEntier.unit)], "*" :: e :: liste 45 | | e :: liste -> [compile e], liste 46 | in 47 | let (premier, l) = premier_el l in 48 | let rec boucle acc = function 49 | [_] -> failwith "chut OCaml" 50 | | [] -> List.rev acc 51 | | "*" :: e :: liste -> boucle (compile e :: acc) liste 52 | | "/" :: e :: liste -> boucle (Inv (compile e) :: acc) liste 53 | |_-> failwith "error" 54 | 55 | in match boucle premier l with 56 | [] -> failwith "chut OCaml" 57 | | [e] -> e (* l'addition d'un terme est le terme lui même *) 58 | | l -> Operation ("*", l) 59 | 60 | let parse = 61 | let parse = [] in 62 | let parse = (est_multiplication_division, variable_de_multiplication_division) :: parse in 63 | let parse = (est_addition_soustraction, variable_de_addition_soustraction) :: parse in 64 | let parse = (est_variable, variable_de_texte) :: parse in 65 | let parse = (est_entier10, variable_de_entier) :: parse in 66 | parse 67 | 68 | let rec expr_de_texte_etend fxs(*list of function*) t(*exte*) = 69 | let f = expr_de_texte_etend fxs in 70 | let rec b(*oucle*) = function 71 | (p(*redicat*), c(*onvertisseur*)) :: _ when p t -> c f t 72 | | _ :: l -> b l 73 | | [] -> Textenonvalide t 74 | in b fxs 75 | 76 | let expr_de_texte = expr_de_texte_etend parse 77 | 78 | let rec texte_de_expr ?paren = function 79 | Variable nom -> nom 80 | | Entier ga -> GrandEntier.texte_depuis_grandentier ga 81 | | Neg e -> "(-" ^ texte_de_expr e ^ ")" 82 | | Inv e -> "(1/" ^ texte_de_expr e ^ ")" 83 | | Textenonvalide s -> s 84 | | Operation (_, []) -> failwith "On a une operation sans operande" 85 | | Operation (_, e :: []) -> texte_de_expr e 86 | | Operation (op, e :: l) -> 87 | let s = 88 | texte_de_expr e ^ op ^ (texte_de_expr ?paren:(Some false) (Operation (op, l))) in 89 | match paren with 90 | None | Some true -> "(" ^ s ^ ")" 91 | | Some false -> s 92 | -------------------------------------------------------------------------------- /src/noyau/parser.mli: -------------------------------------------------------------------------------- 1 | val ge: string -> Lien.GrandEntier.grandentier 2 | 3 | val variable_de_entier : (string -> Type.expr) -> string -> Type.expr 4 | 5 | val variable_de_texte : (string -> Type.expr) -> string -> Type.expr 6 | 7 | val variable_de_addition_soustraction : (string -> Type.expr) -> string -> Type.expr 8 | 9 | val variable_de_multiplication_division : (string -> Type.expr) -> string -> Type.expr 10 | 11 | val texte_de_expr : ?paren: bool -> Type.expr -> string 12 | 13 | val expr_de_texte_etend : ((string -> bool) * ((string -> Type.expr) -> string -> Type.expr)) list -> string -> Type.expr 14 | 15 | val expr_de_texte : string -> Type.expr 16 | -------------------------------------------------------------------------------- /src/noyau/type.ml: -------------------------------------------------------------------------------- 1 | open Lien 2 | 3 | type expr = Variable of string 4 | | Entier of GrandEntier.grandentier 5 | | Textenonvalide of string 6 | | Operation of string * expr list 7 | | Neg of expr 8 | | Inv of expr 9 | -------------------------------------------------------------------------------- /src/noyau/type.mli: -------------------------------------------------------------------------------- 1 | type expr = 2 | Variable of string 3 | | Entier of Lien.GrandEntier.grandentier 4 | | Textenonvalide of string 5 | | Operation of string * expr list 6 | | Neg of expr 7 | | Inv of expr 8 | -------------------------------------------------------------------------------- /src/noyau/utils.ml: -------------------------------------------------------------------------------- 1 | let print_bool b = 2 | print_endline ( 3 | if b then 4 | "true" 5 | else 6 | "false" 7 | ) 8 | 9 | let contient_texte t(*exte*) l(*iste à chercher*) = 10 | let car_dans_liste c = 11 | let rec boucle = function 12 | []-> false 13 | | e :: l -> c = e || boucle l 14 | in boucle l 15 | in let len = String.length t in 16 | let rec boucle p(*arenthèses*) c(*rochets*) a(*ccolades*) i = 17 | if i < len then 18 | match t.[i] with 19 | '(' -> boucle (p + 1) c a (i + 1) 20 | | '[' -> boucle p (c + 1) a (i + 1) 21 | | '{' -> boucle p c (a + 1) (i + 1) 22 | | ')' -> boucle (p - 1) c a (i + 1) 23 | | ']' -> boucle p (c - 1) a (i + 1) 24 | | '}' -> boucle p c (a - 1) (i + 1) 25 | | lettre -> p = 0 && c = 0 && a = 0 && car_dans_liste lettre || boucle p c a (i + 1) 26 | else 27 | false 28 | in boucle 0 0 0 0 29 | 30 | let couper_texte t(*exte*) l(*iste à chercher*) = 31 | let car_dans_liste c = 32 | let rec boucle = function 33 | []-> false 34 | | e :: l -> c = e || boucle l 35 | in boucle l 36 | in let len = String.length t in 37 | let start = ref 0 in 38 | let rec boucle p(*arenthèses*) c(*rochets*) a(*ccolades*) i acc = 39 | if i < len then 40 | match t.[i] with 41 | '(' -> boucle (p + 1) c a (i + 1) acc 42 | | '[' -> boucle p (c + 1) a (i + 1) acc 43 | | '{' -> boucle p c (a + 1) (i + 1) acc 44 | | ')' -> boucle (p - 1) c a (i + 1) acc 45 | | ']' -> boucle p (c - 1) a (i + 1) acc 46 | | '}' -> boucle p c (a - 1) (i + 1) acc 47 | | lettre -> if p = 0 && c = 0 && a = 0 && car_dans_liste lettre then 48 | let acc = String.sub t i 1 :: String.sub t !start (i - !start) :: acc in 49 | let () = start := i + 1 in 50 | boucle p c a (i + 1) acc 51 | else 52 | boucle p c a (i + 1) acc 53 | else 54 | let acc = String.sub t !start (i - !start) :: acc in 55 | List.rev acc 56 | in boucle 0 0 0 0 [] 57 | 58 | let parenthese_correcte t(*exte*)= 59 | let len = String.length t in 60 | let rec boucle i acc = 61 | if i < len then 62 | match t.[i], acc with 63 | ('(' as o), _ | ('[' as o), _ | ('{' as o), _ -> boucle (i + 1) (o :: acc) 64 | | ')', '(' :: acc -> boucle (i + 1) acc 65 | | ']', '[' :: acc -> boucle (i + 1) acc 66 | | '}', '{' :: acc -> boucle (i + 1) acc 67 | | ')', _ :: _ | ']', _ :: _ | '}', _ :: _ | ')', [] | ']', [] | '}', [] -> false 68 | | _ -> boucle (i + 1) acc 69 | else 70 | acc = [] 71 | in boucle 0 [] 72 | -------------------------------------------------------------------------------- /src/noyau/utils.mli: -------------------------------------------------------------------------------- 1 | val print_bool : bool -> unit 2 | val contient_texte : string -> char list -> bool 3 | val couper_texte : string -> char list -> string list 4 | val parenthese_correcte : string -> bool 5 | --------------------------------------------------------------------------------