{"id":34109175,"url":"https://github.com/reasoned-ai/norm","last_synced_at":"2026-04-02T01:01:23.602Z","repository":{"id":37602158,"uuid":"118585635","full_name":"reasoned-ai/norm","owner":"reasoned-ai","description":"Neural Logic Programming Language","archived":false,"fork":false,"pushed_at":"2022-09-16T17:58:56.000Z","size":44924,"stargazers_count":9,"open_issues_count":7,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-12-17T01:50:59.405Z","etag":null,"topics":["ai","deep-learning","deep-neural-networks","logic-programming","machine-reasoning","ml"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reasoned-ai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-23T09:09:45.000Z","updated_at":"2023-03-08T13:15:34.000Z","dependencies_parsed_at":"2022-08-25T22:12:19.707Z","dependency_job_id":null,"html_url":"https://github.com/reasoned-ai/norm","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/reasoned-ai/norm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reasoned-ai%2Fnorm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reasoned-ai%2Fnorm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reasoned-ai%2Fnorm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reasoned-ai%2Fnorm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reasoned-ai","download_url":"https://codeload.github.com/reasoned-ai/norm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reasoned-ai%2Fnorm/sbom","scorecard":{"id":766874,"data":{"date":"2025-08-11","repo":{"name":"github.com/reasoned-ai/norm","commit":"5e45d5917ce8745c9a757a0c6b5e689ea0cac19f"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":0,"reason":"23 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2021-421 / GHSA-h4m5-qpfp-3mpv","Warn: Project is vulnerable to: PYSEC-2021-387 / PYSEC-2021-871 / PYSEC-2021-872 / GHSA-hwqr-f3v9-hwxr / GHSA-j8fq-86c5-5v2r","Warn: Project is vulnerable to: GHSA-29gw-9793-fvw7","Warn: Project is vulnerable to: PYSEC-2022-12 / GHSA-pq7m-3gw7-gq5x","Warn: Project is vulnerable to: GHSA-cjgq-5qmw-rcj6","Warn: Project is vulnerable to: GHSA-x4wf-678h-2pmq","Warn: Project is vulnerable to: PYSEC-2022-260 / GHSA-v973-fxgf-6xhp","Warn: Project is vulnerable to: PYSEC-2021-856 / GHSA-5545-2q6w-2gh6","Warn: Project is vulnerable to: GHSA-6p56-wp2h-9hxr","Warn: Project is vulnerable to: PYSEC-2021-857 / GHSA-f7c7-j99h-c22f","Warn: Project is vulnerable to: GHSA-fpfv-jqm9-f5jm","Warn: Project is vulnerable to: PYSEC-2020-73","Warn: Project is vulnerable to: PYSEC-2020-176 / GHSA-3pqx-4fqf-j49f","Warn: Project is vulnerable to: PYSEC-2020-96 / GHSA-6757-jp84-gxfx","Warn: Project is vulnerable to: PYSEC-2021-142 / GHSA-8q59-q68h-6hv4","Warn: Project is vulnerable to: GHSA-9hjg-9r4m-mvj7","Warn: Project is vulnerable to: GHSA-9wx4-h78v-vm56","Warn: Project is vulnerable to: PYSEC-2023-74 / GHSA-j8r2-6x86-q33q","Warn: Project is vulnerable to: PYSEC-2020-107 / GHSA-jjw5-xxj6-pcv5","Warn: Project is vulnerable to: PYSEC-2024-110 / GHSA-jw8x-6495-233v","Warn: Project is vulnerable to: PYSEC-2020-108","Warn: Project is vulnerable to: PYSEC-2023-102","Warn: Project is vulnerable to: PYSEC-2023-114"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T01:06:26.139Z","repository_id":37602158,"created_at":"2025-08-23T01:06:26.139Z","updated_at":"2025-08-23T01:06:26.139Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31293629,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","deep-learning","deep-neural-networks","logic-programming","machine-reasoning","ml"],"created_at":"2025-12-14T18:27:37.951Z","updated_at":"2026-04-02T01:01:23.566Z","avatar_url":"https://github.com/reasoned-ai.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Norm :: Neural Object Relational Models\n\n\n![alt text](docs/_static/norm-logo.png \"Norm Logo\")\n\n\nWe propose a neural logic programming language, Neural Object Relational Models (Norm), primarily for human experts \nconducting data analytics and artificial intelligence computations. Humans are taught to reason through logic while the \nmost advanced AI today computes through tensors. Norm is trying to close the gap between human logic reasoning and \nmachine tensor computation and to keep human experts in the loop. \n\nNorm expresses the world in higher-order-logic and compiles the logic program to neural network frameworks and \ndistributed computation frameworks to take advantage of advanced algorithms and large-scale parallel computation. \nNorm takes an object-relational semantics to ground logic expressions into a directed factor graph. Deterministic \nlogic reasoning follows the graphical structure and assigns each object a false or true value. Probabilistic \ncomputation follows the same structure but relaxes the binary value to a range between 0 and 1. The relaxation \nparameterizes the logic reasoning with a neural network which can be optimized through learning algorithms. \n\nNorm is suitable for bridging the collaboration between human experts and machine intelligence where people provide \nhigh-level cross-domain knowledge while machine provides specific in-domain optimization. Since the knowledge \nrepresentation by logic is abstracted from the actual tensor computation, human experts will be able to hypothesize \ntheories, fit and test them against data, and conduct counterfactual analysis without a deep understanding of \nhow neural networks computing. We hope that Norm can enable more people to innovate in their own domains at\na much faster pace.\n\n## Object Relational Semantics\nThe world is composed of an infinite number of \nobjects where relations form directed edges among these objects. Each object is represented by both a symbol and a \ntensor. Each relation computes a probability value of the output object given the input objects. The logic computation \nproduces 0 or 1 probability representing false or true value. The probabilistic computation produces a probability \nbetween 0 and 1 representing how likely the object is true. For each object, Norm assigns a label to indicate whether \nit is witnessed or not. Witnessed object is labeled as 1 or 0 for being positive or negative. Norm can construct \nobjects with no witnessed label, i.e., na, due to the **open-world assumption** (OWA) that unknowns do not equal negatives. \nThe probability computation of un-witnessed objects is called prediction. Otherwise, it is called interpretation. \nThe quality of the interpretation can be measured based on how consistent probability values and label values,\n e.g., entropy or accuracy. These measures also drive parameter optimization through different learning algorithms.\n  The statistical principles provide generalization guarantees for the prediction quality from the measured\n   interpretation quality. Meanwhile, because the inference still follows the same semantics as human experts expressed, \n   people can understand the computation intuitively compared to a pure DNN architecture. This object-relational \n   semantics establishes a common communication protocol between human experts and machines\n   \n### Type, Relation and Predicate\nA type declares a relation over a set of variables. For example,\n\n    History(patient: Patient, record: String);\n    \nHere, `History` is a relation between a `patient` and a `record`. The keyword “History” is called the predicate. \nThe above declaration can be read as A patient of type Patient has a medical history record of type String. \nSemantically, these three concepts are interchangeable in Norm.\n\nAn entity is a special relation whose variables are considered as attributes. For example,\n\n    Patient(name: String, age: Integer);\n    \n### Object\nConstants are objects, e.g. \"Adam\" and 34. Each object has a particular type. Each type refers to a set of such objects.\n The world is composed of objects. We assume an open world which contains an infinite number of objects where most of \n them are unknowns.\n \nA relation combines a tuple of input objects into an output object, e.g., `@Patient(\"Adam\", 34)`. \nThis is called grounding. In Norm, type itself can be grounded to a type-object, e.g., `@Patient`. \nType-object has a generic type Type. See section for more details about Norm’s type system.\nEvery object has a unique id, _oid. We can refer to the object with the _oid or with the fully specified symbol.\n\nHowever, a partially grounded type is not an object, e.g., `@Patient(\"Adam\")` does not have a _oid associated with that symbol. \nUnlike in common databases where objects are allowed to be duplicated, Norm specifies that every object has a unique _oid. \nIn this way, deduplication is automatically applied during the construction process.\n\n### Variable\nVariables are placeholders for objects. A Norm expression is first grounded to fill variables with objects, \nthen infers the probability of these objects. Norm is a 3-valued logic where na denotes the unknown objects. \nIn many cases, variable can take `na` objects.\n\n##### Type of variables\nEvery variable has a type which restricts the set of objects to select from. For example, name of Patient is a String. \nThis implies that any string can be a person’s name. We use the symbol “:” to denote the isa relationship between a \nvariable and a type.\n\n##### Scope of variables\nA variable can belong to a type or another variable. For example,\n\n    Patient.name;\n    History.patient.name;\n\nAccessing `name` in both cases are valid but their domains are different. `Patient.name` has the domain of names of \nevery `Patient`, while `History.patient.name` only has names of all patients who have a medical record.\n \n### Definition\nDeclaration of types informs the machine about the structure of types. For example, we know that History has a subset \nof objects from Patient. Definition informs the machine about the structure of objects. For example,\n\n    Patient := \"Adam\", 34\n             | \"Adam\", 5\n             | \"Adam\", 11\n             | \"Joey\", 9;\n    History := @Patient(\"Adam\", 34), \"smoking\"\n             | @Patient(\"Adam\", 5), \"parents are heavy smokers\"\n             | @Patient(\"Adam\", 5), \"had a fever for 3 days\";\n\nHere, symbol \":=\" denotes **means** relationship, and \"|\" denotes **or** relationship. Examples above show the \n**extensional definition** that constructs objects and label them as positives. If a negative label is required, \nwe can specify it at the end of each row, e.g., `Patient |= \"Adam\", 34, 0`. An **intensional definition** is a logical \nexpression that can be evaluated to the extensional objects. \n\nAt any moment, the full extensional definition of the world results in a factor graph.\n\n![factor graph](docs/_static/factor_graph.jpg)\n\nEvery type is represented by a box with different color. Every object is represented by a circle with the same color as \nits type. Input objects to the type have variable names on the label. The output object simply reflects the composition\n of input objects. Types like Integer or String are constant types without any inputs. Objects witnessed as positives \n filled with color. Objects witnessed as negatives filled with gray but edged with color. Unknown objects are dark \n matters in the world that might not be depicted in the graph.\n\n### Expression\nWith the basic concepts of type, variable, and object, we can form logical expressions to validate a statement or infer \nvariables. For example,\n\n    // Any child less than 10 year old does not have a tobacco history\n    forany p: Patient, p.age \u003c 10 =\u003e\n         not exist r in p.History.record, r ~ 'smoke';\n         \nThis is a first order logic expression, where symbol \"=\u003e\" denotes **imply** relation, a.k.a., if … then.  \nSymbol \"~\" denotes the **like** relationship. Any record evaluating to true is returned as a positive. \nAny record evaluating to false is returned as a negative. Any failed record is returned as exceptions or unknowns. \nFor the given example, we have the following results where each object is listed as a row in the table. \nThe variable _label represents the witnessed value while _prob represents the inferred value. \nClearly, the negative object is a counter-example (false negative) that indicates the conflicts of given \nlogic expression and the witnessed world. Domain experts can further investigate and modify hypothesis accordingly.\n \nPositives:\n\n| _oid      | p                    |r         |_prob   |_label |\n|:--------- |:-------------------- |:-------- |:------ |:----- |\n| $12faefe  | @Patient(“Adam”, 34) |“smoking” |1.0     |1      |\n| $21feab   | @Patient(“Adam”, 11) |na        |1.0     |1      |\n| $fa32b3   | @Patient(“Joey”, 9)  |na        |1.0     |1      |\n\nNegatives: \n\n| _oid      | p                    |r         |_prob   |_label |\n|:--------- |:-------------------- |:-------- |:------ |:----- |\n| $a14aee   | @Patient(“Adam”, 5)  | “parents are heavy smokers” |**0.0** |**1**|\n\nThe graph representation of the logical path can be depicted in the following figure. The old world is grayed out to \nemphasize the newly added parts. \n\n![factor graph](docs/_static/query_factor_graph.jpg)\n\nLogic relations like \"\u003c\", \"not exist\", \"\\~\" and \"=\u003e\" take the input objects and compute the probability for the output \nobject. For logic computation, the probability to be either a 0 or 1. For probabilistic computation, logic relation \nproduces a probability between 0 and 1. For example, if we query the record by \"tobacco\" instead of \"smoke\", \nthe \"~\" relation can produce a similarity measure to decide whether the record implies a “tobacco” history or not. \nThis relation can be as simple as a cosine similarity or as complicated as a Transformer model. Norm utilizes a \nversioning mechanism to override relations for different definitions either deterministic or probabilistic. \nPeople can specify which version to use in the logic expression or rely on an auto machine learning algorithm to \ndecide which version is the best to fit the witnessed world.\n\nThe actual implementation of the computation depends on the engine we use. \nFor example, when data fit in memory, a python framework Pandas can be used to execute the computation. \nWhen data are distributed across multiple nodes, a python framework Dask can be used to push down the predicates. \nIf GPUs are available, a python framework cudf can be used to run the expression. Of course, \nfor the probabilistic computation, Norm compiles to tensorflow or pytorch. We will discuss the system in later section.\n\n### Encapsulation\nAt last, a new type can be defined by removing the quantifiers.\n\n    ChildNoSmoke(p: Patient, r: String) \n           := p.age \u003c 10 =\u003e r !~ 'smoke';\n\n![factor graph](docs/_static/encapsulate_factor_graph.jpg)\n\nThis practice is called encapsulation which is a similar concept in Object Oriented Programming (OOP). \nEncapsulation not only modularizes the logic expression to reduce the overall code complexity, but it also \nfactors out a lemma from the world. Other logic expressions can sign up the lemma without re-proving it. \nThe more logic expressions depend on this lemma, the higher impact it is. These high impact in-domain or \ncross-domain lemmas will be the value of proposition. Inventing new lemmas from data is the task known as inductive \nlogic programming (ILP). ILP facilitates the machine initiated collaboration that can help discover hidden relations in\n the world that are overlooked by human experts.\n\n### Relaxation\nLogic expressions are often strict, a.k.a., ‘hard’. These hard rules can be difficult to generalize. Sometimes \nthey are precise, but fail to cover many cases. Sometimes they are brittle and sensitive to the changes of values. \nThe relaxation softens the hard rules through parameterization which can be optimized by machine learning algorithms.\n Parameterization creates a family of logical relations among objects. The process of fitting searches for the best \n value of these parameters with respect to an objective, e.g., the expected accuracy. Sophisticated controls involve \n fine-tune cross-validation or calibration hyper-parameters, but people can rely on automatic machine learning (AutoML) \n algorithms to obtain the most generalizable parameters. \n \n    ChildNoSmoke(p: Patient, r: String, th: Integer parameter(10)) \n          := p.age \u003c th =\u003e r !~ 'smoke';\n    History.fit();\n\nThe above example sets the age threshold as a parameter initialized to 10. Fitting uses witnessed data of the patient’s \nmedical history to minimize the mis-matches between *_prob* and *_label*. \n\nNot only explicit threshold parameters can be relaxed, relations can be parameterized too. \nFor example,\n\n    // Relax ~ to a glove based similarity operator\n    ChildNoSmoke.relax(~, ~$glove);\n    // Simply relax ~ to any implementation\n    ChildNoSmoke.relax(~);\n\nHere, the ‘like’ operator is replaced with a glove based similarity relation which contains pre-trained parameters. \nGlove word2vec allows us to compare ‘smoke’ and ‘tobacco’ without enumerating the semantics. However, not all \npre-trained parameters generalize to the existing domain. The fitting process adapts these pre-trained parameters \naccordingly to improve the generalizability. \n\nMoreover, Norm implements a graph attention layer to relax the generic logical operators like ‘or’, ‘and’, and ‘imp’. \nThe entire logic program can be compiled to a giant neural network that is trained end-to-end. \n\nRelaxation enables human initiated collaboration that human experts provide knowledge like physical laws or common sense\n as parameterized relations, while machines optimize these parameters with respect to a specific task. \n\nBoth human and machine initiated collaborations are important for human experts to model the domain. The more efficient \nlearning algorithms, the more effective collaborations. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freasoned-ai%2Fnorm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freasoned-ai%2Fnorm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freasoned-ai%2Fnorm/lists"}